diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-03-25 12:44:05 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-03-25 13:05:40 +0100 |
| commit | 46f08f1434f66a4160d7c74923efcfb81505b398 (patch) | |
| tree | 680c623c5eee0978cf03e2f6475995d1e8cd52d0 | |
| parent | d4fd50f10ecabb9e9642cb4f877262e082677be4 (diff) | |
| download | PROJ-46f08f1434f66a4160d7c74923efcfb81505b398.tar.gz PROJ-46f08f1434f66a4160d7c74923efcfb81505b398.zip | |
WKT2_2018: always export ID in base crs node, even if there is one on upper node
This is a particular logic allowed by paragraph 7.3.3 Identifier
of OGC 18-010r6
| -rw-r--r-- | include/proj/io.hpp | 2 | ||||
| -rw-r--r-- | src/iso19111/crs.cpp | 6 | ||||
| -rw-r--r-- | src/iso19111/io.cpp | 12 | ||||
| -rw-r--r-- | test/cli/testprojinfo_out.dist | 3 | ||||
| -rw-r--r-- | test/unit/test_crs.cpp | 46 | ||||
| -rw-r--r-- | test/unit/test_io.cpp | 15 |
6 files changed, 81 insertions, 3 deletions
diff --git a/include/proj/io.hpp b/include/proj/io.hpp index 90163001..ace8ad9d 100644 --- a/include/proj/io.hpp +++ b/include/proj/io.hpp @@ -302,6 +302,8 @@ class PROJ_GCC_DLL WKTFormatter { PROJ_INTERNAL bool primeMeridianOrParameterUnitOmittedIfSameAsAxis() const; PROJ_INTERNAL bool primeMeridianInDegree() const; PROJ_INTERNAL bool outputCSUnitOnlyOnceIfSame() const; + PROJ_INTERNAL bool idOnTopLevelOnly() const; + PROJ_INTERNAL bool topLevelHasId() const; /** WKT version. */ enum class Version { diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 9779d817..2dc6b3bf 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -2432,7 +2432,8 @@ void DerivedCRS::baseExportToWKT(io::WKTFormatter *formatter, !l_baseCRS->identifiers().empty()); formatter->addQuotedString(l_baseCRS->nameStr()); l_baseCRS->exportDatumOrDatumEnsembleToWkt(formatter); - if (formatter->use2018Keywords() && formatter->outputId()) { + if (formatter->use2018Keywords() && + !(formatter->idOnTopLevelOnly() && formatter->topLevelHasId())) { l_baseCRS->formatID(formatter); } formatter->endNode(); @@ -2673,7 +2674,8 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const { geodeticCRSAxisList[0]->unit()._exportToWKT(formatter); } l_baseCRS->primeMeridian()->_exportToWKT(formatter); - if (formatter->use2018Keywords() && formatter->outputId()) { + if (formatter->use2018Keywords() && + !(formatter->idOnTopLevelOnly() && formatter->topLevelHasId())) { l_baseCRS->formatID(formatter); } formatter->endNode(); diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 220ee967..78b18719 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -634,6 +634,18 @@ bool WKTFormatter::primeMeridianInDegree() const { // --------------------------------------------------------------------------- +bool WKTFormatter::idOnTopLevelOnly() const { + return d->params_.idOnTopLevelOnly_; +} + +// --------------------------------------------------------------------------- + +bool WKTFormatter::topLevelHasId() const { + return d->stackHasId_.size() >= 2 && d->stackHasId_[1]; +} + +// --------------------------------------------------------------------------- + WKTFormatter::Version WKTFormatter::version() const { return d->params_.version_; } diff --git a/test/cli/testprojinfo_out.dist b/test/cli/testprojinfo_out.dist index a2e2cab9..ee9aeca7 100644 --- a/test/cli/testprojinfo_out.dist +++ b/test/cli/testprojinfo_out.dist @@ -633,7 +633,8 @@ PROJCRS["Monte Mario (Rome) / Italy zone 1", ELLIPSOID["International 1924",6378388,297, LENGTHUNIT["metre",1]]], PRIMEM["Rome",12.4523333333333, - ANGLEUNIT["degree",0.0174532925199433]]], + ANGLEUNIT["degree",0.0174532925199433]], + ID["EPSG",4806]], CONVERSION["Italy zone 1", METHOD["Transverse Mercator", ID["EPSG",9807]], diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index bfd6ee66..d7303df9 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -1601,6 +1601,52 @@ TEST(crs, projectedCRS_as_WKT2) { // --------------------------------------------------------------------------- +TEST(crs, projectedCRS_as_WKT2_2018) { + auto crs = createProjected(); + + auto expected = + "PROJCRS[\"WGS 84 / UTM zone 31N\",\n" + " BASEGEOGCRS[\"WGS 84\",\n" + " DATUM[\"World Geodetic System 1984\",\n" + " ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n" + " LENGTHUNIT[\"metre\",1]]],\n" + " PRIMEM[\"Greenwich\",0,\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " ID[\"EPSG\",4326]],\n" + " CONVERSION[\"UTM zone 31N\",\n" + " METHOD[\"Transverse Mercator\",\n" + " ID[\"EPSG\",9807]],\n" + " PARAMETER[\"Latitude of natural origin\",0,\n" + " ANGLEUNIT[\"degree\",0.0174532925199433],\n" + " ID[\"EPSG\",8801]],\n" + " PARAMETER[\"Longitude of natural origin\",3,\n" + " ANGLEUNIT[\"degree\",0.0174532925199433],\n" + " ID[\"EPSG\",8802]],\n" + " PARAMETER[\"Scale factor at natural origin\",0.9996,\n" + " SCALEUNIT[\"unity\",1],\n" + " ID[\"EPSG\",8805]],\n" + " PARAMETER[\"False easting\",500000,\n" + " LENGTHUNIT[\"metre\",1],\n" + " ID[\"EPSG\",8806]],\n" + " PARAMETER[\"False northing\",0,\n" + " LENGTHUNIT[\"metre\",1],\n" + " ID[\"EPSG\",8807]]],\n" + " CS[Cartesian,2],\n" + " AXIS[\"(E)\",east,\n" + " ORDER[1],\n" + " LENGTHUNIT[\"metre\",1]],\n" + " AXIS[\"(N)\",north,\n" + " ORDER[2],\n" + " LENGTHUNIT[\"metre\",1]],\n" + " ID[\"EPSG\",32631]]"; + + EXPECT_EQ( + crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018).get()), + expected); +} +// --------------------------------------------------------------------------- + TEST(crs, projectedCRS_as_WKT2_simplified) { auto crs = createProjected(); diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 2181b321..17b3c334 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -1663,6 +1663,21 @@ TEST(wkt_parse, wkt2_2018_projected_with_id_in_basegeodcrs) { ASSERT_TRUE(crs != nullptr); ASSERT_EQ(crs->baseCRS()->identifiers().size(), 1U); EXPECT_EQ(crs->baseCRS()->identifiers().front()->code(), "4326"); + + { + auto got_wkt = crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018).get()); + EXPECT_TRUE(got_wkt.find("ID[\"EPSG\",4326]]") != std::string::npos) + << got_wkt; + } + + { + auto got_wkt = crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018_SIMPLIFIED) + .get()); + EXPECT_TRUE(got_wkt.find("ID[\"EPSG\",4326]]") == std::string::npos) + << got_wkt; + } } // --------------------------------------------------------------------------- |
