aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-03-25 12:44:05 +0100
committerEven Rouault <even.rouault@spatialys.com>2019-03-25 13:05:40 +0100
commit46f08f1434f66a4160d7c74923efcfb81505b398 (patch)
tree680c623c5eee0978cf03e2f6475995d1e8cd52d0
parentd4fd50f10ecabb9e9642cb4f877262e082677be4 (diff)
downloadPROJ-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.hpp2
-rw-r--r--src/iso19111/crs.cpp6
-rw-r--r--src/iso19111/io.cpp12
-rw-r--r--test/cli/testprojinfo_out.dist3
-rw-r--r--test/unit/test_crs.cpp46
-rw-r--r--test/unit/test_io.cpp15
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;
+ }
}
// ---------------------------------------------------------------------------