diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-05-14 16:08:06 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2020-05-14 18:55:39 +0200 |
| commit | 70424a9a17dbfae28dac287831a06f3aee8d2725 (patch) | |
| tree | f17664ba44d36b23a32b858dbbea1bda5ab04b7e | |
| parent | 11012ebcc910c4d95d5acbff43f444715ae1ad32 (diff) | |
| download | PROJ-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.cpp | 35 | ||||
| -rw-r--r-- | test/unit/test_operation.cpp | 110 |
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"); |
