diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-10-20 21:51:45 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2020-10-20 21:51:45 +0200 |
| commit | 31f272708eaba9274b4b3c02240e9e7012c6b2b8 (patch) | |
| tree | 87825317534c3d41159ea56497bf053f8b240e61 | |
| parent | 45c819b69fb401c21c5571ddc2a602a8e72385d6 (diff) | |
| download | PROJ-31f272708eaba9274b4b3c02240e9e7012c6b2b8.tar.gz PROJ-31f272708eaba9274b4b3c02240e9e7012c6b2b8.zip | |
VerticalCRS: morph CRS and datum name using ESRI aliases on import from / export to WKT1:ESRI
| -rw-r--r-- | src/iso19111/crs.cpp | 20 | ||||
| -rw-r--r-- | src/iso19111/datum.cpp | 17 | ||||
| -rw-r--r-- | src/iso19111/io.cpp | 41 | ||||
| -rw-r--r-- | test/unit/test_crs.cpp | 19 | ||||
| -rw-r--r-- | test/unit/test_io.cpp | 25 |
5 files changed, 119 insertions, 3 deletions
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index dbe3b211..52b10119 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -2851,7 +2851,25 @@ void VerticalCRS::_exportToWKT(io::WKTFormatter *formatter) const { ? io::WKTConstants::VERTCS : io::WKTConstants::VERT_CS, !identifiers().empty()); - formatter->addQuotedString(nameStr()); + + auto l_name = nameStr(); + if (formatter->useESRIDialect()) { + bool aliasFound = false; + const auto &dbContext = formatter->databaseContext(); + if (dbContext) { + auto l_alias = dbContext->getAliasFromOfficialName( + l_name, "vertical_crs", "ESRI"); + if (!l_alias.empty()) { + l_name = l_alias; + aliasFound = true; + } + } + if (!aliasFound) { + l_name = io::WKTFormatter::morphNameToESRI(l_name); + } + } + + formatter->addQuotedString(l_name); exportDatumOrDatumEnsembleToWkt(formatter); const auto &cs = SingleCRS::getPrivate()->coordinateSystem; const auto &axisList = cs->axisList(); diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 7d42fd13..5bc8074c 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -1933,8 +1933,23 @@ void VerticalReferenceFrame::_exportToWKT( ? io::WKTConstants::VDATUM : io::WKTConstants::VERT_DATUM, !identifiers().empty()); - const auto &l_name = nameStr(); + auto l_name = nameStr(); if (!l_name.empty()) { + if (!isWKT2 && formatter->useESRIDialect()) { + bool aliasFound = false; + const auto &dbContext = formatter->databaseContext(); + if (dbContext) { + auto l_alias = dbContext->getAliasFromOfficialName( + l_name, "vertical_datum", "ESRI"); + if (!l_alias.empty()) { + l_name = l_alias; + aliasFound = true; + } + } + if (!aliasFound) { + l_name = io::WKTFormatter::morphNameToESRI(l_name); + } + } formatter->addQuotedString(l_name); } else { formatter->addQuotedString("unnamed"); diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 7a107f96..99fc6046 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -4006,6 +4006,22 @@ VerticalReferenceFrameNNPtr WKTParser::Private::buildVerticalReferenceFrame( const auto *nodeP = node->GP(); const std::string &name(nodeP->value()); auto &props = buildProperties(node); + + if (esriStyle_ && dbContext_) { + std::string outTableName; + std::string authNameFromAlias; + std::string codeFromAlias; + auto authFactory = + AuthorityFactory::create(NN_NO_CHECK(dbContext_), std::string()); + const std::string datumName = stripQuotes(nodeP->children()[0]); + auto officialName = authFactory->getOfficialNameFromAlias( + datumName, "vertical_datum", "ESRI", false, outTableName, + authNameFromAlias, codeFromAlias); + if (!officialName.empty()) { + props.set(IdentifiedObject::NAME_KEY, officialName); + } + } + if (ci_equal(name, WKTConstants::VERT_DATUM)) { const auto &children = nodeP->children(); if (children.size() >= 2) { @@ -4137,6 +4153,16 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) { throw ParsingException("Missing VDATUM or ENSEMBLE node"); } + for (const auto &childNode : nodeP->children()) { + const auto &childNodeChildren = childNode->GP()->children(); + if (childNodeChildren.size() == 2 && + ci_equal(childNode->GP()->value(), WKTConstants::PARAMETER) && + childNodeChildren[0]->GP()->value() == "\"Vertical_Shift\"") { + esriStyle_ = true; + break; + } + } + auto &dynamicNode = nodeP->lookForChild(WKTConstants::DYNAMIC); auto datum = !isNull(datumNode) @@ -4162,6 +4188,21 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) { auto &props = buildProperties(node); + if (esriStyle_ && dbContext_) { + std::string outTableName; + std::string authNameFromAlias; + std::string codeFromAlias; + auto authFactory = + AuthorityFactory::create(NN_NO_CHECK(dbContext_), std::string()); + const std::string vertCRSName = stripQuotes(nodeP->children()[0]); + auto officialName = authFactory->getOfficialNameFromAlias( + vertCRSName, "vertical_crs", "ESRI", false, outTableName, + authNameFromAlias, codeFromAlias); + if (!officialName.empty()) { + props.set(IdentifiedObject::NAME_KEY, officialName); + } + } + // Deal with Lidar WKT1 VertCRS that embeds geoid model in CRS name, // following conventions from // https://pubs.usgs.gov/tm/11b4/pdf/tm11-B4.pdf diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index c2031081..a0fee905 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -3593,7 +3593,7 @@ TEST(crs, verticalCRS_as_WKT1_GDAL) { TEST(crs, verticalCRS_as_WKT1_ESRI) { auto crs = createVerticalCRS(); - auto expected = "VERTCS[\"ODN height\",VDATUM[\"Ordnance Datum Newlyn\"]," + auto expected = "VERTCS[\"ODN_height\",VDATUM[\"Ordnance_Datum_Newlyn\"]," "PARAMETER[\"Vertical_Shift\",0.0]," "PARAMETER[\"Direction\",1.0]," "UNIT[\"Meter\",1.0]]"; @@ -3603,6 +3603,23 @@ TEST(crs, verticalCRS_as_WKT1_ESRI) { WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI).get()), expected); } + +// --------------------------------------------------------------------------- + +TEST(crs, verticalCRS_as_WKT1_ESRI_context) { + auto crs = createVerticalCRS(); + auto expected = "VERTCS[\"Newlyn\",VDATUM[\"Ordnance_Datum_Newlyn\"]," + "PARAMETER[\"Vertical_Shift\",0.0]," + "PARAMETER[\"Direction\",1.0]," + "UNIT[\"Meter\",1.0]]"; + + EXPECT_EQ(crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, + DatabaseContext::create()) + .get()), + expected); +} + // --------------------------------------------------------------------------- TEST(crs, verticalCRS_down_as_WKT1_ESRI) { diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 1be0f2aa..055b1e1d 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -2106,6 +2106,31 @@ TEST(wkt_parse, VERTCS_WKT1_ESRI) { // --------------------------------------------------------------------------- +TEST(wkt_parse, VERTCS_WKT1_ESRI_context) { + auto wkt = "VERTCS[\"EGM2008_Geoid\",VDATUM[\"EGM2008_Geoid\"]," + "PARAMETER[\"Vertical_Shift\",0.0]," + "PARAMETER[\"Direction\",1.0],UNIT[\"Meter\",1.0]]"; + + auto obj = WKTParser() + .attachDatabaseContext(DatabaseContext::create()) + .createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast<VerticalCRS>(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_EQ(crs->nameStr(), "EGM2008 height"); + + auto datum = crs->datum(); + EXPECT_EQ(datum->nameStr(), "EGM2008 geoid"); + + auto cs = crs->coordinateSystem(); + ASSERT_EQ(cs->axisList().size(), 1U); + EXPECT_EQ(cs->axisList()[0]->direction(), AxisDirection::UP); + + EXPECT_EQ(WKTParser().guessDialect(wkt), + WKTParser::WKTGuessedDialect::WKT1_ESRI); +} + +// --------------------------------------------------------------------------- + TEST(wkt_parse, VERTCS_WKT1_ESRI_down) { auto wkt = "VERTCS[\"Caspian\",VDATUM[\"Caspian_Sea\"]," "PARAMETER[\"Vertical_Shift\",0.0]," |
