diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2021-11-14 15:48:39 +0100 |
|---|---|---|
| committer | github-actions[bot] <github-actions[bot]@users.noreply.github.com> | 2021-11-14 14:49:06 +0000 |
| commit | 4db10d9e13223fd5aaafc2c187d9a96676c1d385 (patch) | |
| tree | 73491043fb834b0c9c0d18ff0889256f0602ca58 | |
| parent | cf8c1a825bb80b472900c0ca2d0530f86271995d (diff) | |
| download | PROJ-4db10d9e13223fd5aaafc2c187d9a96676c1d385.tar.gz PROJ-4db10d9e13223fd5aaafc2c187d9a96676c1d385.zip | |
Merge pull request #2937 from rouault/fix_2936
createOperations(): do not stop at the first operation in the PROJ namespace for vertical transformations
| -rw-r--r-- | src/iso19111/operation/coordinateoperationfactory.cpp | 37 | ||||
| -rw-r--r-- | test/unit/test_operationfactory.cpp | 47 |
2 files changed, 72 insertions, 12 deletions
diff --git a/src/iso19111/operation/coordinateoperationfactory.cpp b/src/iso19111/operation/coordinateoperationfactory.cpp index e9bd3cfe..971e265a 100644 --- a/src/iso19111/operation/coordinateoperationfactory.cpp +++ b/src/iso19111/operation/coordinateoperationfactory.cpp @@ -1624,6 +1624,9 @@ CoordinateOperationFactory::Private::findOpsInRegistryDirect( context.extent1, context.extent2); res.insert(res.end(), resTmp.begin(), resTmp.end()); if (authName == "PROJ") { + // Do not stop at the first transformations available in + // the PROJ namespace, but allow the next authority to + // continue continue; } if (!res.empty()) { @@ -1669,24 +1672,34 @@ CoordinateOperationFactory::Private::findOpsInRegistryDirectTo( const auto authorities(getCandidateAuthorities( authFactory, targetAuthName, targetAuthName)); + std::vector<CoordinateOperationNNPtr> res; for (const auto &authority : authorities) { + const auto authName = + authority == "any" ? std::string() : authority; const auto tmpAuthFactory = io::AuthorityFactory::create( - authFactory->databaseContext(), - authority == "any" ? std::string() : authority); - auto res = tmpAuthFactory->createFromCoordinateReferenceSystemCodes( - std::string(), std::string(), targetAuthName, targetCode, - context.context->getUsePROJAlternativeGridNames(), + authFactory->databaseContext(), authName); + auto resTmp = + tmpAuthFactory->createFromCoordinateReferenceSystemCodes( + std::string(), std::string(), targetAuthName, targetCode, + context.context->getUsePROJAlternativeGridNames(), - gridAvailabilityUse == - CoordinateOperationContext::GridAvailabilityUse:: - DISCARD_OPERATION_IF_MISSING_GRID || + gridAvailabilityUse == + CoordinateOperationContext::GridAvailabilityUse:: + DISCARD_OPERATION_IF_MISSING_GRID || + gridAvailabilityUse == + CoordinateOperationContext::GridAvailabilityUse:: + KNOWN_AVAILABLE, gridAvailabilityUse == CoordinateOperationContext::GridAvailabilityUse:: KNOWN_AVAILABLE, - gridAvailabilityUse == CoordinateOperationContext:: - GridAvailabilityUse::KNOWN_AVAILABLE, - context.context->getDiscardSuperseded(), true, true, - context.extent1, context.extent2); + context.context->getDiscardSuperseded(), true, true, + context.extent1, context.extent2); + res.insert(res.end(), resTmp.begin(), resTmp.end()); + if (authName == "PROJ") { + // Do not stop at the first transformations available in + // the PROJ namespace, but allow the next authority to continue + continue; + } if (!res.empty()) { auto resFiltered = FilterResults(res, context.context, context.extent1, diff --git a/test/unit/test_operationfactory.cpp b/test/unit/test_operationfactory.cpp index 2246c60c..a445d8c7 100644 --- a/test/unit/test_operationfactory.cpp +++ b/test/unit/test_operationfactory.cpp @@ -4922,6 +4922,53 @@ TEST(operation, compoundCRS_to_geogCRS_3D_context) { "+step +proj=unitconvert +xy_in=rad +xy_out=deg " "+step +proj=axisswap +order=2,1"); } + + // Check that we can handle vertical transformations where there is a + // mix of available ones in the PROJ namespace (mx_inegi_ggm10) and in + // in the EPSG namespace (us_noaa_g2018u0) + // This test might no longer test this scenario if mx_inegi_ggm10 is + // referenced one day by EPSG, but at least this tests a common use case. + { + auto authFactoryAll = + AuthorityFactory::create(DatabaseContext::create(), std::string()); + auto ctxt = + CoordinateOperationContext::create(authFactoryAll, nullptr, 0.0); + ctxt->setSpatialCriterion( + CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION); + ctxt->setGridAvailabilityUse( + CoordinateOperationContext::GridAvailabilityUse:: + IGNORE_GRID_AVAILABILITY); + // NAD83(2011) + NAVD88 height + auto srcObj = createFromUserInput( + "EPSG:6318+5703", authFactory->databaseContext(), false); + auto src = nn_dynamic_pointer_cast<CRS>(srcObj); + ASSERT_TRUE(src != nullptr); + auto nnSrc = NN_NO_CHECK(src); + + auto list = CoordinateOperationFactory::create()->createOperations( + nnSrc, + authFactory->createCoordinateReferenceSystem("4979"), // WGS 84 3D + ctxt); + bool foundGeoid2018 = false; + bool foundGGM10 = false; + for (const auto &op : list) { + try { + const auto projString = op->exportToPROJString( + PROJStringFormatter::create( + PROJStringFormatter::Convention::PROJ_5, + authFactory->databaseContext()) + .get()); + if (projString.find("us_noaa_g2018u0.tif") != std::string::npos) + foundGeoid2018 = true; + else if (projString.find("mx_inegi_ggm10.tif") != + std::string::npos) + foundGGM10 = true; + } catch (const std::exception &) { + } + } + EXPECT_TRUE(foundGeoid2018); + EXPECT_TRUE(foundGGM10); + } } // --------------------------------------------------------------------------- |
