aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/io.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/iso19111/io.cpp')
-rw-r--r--src/iso19111/io.cpp88
1 files changed, 73 insertions, 15 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 0f4ffba0..b8e835d7 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -4145,11 +4145,19 @@ createBoundCRSSourceTransformationCRS(const crs::CRSPtr &sourceCRS,
CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) {
const auto *nodeP = node->GP();
- auto &datumNode =
+ const auto &nodeValue = nodeP->value();
+ auto &vdatumNode =
nodeP->lookForChild(WKTConstants::VDATUM, WKTConstants::VERT_DATUM,
WKTConstants::VERTICALDATUM, WKTConstants::VRF);
auto &ensembleNode = nodeP->lookForChild(WKTConstants::ENSEMBLE);
- if (isNull(datumNode) && isNull(ensembleNode)) {
+ // like in ESRI VERTCS["WGS_1984",DATUM["D_WGS_1984",
+ // SPHEROID["WGS_1984",6378137.0,298.257223563]],
+ // PARAMETER["Vertical_Shift",0.0],
+ // PARAMETER["Direction",1.0],UNIT["Meter",1.0]
+ auto &geogDatumNode = ci_equal(nodeValue, WKTConstants::VERTCS)
+ ? nodeP->lookForChild(WKTConstants::DATUM)
+ : null_node;
+ if (isNull(vdatumNode) && isNull(geogDatumNode) && isNull(ensembleNode)) {
throw ParsingException("Missing VDATUM or ENSEMBLE node");
}
@@ -4164,28 +4172,50 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) {
}
auto &dynamicNode = nodeP->lookForChild(WKTConstants::DYNAMIC);
- auto datum =
- !isNull(datumNode)
- ? buildVerticalReferenceFrame(datumNode, dynamicNode).as_nullable()
- : nullptr;
+ auto vdatum =
+ !isNull(geogDatumNode)
+ ? VerticalReferenceFrame::create(
+ PropertyMap()
+ .set(IdentifiedObject::NAME_KEY,
+ buildGeodeticReferenceFrame(geogDatumNode,
+ PrimeMeridian::GREENWICH,
+ null_node)
+ ->nameStr())
+ .set("VERT_DATUM_TYPE", "2002"))
+ .as_nullable()
+ : !isNull(vdatumNode)
+ ? buildVerticalReferenceFrame(vdatumNode, dynamicNode)
+ .as_nullable()
+ : nullptr;
auto datumEnsemble =
!isNull(ensembleNode)
? buildDatumEnsemble(ensembleNode, nullptr, false).as_nullable()
: nullptr;
auto &csNode = nodeP->lookForChild(WKTConstants::CS_);
- const auto &nodeValue = nodeP->value();
if (isNull(csNode) && !ci_equal(nodeValue, WKTConstants::VERT_CS) &&
!ci_equal(nodeValue, WKTConstants::VERTCS) &&
!ci_equal(nodeValue, WKTConstants::BASEVERTCRS)) {
ThrowMissing(WKTConstants::CS_);
}
- auto cs = buildCS(csNode, node, UnitOfMeasure::NONE);
- auto verticalCS = nn_dynamic_pointer_cast<VerticalCS>(cs);
+ auto verticalCS = nn_dynamic_pointer_cast<VerticalCS>(
+ buildCS(csNode, node, UnitOfMeasure::NONE));
if (!verticalCS) {
ThrowNotExpectedCSType("vertical");
}
+ if (vdatum && vdatum->getWKT1DatumType() == "2002" &&
+ &(verticalCS->axisList()[0]->direction()) == &(AxisDirection::UP)) {
+ verticalCS =
+ VerticalCS::create(
+ util::PropertyMap(),
+ CoordinateSystemAxis::create(
+ util::PropertyMap().set(IdentifiedObject::NAME_KEY,
+ "ellipsoidal height"),
+ "h", AxisDirection::UP, verticalCS->axisList()[0]->unit()))
+ .as_nullable();
+ }
+
auto &props = buildProperties(node);
if (esriStyle_ && dbContext_) {
@@ -4246,10 +4276,10 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) {
"North American Vertical Datum 1988");
propsDatum.set(Identifier::CODE_KEY, 5103);
propsDatum.set(Identifier::CODESPACE_KEY, Identifier::EPSG);
- datum =
+ vdatum =
VerticalReferenceFrame::create(propsDatum).as_nullable();
const auto dummyCRS =
- VerticalCRS::create(PropertyMap(), datum, datumEnsemble,
+ VerticalCRS::create(PropertyMap(), vdatum, datumEnsemble,
NN_NO_CHECK(verticalCS));
const auto model(Transformation::create(
propsModel, dummyCRS, dummyCRS, nullptr,
@@ -4265,7 +4295,7 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) {
if (!isNull(geoidModelNode)) {
auto &propsModel = buildProperties(geoidModelNode);
const auto dummyCRS = VerticalCRS::create(
- PropertyMap(), datum, datumEnsemble, NN_NO_CHECK(verticalCS));
+ PropertyMap(), vdatum, datumEnsemble, NN_NO_CHECK(verticalCS));
const auto model(Transformation::create(
propsModel, dummyCRS, dummyCRS, nullptr,
OperationMethod::create(PropertyMap(),
@@ -4275,10 +4305,10 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) {
}
auto crs = nn_static_pointer_cast<CRS>(VerticalCRS::create(
- props, datum, datumEnsemble, NN_NO_CHECK(verticalCS)));
+ props, vdatum, datumEnsemble, NN_NO_CHECK(verticalCS)));
- if (!isNull(datumNode)) {
- auto &extensionNode = datumNode->lookForChild(WKTConstants::EXTENSION);
+ if (!isNull(vdatumNode)) {
+ auto &extensionNode = vdatumNode->lookForChild(WKTConstants::EXTENSION);
const auto &extensionChildren = extensionNode->GP()->children();
if (extensionChildren.size() == 2) {
if (ci_equal(stripQuotes(extensionChildren[0]), "PROJ4_GRIDS")) {
@@ -6507,6 +6537,34 @@ BaseObjectNNPtr WKTParser::createFromWKT(const std::string &wkt) {
}
return d->buildGeodeticReferenceFrame(root, primeMeridian,
null_node);
+ } else if (ci_equal(name, WKTConstants::GEOGCS) ||
+ ci_equal(name, WKTConstants::PROJCS)) {
+ // Parse implicit compoundCRS from ESRI that is
+ // "PROJCS[...],VERTCS[...]" or "GEOGCS[...],VERTCS[...]"
+ if (indexEnd < wkt.size()) {
+ indexEnd = skipSpace(wkt, indexEnd);
+ if (indexEnd < wkt.size() && wkt[indexEnd] == ',') {
+ ++indexEnd;
+ indexEnd = skipSpace(wkt, indexEnd);
+ if (indexEnd < wkt.size() &&
+ ci_starts_with(wkt.c_str() + indexEnd,
+ WKTConstants::VERTCS.c_str())) {
+ auto horizCRS = d->buildCRS(root);
+ if (horizCRS) {
+ auto vertCRS =
+ d->buildVerticalCRS(WKTNode::createFrom(
+ wkt, indexEnd, 0, indexEnd));
+ return CompoundCRS::createLax(
+ util::PropertyMap().set(
+ IdentifiedObject::NAME_KEY,
+ horizCRS->nameStr() + " + " +
+ vertCRS->nameStr()),
+ {NN_NO_CHECK(horizCRS), vertCRS},
+ d->dbContext_);
+ }
+ }
+ }
+ }
}
return d->build(root);
};