aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/io.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-06-05 22:03:00 +0200
committerEven Rouault <even.rouault@spatialys.com>2019-06-06 15:02:58 +0200
commitcd28089a9984698b5557be1d9b868d30eaa3a893 (patch)
tree9d113dca2e00d8d8704adc6123d30c00593956de /src/iso19111/io.cpp
parent0383f7829792f896d233acc1676377d2fffc3cdc (diff)
downloadPROJ-cd28089a9984698b5557be1d9b868d30eaa3a893.tar.gz
PROJ-cd28089a9984698b5557be1d9b868d30eaa3a893.zip
createFromUserInput(): support OGC URN to create projectedCRS, for example to instanciate a projected 3D CRS
Diffstat (limited to 'src/iso19111/io.cpp')
-rw-r--r--src/iso19111/io.cpp119
1 files changed, 117 insertions, 2 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 7329758a..7b8e270b 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -4449,13 +4449,118 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text,
}
}
- // OGC 07-092r2: para 7.5.2
- // URN combined references for compound coordinate reference systems
if (starts_with(text, "urn:ogc:def:crs,")) {
if (!dbContext) {
throw ParsingException("no database context specified");
}
auto tokensComma = split(text, ',');
+ if (tokensComma.size() == 4 && starts_with(tokensComma[1], "crs:") &&
+ starts_with(tokensComma[2], "cs:") &&
+ starts_with(tokensComma[3], "coordinateOperation:")) {
+ // OGC 07-092r2: para 7.5.4
+ // URN combined references for projected or derived CRSs
+ const auto &crsPart = tokensComma[1];
+ const auto tokensCRS = split(crsPart, ':');
+ if (tokensCRS.size() != 4) {
+ throw ParsingException(
+ concat("invalid crs component: ", crsPart));
+ }
+ auto factoryCRS =
+ AuthorityFactory::create(NN_NO_CHECK(dbContext), tokensCRS[1]);
+ auto baseCRS =
+ factoryCRS->createCoordinateReferenceSystem(tokensCRS[3], true);
+
+ const auto &csPart = tokensComma[2];
+ auto tokensCS = split(csPart, ':');
+ if (tokensCS.size() != 4) {
+ throw ParsingException(
+ concat("invalid cs component: ", csPart));
+ }
+ auto factoryCS =
+ AuthorityFactory::create(NN_NO_CHECK(dbContext), tokensCS[1]);
+ auto cs = factoryCS->createCoordinateSystem(tokensCS[3]);
+
+ const auto &opPart = tokensComma[3];
+ auto tokensOp = split(opPart, ':');
+ if (tokensOp.size() != 4) {
+ throw ParsingException(
+ concat("invalid coordinateOperation component: ", opPart));
+ }
+ auto factoryOp =
+ AuthorityFactory::create(NN_NO_CHECK(dbContext), tokensOp[1]);
+ auto op = factoryOp->createCoordinateOperation(tokensOp[3], true);
+
+ if (dynamic_cast<GeographicCRS *>(baseCRS.get()) &&
+ dynamic_cast<Conversion *>(op.get()) &&
+ dynamic_cast<CartesianCS *>(cs.get())) {
+ auto geogCRS = NN_NO_CHECK(
+ util::nn_dynamic_pointer_cast<GeographicCRS>(baseCRS));
+ auto name = op->nameStr() + " / " + baseCRS->nameStr();
+ if (geogCRS->coordinateSystem()->axisList().size() == 3 &&
+ baseCRS->nameStr().find("3D") == std::string::npos) {
+ name += " (3D)";
+ }
+ return ProjectedCRS::create(
+ util::PropertyMap().set(IdentifiedObject::NAME_KEY, name),
+ geogCRS,
+ NN_NO_CHECK(util::nn_dynamic_pointer_cast<Conversion>(op)),
+ NN_NO_CHECK(
+ util::nn_dynamic_pointer_cast<CartesianCS>(cs)));
+ } else if (dynamic_cast<GeodeticCRS *>(baseCRS.get()) &&
+ !dynamic_cast<GeographicCRS *>(baseCRS.get()) &&
+ dynamic_cast<Conversion *>(op.get()) &&
+ dynamic_cast<CartesianCS *>(cs.get())) {
+ return DerivedGeodeticCRS::create(
+ util::PropertyMap().set(IdentifiedObject::NAME_KEY,
+ op->nameStr() + " / " +
+ baseCRS->nameStr()),
+ NN_NO_CHECK(
+ util::nn_dynamic_pointer_cast<GeodeticCRS>(baseCRS)),
+ NN_NO_CHECK(util::nn_dynamic_pointer_cast<Conversion>(op)),
+ NN_NO_CHECK(
+ util::nn_dynamic_pointer_cast<CartesianCS>(cs)));
+ } else if (dynamic_cast<GeographicCRS *>(baseCRS.get()) &&
+ dynamic_cast<Conversion *>(op.get()) &&
+ dynamic_cast<EllipsoidalCS *>(cs.get())) {
+ return DerivedGeographicCRS::create(
+ util::PropertyMap().set(IdentifiedObject::NAME_KEY,
+ op->nameStr() + " / " +
+ baseCRS->nameStr()),
+ NN_NO_CHECK(
+ util::nn_dynamic_pointer_cast<GeodeticCRS>(baseCRS)),
+ NN_NO_CHECK(util::nn_dynamic_pointer_cast<Conversion>(op)),
+ NN_NO_CHECK(
+ util::nn_dynamic_pointer_cast<EllipsoidalCS>(cs)));
+ } else if (dynamic_cast<ProjectedCRS *>(baseCRS.get()) &&
+ dynamic_cast<Conversion *>(op.get())) {
+ return DerivedProjectedCRS::create(
+ util::PropertyMap().set(IdentifiedObject::NAME_KEY,
+ op->nameStr() + " / " +
+ baseCRS->nameStr()),
+ NN_NO_CHECK(
+ util::nn_dynamic_pointer_cast<ProjectedCRS>(baseCRS)),
+ NN_NO_CHECK(util::nn_dynamic_pointer_cast<Conversion>(op)),
+ cs);
+ } else if (dynamic_cast<VerticalCRS *>(baseCRS.get()) &&
+ dynamic_cast<Conversion *>(op.get()) &&
+ dynamic_cast<VerticalCS *>(cs.get())) {
+ return DerivedVerticalCRS::create(
+ util::PropertyMap().set(IdentifiedObject::NAME_KEY,
+ op->nameStr() + " / " +
+ baseCRS->nameStr()),
+ NN_NO_CHECK(
+ util::nn_dynamic_pointer_cast<VerticalCRS>(baseCRS)),
+ NN_NO_CHECK(util::nn_dynamic_pointer_cast<Conversion>(op)),
+ NN_NO_CHECK(util::nn_dynamic_pointer_cast<VerticalCS>(cs)));
+ } else {
+ throw ParsingException("unsupported combination of baseCRS, CS "
+ "and coordinateOperation for a "
+ "DerivedCRS");
+ }
+ }
+
+ // OGC 07-092r2: para 7.5.2
+ // URN combined references for compound coordinate reference systems
std::vector<CRSNNPtr> components;
std::string name;
for (size_t i = 1; i < tokensComma.size(); i++) {
@@ -4622,6 +4727,11 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text,
* e.g. "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717"
* We also accept a custom abbreviated syntax EPSG:2393+5717
* </li>
+ * <li> OGC URN combining references for references for projected or derived
+ * CRSs
+ * e.g. for Projected 3D CRS "UTM zone 31N / WGS 84 (3D)"
+ * "urn:ogc:def:crs,crs:EPSG::4979,cs:PROJ::ENh,coordinateOperation:EPSG::16031"
+ * </li>
* <li> OGC URN combining references for concatenated operations
* e.g.
* "urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618"</li>
@@ -4665,6 +4775,11 @@ BaseObjectNNPtr createFromUserInput(const std::string &text,
* e.g. "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717"
* We also accept a custom abbreviated syntax EPSG:2393+5717
* </li>
+ * <li> OGC URN combining references for references for projected or derived
+ * CRSs
+ * e.g. for Projected 3D CRS "UTM zone 31N / WGS 84 (3D)"
+ * "urn:ogc:def:crs,crs:EPSG::4979,cs:PROJ::ENh,coordinateOperation:EPSG::16031"
+ * </li>
* <li> OGC URN combining references for concatenated operations
* e.g.
* "urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618"</li>