aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-08-10 17:44:53 +0200
committerEven Rouault <even.rouault@spatialys.com>2019-08-10 17:44:53 +0200
commit0a1261781de96d2bb8c76fbd905ebf8b0121d3a6 (patch)
treebc08254e1603339aa5450a5ee1b680a92de66315 /src
parent63981af418d84749cd4d70752f83fd551100389f (diff)
downloadPROJ-0a1261781de96d2bb8c76fbd905ebf8b0121d3a6.tar.gz
PROJ-0a1261781de96d2bb8c76fbd905ebf8b0121d3a6.zip
PROJJSON: a few fixes, and add import of DerivedCRS, EngineeringCRS, ParametricCRS and TemporalCRS
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/common.cpp2
-rw-r--r--src/iso19111/coordinatesystem.cpp5
-rw-r--r--src/iso19111/crs.cpp4
-rw-r--r--src/iso19111/io.cpp146
4 files changed, 132 insertions, 25 deletions
diff --git a/src/iso19111/common.cpp b/src/iso19111/common.cpp
index fb7a63c0..f375ea0a 100644
--- a/src/iso19111/common.cpp
+++ b/src/iso19111/common.cpp
@@ -257,7 +257,7 @@ void UnitOfMeasure::_exportToJSON(
} else if (l_type == Type::TIME) {
writer.Add("TimeUnit");
} else if (l_type == Type::PARAMETRIC) {
- writer.Add("ParametericUnit");
+ writer.Add("ParametricUnit");
} else {
writer.Add("Unit");
}
diff --git a/src/iso19111/coordinatesystem.cpp b/src/iso19111/coordinatesystem.cpp
index ef53dd57..5a852b0d 100644
--- a/src/iso19111/coordinatesystem.cpp
+++ b/src/iso19111/coordinatesystem.cpp
@@ -409,12 +409,13 @@ void CoordinateSystemAxis::_exportToJSON(
writer.AddObjKey("direction");
writer.Add(direction().toString());
- writer.AddObjKey("unit");
const auto &l_unit(unit());
if (l_unit == common::UnitOfMeasure::METRE ||
l_unit == common::UnitOfMeasure::DEGREE) {
+ writer.AddObjKey("unit");
writer.Add(l_unit.name());
- } else {
+ } else if (l_unit.type() != common::UnitOfMeasure::Type::NONE) {
+ writer.AddObjKey("unit");
l_unit._exportToJSON(formatter);
}
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index b03ece23..b9694ba2 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -2711,6 +2711,7 @@ void DerivedCRS::_exportToJSON(
baseCRS()->_exportToJSON(formatter);
writer.AddObjKey("conversion");
+ formatter->setOmitTypeInImmediateChild();
derivingConversionRef()->_exportToJSON(formatter);
writer.AddObjKey("coordinate_system");
@@ -4837,6 +4838,7 @@ void TemporalCRS::_exportToJSON(
}
writer.AddObjKey("datum");
+ formatter->setOmitTypeInImmediateChild();
datum()->_exportToJSON(formatter);
writer.AddObjKey("coordinate_system");
@@ -4974,6 +4976,7 @@ void EngineeringCRS::_exportToJSON(
}
writer.AddObjKey("datum");
+ formatter->setOmitTypeInImmediateChild();
datum()->_exportToJSON(formatter);
writer.AddObjKey("coordinate_system");
@@ -5105,6 +5108,7 @@ void ParametricCRS::_exportToJSON(
}
writer.AddObjKey("datum");
+ formatter->setOmitTypeInImmediateChild();
datum()->_exportToJSON(formatter);
writer.AddObjKey("coordinate_system");
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 8467a9e1..cd54f4ea 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -4414,6 +4414,61 @@ class JSONParser {
TransformationNNPtr buildTransformation(const json &j);
ConcatenatedOperationNNPtr buildConcatenatedOperation(const json &j);
+ static util::optional<std::string> getAnchor(const json &j) {
+ util::optional<std::string> anchor;
+ if (j.contains("anchor")) {
+ anchor = getString(j, "anchor");
+ }
+ return anchor;
+ }
+
+ EngineeringDatumNNPtr buildEngineeringDatum(const json &j) {
+ return EngineeringDatum::create(buildProperties(j), getAnchor(j));
+ }
+
+ ParametricDatumNNPtr buildParametricDatum(const json &j) {
+ return ParametricDatum::create(buildProperties(j), getAnchor(j));
+ }
+
+ TemporalDatumNNPtr buildTemporalDatum(const json &j) {
+ auto calendar = getString(j, "calendar");
+ auto origin = DateTime::create(j.contains("time_origin")
+ ? getString(j, "time_origin")
+ : std::string());
+ return TemporalDatum::create(buildProperties(j), origin, calendar);
+ }
+
+ template <class TargetCRS, class DatumBuilderType,
+ class CS = CoordinateSystem>
+ util::nn<std::shared_ptr<TargetCRS>> buildCRS(const json &j,
+ DatumBuilderType f) {
+ auto datum = (this->*f)(getObject(j, "datum"));
+ auto cs = buildCS(getObject(j, "coordinate_system"));
+ auto csCast = util::nn_dynamic_pointer_cast<CS>(cs);
+ if (!csCast) {
+ throw ParsingException("coordinate_system not of expected type");
+ }
+ return TargetCRS::create(buildProperties(j), datum,
+ NN_NO_CHECK(csCast));
+ }
+
+ template <class TargetCRS, class BaseCRS, class CS = CoordinateSystem>
+ util::nn<std::shared_ptr<TargetCRS>> buildDerivedCRS(const json &j) {
+ auto baseCRSObj = create(getObject(j, "base_crs"));
+ auto baseCRS = util::nn_dynamic_pointer_cast<BaseCRS>(baseCRSObj);
+ if (!baseCRS) {
+ throw ParsingException("base_crs not of expected type");
+ }
+ auto cs = buildCS(getObject(j, "coordinate_system"));
+ auto csCast = util::nn_dynamic_pointer_cast<CS>(cs);
+ if (!csCast) {
+ throw ParsingException("coordinate_system not of expected type");
+ }
+ auto conv = buildConversion(getObject(j, "conversion"));
+ return TargetCRS::create(buildProperties(j), NN_NO_CHECK(baseCRS), conv,
+ NN_NO_CHECK(csCast));
+ }
+
public:
JSONParser() = default;
@@ -4511,7 +4566,7 @@ UnitOfMeasure JSONParser::getUnit(const json &j, const char *key) {
type = UnitOfMeasure::Type::SCALE;
} else if (typeStr == "TimeUnit") {
type = UnitOfMeasure::Type::TIME;
- } else if (typeStr == "ParametericUnit") {
+ } else if (typeStr == "ParametricUnit") {
type = UnitOfMeasure::Type::PARAMETRIC;
} else if (typeStr == "Unit") {
type = UnitOfMeasure::Type::UNKNOWN;
@@ -4695,6 +4750,58 @@ BaseObjectNNPtr JSONParser::create(const json &j)
if (type == "BoundCRS") {
return buildBoundCRS(j);
}
+ if (type == "EngineeringCRS") {
+ return buildCRS<EngineeringCRS>(j, &JSONParser::buildEngineeringDatum);
+ }
+ if (type == "ParametricCRS") {
+ return buildCRS<ParametricCRS,
+ decltype(&JSONParser::buildParametricDatum),
+ ParametricCS>(j, &JSONParser::buildParametricDatum);
+ }
+ if (type == "TemporalCRS") {
+ return buildCRS<TemporalCRS, decltype(&JSONParser::buildTemporalDatum),
+ TemporalCS>(j, &JSONParser::buildTemporalDatum);
+ }
+ if (type == "DerivedGeodeticCRS") {
+ auto baseCRSObj = create(getObject(j, "base_crs"));
+ auto baseCRS = util::nn_dynamic_pointer_cast<GeodeticCRS>(baseCRSObj);
+ if (!baseCRS) {
+ throw ParsingException("base_crs not of expected type");
+ }
+ auto cs = buildCS(getObject(j, "coordinate_system"));
+ auto conv = buildConversion(getObject(j, "conversion"));
+ auto csCartesian = util::nn_dynamic_pointer_cast<CartesianCS>(cs);
+ if (csCartesian)
+ return DerivedGeodeticCRS::create(buildProperties(j),
+ NN_NO_CHECK(baseCRS), conv,
+ NN_NO_CHECK(csCartesian));
+ auto csSpherical = util::nn_dynamic_pointer_cast<SphericalCS>(cs);
+ if (csSpherical)
+ return DerivedGeodeticCRS::create(buildProperties(j),
+ NN_NO_CHECK(baseCRS), conv,
+ NN_NO_CHECK(csSpherical));
+ throw ParsingException("coordinate_system not of expected type");
+ }
+ if (type == "DerivedGeographicCRS") {
+ return buildDerivedCRS<DerivedGeographicCRS, GeodeticCRS,
+ EllipsoidalCS>(j);
+ }
+ if (type == "DerivedProjectedCRS") {
+ return buildDerivedCRS<DerivedProjectedCRS, ProjectedCRS>(j);
+ }
+ if (type == "DerivedVerticalCRS") {
+ return buildDerivedCRS<DerivedVerticalCRS, VerticalCRS, VerticalCS>(j);
+ }
+ if (type == "DerivedEngineeringCRS") {
+ return buildDerivedCRS<DerivedEngineeringCRS, EngineeringCRS>(j);
+ }
+ if (type == "DerivedParametricCRS") {
+ return buildDerivedCRS<DerivedParametricCRS, ParametricCRS,
+ ParametricCS>(j);
+ }
+ if (type == "DerivedTemporalCRS") {
+ return buildDerivedCRS<DerivedTemporalCRS, TemporalCRS, TemporalCS>(j);
+ }
if (type == "DatumEnsemble") {
return buildDatumEnsemble(j);
}
@@ -4710,6 +4817,15 @@ BaseObjectNNPtr JSONParser::create(const json &j)
if (type == "DynamicVerticalReferenceFrame") {
return buildDynamicVerticalReferenceFrame(j);
}
+ if (type == "EngineeringDatum") {
+ return buildEngineeringDatum(j);
+ }
+ if (type == "ParametricDatum") {
+ return buildParametricDatum(j);
+ }
+ if (type == "TemporalDatum") {
+ return buildTemporalDatum(j);
+ }
if (type == "Ellipsoid") {
return buildEllipsoid(j);
}
@@ -5033,7 +5149,9 @@ JSONParser::buildConcatenatedOperation(const json &j) {
CoordinateSystemAxisNNPtr JSONParser::buildAxis(const json &j) {
auto dirString = getString(j, "direction");
auto abbreviation = getString(j, "abbreviation");
- auto unit = getUnit(j, "unit");
+ auto unit = j.contains("unit") ? getUnit(j, "unit")
+ : UnitOfMeasure(std::string(), 1.0,
+ UnitOfMeasure::Type::NONE);
auto direction = AxisDirection::valueOf(dirString);
if (!direction) {
throw ParsingException(concat("unhandled axis direction: ", dirString));
@@ -5198,12 +5316,8 @@ JSONParser::buildGeodeticReferenceFrame(const json &j) {
auto pm = j.contains("prime_meridian")
? buildPrimeMeridian(getObject(j, "prime_meridian"))
: PrimeMeridian::GREENWICH;
- optional<std::string> anchor;
- if (j.contains("anchor")) {
- anchor = getString(j, "anchor");
- }
return GeodeticReferenceFrame::create(
- buildProperties(j), buildEllipsoid(ellipsoidJ), anchor, pm);
+ buildProperties(j), buildEllipsoid(ellipsoidJ), getAnchor(j), pm);
}
// ---------------------------------------------------------------------------
@@ -5214,10 +5328,6 @@ JSONParser::buildDynamicGeodeticReferenceFrame(const json &j) {
auto pm = j.contains("prime_meridian")
? buildPrimeMeridian(getObject(j, "prime_meridian"))
: PrimeMeridian::GREENWICH;
- optional<std::string> anchor;
- if (j.contains("anchor")) {
- anchor = getString(j, "anchor");
- }
Measure frameReferenceEpoch(getNumber(j, "frame_reference_epoch"),
UnitOfMeasure::YEAR);
optional<std::string> deformationModel;
@@ -5225,7 +5335,7 @@ JSONParser::buildDynamicGeodeticReferenceFrame(const json &j) {
deformationModel = getString(j, "deformation_model");
}
return DynamicGeodeticReferenceFrame::create(
- buildProperties(j), buildEllipsoid(ellipsoidJ), anchor, pm,
+ buildProperties(j), buildEllipsoid(ellipsoidJ), getAnchor(j), pm,
frameReferenceEpoch, deformationModel);
}
@@ -5233,21 +5343,13 @@ JSONParser::buildDynamicGeodeticReferenceFrame(const json &j) {
VerticalReferenceFrameNNPtr
JSONParser::buildVerticalReferenceFrame(const json &j) {
- optional<std::string> anchor;
- if (j.contains("anchor")) {
- anchor = getString(j, "anchor");
- }
- return VerticalReferenceFrame::create(buildProperties(j), anchor);
+ return VerticalReferenceFrame::create(buildProperties(j), getAnchor(j));
}
// ---------------------------------------------------------------------------
DynamicVerticalReferenceFrameNNPtr
JSONParser::buildDynamicVerticalReferenceFrame(const json &j) {
- optional<std::string> anchor;
- if (j.contains("anchor")) {
- anchor = getString(j, "anchor");
- }
Measure frameReferenceEpoch(getNumber(j, "frame_reference_epoch"),
UnitOfMeasure::YEAR);
optional<std::string> deformationModel;
@@ -5255,7 +5357,7 @@ JSONParser::buildDynamicVerticalReferenceFrame(const json &j) {
deformationModel = getString(j, "deformation_model");
}
return DynamicVerticalReferenceFrame::create(
- buildProperties(j), anchor, util::optional<RealizationMethod>(),
+ buildProperties(j), getAnchor(j), util::optional<RealizationMethod>(),
frameReferenceEpoch, deformationModel);
}