aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-11-15 12:43:20 +0100
committerGitHub <noreply@github.com>2021-11-15 12:43:20 +0100
commit97a5fad1f01bd3102768bcedaa88dbeb82e069b5 (patch)
tree73491043fb834b0c9c0d18ff0889256f0602ca58
parentcf8c1a825bb80b472900c0ca2d0530f86271995d (diff)
parent4db10d9e13223fd5aaafc2c187d9a96676c1d385 (diff)
downloadPROJ-97a5fad1f01bd3102768bcedaa88dbeb82e069b5.tar.gz
PROJ-97a5fad1f01bd3102768bcedaa88dbeb82e069b5.zip
Merge pull request #2939 from OSGeo/backport-2937-to-8.2
[Backport 8.2] createOperations(): do not stop at the first operation in the PROJ namespace for vertical transformations
-rw-r--r--src/iso19111/operation/coordinateoperationfactory.cpp37
-rw-r--r--test/unit/test_operationfactory.cpp47
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);
+ }
}
// ---------------------------------------------------------------------------