aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-05-14 16:08:06 +0200
committerEven Rouault <even.rouault@spatialys.com>2020-05-14 18:55:39 +0200
commit70424a9a17dbfae28dac287831a06f3aee8d2725 (patch)
treef17664ba44d36b23a32b858dbbea1bda5ab04b7e
parent11012ebcc910c4d95d5acbff43f444715ae1ad32 (diff)
downloadPROJ-70424a9a17dbfae28dac287831a06f3aee8d2725.tar.gz
PROJ-70424a9a17dbfae28dac287831a06f3aee8d2725.zip
WKT1 parsing: fix parsing of CompoundCRS that has a TOWGS84 for horizontal and PROJ4_GRIDS for vertical (refs #2217)
-rw-r--r--src/iso19111/io.cpp35
-rw-r--r--test/unit/test_operation.cpp110
2 files changed, 130 insertions, 15 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 7fddd324..af957ada 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -4544,12 +4544,27 @@ CRSPtr WKTParser::Private::buildCRS(const WKTNodeNNPtr &node) {
const auto *nodeP = node->GP();
const std::string &name(nodeP->value());
+ const auto applyHorizontalBoundCRSParams = [&](const CRSNNPtr &crs) {
+ if (!toWGS84Parameters_.empty()) {
+ auto ret = BoundCRS::createFromTOWGS84(crs, toWGS84Parameters_);
+ toWGS84Parameters_.clear();
+ return util::nn_static_pointer_cast<CRS>(ret);
+ } else if (!datumPROJ4Grids_.empty()) {
+ auto ret = BoundCRS::createFromNadgrids(crs, datumPROJ4Grids_);
+ datumPROJ4Grids_.clear();
+ return util::nn_static_pointer_cast<CRS>(ret);
+ }
+ return crs;
+ };
+
if (isGeodeticCRS(name)) {
if (!isNull(nodeP->lookForChild(WKTConstants::BASEGEOGCRS,
WKTConstants::BASEGEODCRS))) {
- return buildDerivedGeodeticCRS(node);
+ return util::nn_static_pointer_cast<CRS>(
+ applyHorizontalBoundCRSParams(buildDerivedGeodeticCRS(node)));
} else {
- return util::nn_static_pointer_cast<CRS>(buildGeodeticCRS(node));
+ return util::nn_static_pointer_cast<CRS>(
+ applyHorizontalBoundCRSParams(buildGeodeticCRS(node)));
}
}
@@ -4574,12 +4589,14 @@ CRSPtr WKTParser::Private::buildCRS(const WKTNodeNNPtr &node) {
PROJStringParser().createFromPROJString(projString);
auto crs = nn_dynamic_pointer_cast<CRS>(projObj);
if (crs) {
- return crs;
+ return util::nn_static_pointer_cast<CRS>(
+ applyHorizontalBoundCRSParams(NN_NO_CHECK(crs)));
}
} catch (const io::ParsingException &) {
}
}
- return util::nn_static_pointer_cast<CRS>(buildProjectedCRS(node));
+ return util::nn_static_pointer_cast<CRS>(
+ applyHorizontalBoundCRSParams(buildProjectedCRS(node)));
}
if (ci_equal(name, WKTConstants::VERT_CS) ||
@@ -4652,16 +4669,6 @@ BaseObjectNNPtr WKTParser::Private::build(const WKTNodeNNPtr &node) {
auto crs = buildCRS(node);
if (crs) {
- if (!toWGS84Parameters_.empty()) {
- return util::nn_static_pointer_cast<BaseObject>(
- BoundCRS::createFromTOWGS84(NN_NO_CHECK(crs),
- toWGS84Parameters_));
- }
- if (!datumPROJ4Grids_.empty()) {
- return util::nn_static_pointer_cast<BaseObject>(
- BoundCRS::createFromNadgrids(NN_NO_CHECK(crs),
- datumPROJ4Grids_));
- }
return util::nn_static_pointer_cast<BaseObject>(NN_NO_CHECK(crs));
}
diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp
index d8944aa8..ae66c1ed 100644
--- a/test/unit/test_operation.cpp
+++ b/test/unit/test_operation.cpp
@@ -7172,7 +7172,7 @@ TEST(operation,
" AUTHORITY[\"EPSG\",\"6360\"]]]";
auto obj = WKTParser().createFromWKT(wkt);
- auto crs = nn_dynamic_pointer_cast<BoundCRS>(obj);
+ auto crs = nn_dynamic_pointer_cast<CompoundCRS>(obj);
ASSERT_TRUE(crs != nullptr);
auto op = CoordinateOperationFactory::create()->createOperation(
NN_NO_CHECK(crs), GeographicCRS::EPSG_4979);
@@ -7351,6 +7351,114 @@ TEST(operation, compoundCRS_to_compoundCRS_with_bound_crs_in_horiz_and_vert) {
// ---------------------------------------------------------------------------
+TEST(
+ operation,
+ compoundCRS_to_compoundCRS_with_bound_crs_in_horiz_and_vert_WKT1_same_geoidgrids_context) {
+ auto objSrc = WKTParser().createFromWKT(
+ "COMPD_CS[\"NAD83 / Alabama West + NAVD88 height - Geoid12B "
+ "(Meters)\",\n"
+ " PROJCS[\"NAD83 / Alabama West\",\n"
+ " GEOGCS[\"NAD83\",\n"
+ " DATUM[\"North_American_Datum_1983\",\n"
+ " SPHEROID[\"GRS 1980\",6378137,298.257222101,\n"
+ " AUTHORITY[\"EPSG\",\"7019\"]],\n"
+ " TOWGS84[0,0,0,0,0,0,0],\n"
+ " AUTHORITY[\"EPSG\",\"6269\"]],\n"
+ " PRIMEM[\"Greenwich\",0,\n"
+ " AUTHORITY[\"EPSG\",\"8901\"]],\n"
+ " UNIT[\"degree\",0.0174532925199433,\n"
+ " AUTHORITY[\"EPSG\",\"9122\"]],\n"
+ " AUTHORITY[\"EPSG\",\"4269\"]],\n"
+ " PROJECTION[\"Transverse_Mercator\"],\n"
+ " PARAMETER[\"latitude_of_origin\",30],\n"
+ " PARAMETER[\"central_meridian\",-87.5],\n"
+ " PARAMETER[\"scale_factor\",0.999933333],\n"
+ " PARAMETER[\"false_easting\",600000],\n"
+ " PARAMETER[\"false_northing\",0],\n"
+ " UNIT[\"metre\",1,\n"
+ " AUTHORITY[\"EPSG\",\"9001\"]],\n"
+ " AXIS[\"X\",EAST],\n"
+ " AXIS[\"Y\",NORTH],\n"
+ " AUTHORITY[\"EPSG\",\"26930\"]],\n"
+ " VERT_CS[\"NAVD88 height\",\n"
+ " VERT_DATUM[\"North American Vertical Datum 1988\",2005,\n"
+ " "
+ "EXTENSION[\"PROJ4_GRIDS\",\"g2012a_alaska.gtx,g2012a_hawaii.gtx,"
+ "g2012a_conus.gtx\"],\n"
+ " AUTHORITY[\"EPSG\",\"5103\"]],\n"
+ " UNIT[\"metre\",1,\n"
+ " AUTHORITY[\"EPSG\",\"9001\"]],\n"
+ " AXIS[\"Gravity-related height\",UP],\n"
+ " AUTHORITY[\"EPSG\",\"5703\"]]]");
+ auto src = nn_dynamic_pointer_cast<CRS>(objSrc);
+ ASSERT_TRUE(src != nullptr);
+ auto objDst = WKTParser().createFromWKT(
+ "COMPD_CS[\"NAD_1983_StatePlane_Alabama_West_FIPS_0102_Feet + NAVD88 "
+ "height - Geoid12B (US Feet)\",\n"
+ " PROJCS[\"NAD_1983_StatePlane_Alabama_West_FIPS_0102_Feet\",\n"
+ " GEOGCS[\"NAD83\",\n"
+ " DATUM[\"North_American_Datum_1983\",\n"
+ " SPHEROID[\"GRS 1980\",6378137,298.257222101,\n"
+ " AUTHORITY[\"EPSG\",\"7019\"]],\n"
+ " TOWGS84[0,0,0,0,0,0,0],\n"
+ " AUTHORITY[\"EPSG\",\"6269\"]],\n"
+ " PRIMEM[\"Greenwich\",0],\n"
+ " UNIT[\"Degree\",0.0174532925199433]],\n"
+ " PROJECTION[\"Transverse_Mercator\"],\n"
+ " PARAMETER[\"latitude_of_origin\",30],\n"
+ " PARAMETER[\"central_meridian\",-87.5],\n"
+ " PARAMETER[\"scale_factor\",0.999933333333333],\n"
+ " PARAMETER[\"false_easting\",1968500],\n"
+ " PARAMETER[\"false_northing\",0],\n"
+ " UNIT[\"US survey foot\",0.304800609601219,\n"
+ " AUTHORITY[\"EPSG\",\"9003\"]],\n"
+ " AXIS[\"Easting\",EAST],\n"
+ " AXIS[\"Northing\",NORTH],\n"
+ " AUTHORITY[\"ESRI\",\"102630\"]],\n"
+ " VERT_CS[\"NAVD88 height (ftUS)\",\n"
+ " VERT_DATUM[\"North American Vertical Datum 1988\",2005,\n"
+ " "
+ "EXTENSION[\"PROJ4_GRIDS\",\"g2012a_alaska.gtx,g2012a_hawaii.gtx,"
+ "g2012a_conus.gtx\"],\n"
+ " AUTHORITY[\"EPSG\",\"5103\"]],\n"
+ " UNIT[\"US survey foot\",0.304800609601219,\n"
+ " AUTHORITY[\"EPSG\",\"9003\"]],\n"
+ " AXIS[\"Gravity-related height\",UP],\n"
+ " AUTHORITY[\"EPSG\",\"6360\"]]]");
+ auto dst = nn_dynamic_pointer_cast<CRS>(objDst);
+ ASSERT_TRUE(dst != nullptr);
+
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), "EPSG");
+ auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0);
+ ctxt->setGridAvailabilityUse(
+ CoordinateOperationContext::GridAvailabilityUse::
+ IGNORE_GRID_AVAILABILITY);
+ ctxt->setSpatialCriterion(
+ CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION);
+ auto list = CoordinateOperationFactory::create()->createOperations(
+ NN_CHECK_ASSERT(src), NN_CHECK_ASSERT(dst), ctxt);
+ ASSERT_GE(list.size(), 1U);
+ EXPECT_EQ(list[0]->nameStr(),
+ "Inverse of unnamed + "
+ "Transformation from NAD83 to WGS84 + "
+ "NAVD88 height to WGS84 ellipsoidal height + "
+ "Inverse of NAVD88 height to WGS84 ellipsoidal height + "
+ "NAVD88 height to NAVD88 height (ftUS) + "
+ "Inverse of Transformation from NAD83 to WGS84 + "
+ "unnamed");
+ EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline "
+ "+step +inv +proj=tmerc +lat_0=30 +lon_0=-87.5 +k=0.999933333 "
+ "+x_0=600000 +y_0=0 +ellps=GRS80 "
+ "+step +proj=unitconvert +z_in=m +z_out=us-ft "
+ "+step +proj=tmerc +lat_0=30 +lon_0=-87.5 +k=0.999933333333333 "
+ "+x_0=600000 +y_0=0 +ellps=GRS80 "
+ "+step +proj=unitconvert +xy_in=m +xy_out=us-ft");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(operation, compoundCRS_to_compoundCRS_context) {
auto authFactory =
AuthorityFactory::create(DatabaseContext::create(), "EPSG");