diff options
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 25 | ||||
| -rw-r--r-- | test/unit/test_operation.cpp | 8 |
2 files changed, 28 insertions, 5 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 8303819f..3ffd208f 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -13212,7 +13212,7 @@ CoordinateOperationFactory::Private::createOperations( return applyInverse(createOperations(targetCRS, sourceCRS, context)); } - // boundCRS to boundCRS using the same geographic hubCRS + // boundCRS to boundCRS if (boundSrc && boundDst) { createOperationsBoundToBound(sourceCRS, targetCRS, context, boundSrc, boundDst, res); @@ -14348,6 +14348,7 @@ void CoordinateOperationFactory::Private::createOperationsBoundToBound( ENTER_FUNCTION(); + // BoundCRS to BoundCRS of horizontal CRS using the same (geographic) hub const auto &hubSrc = boundSrc->hubCRS(); auto hubSrcGeog = dynamic_cast<const crs::GeographicCRS *>(hubSrc.get()); const auto &hubDst = boundDst->hubCRS(); @@ -14396,6 +14397,28 @@ void CoordinateOperationFactory::Private::createOperationsBoundToBound( } } + // BoundCRS to BoundCRS of vertical CRS using the same vertical datum + // ==> ignore the bound transformation + auto baseOfBoundSrcAsVertCRS = + dynamic_cast<crs::VerticalCRS *>(boundSrc->baseCRS().get()); + auto baseOfBoundDstAsVertCRS = + dynamic_cast<crs::VerticalCRS *>(boundDst->baseCRS().get()); + if (baseOfBoundSrcAsVertCRS && baseOfBoundDstAsVertCRS) { + const auto datumSrc = baseOfBoundSrcAsVertCRS->datum(); + const auto datumDst = baseOfBoundDstAsVertCRS->datum(); + if (datumSrc && datumDst && + datumSrc->nameStr() == datumDst->nameStr() && + (datumSrc->nameStr() != "unknown" || + boundSrc->transformation()->_isEquivalentTo( + boundDst->transformation().get(), + util::IComparable::Criterion::EQUIVALENT))) { + res = createOperations(boundSrc->baseCRS(), boundDst->baseCRS(), + context); + return; + } + } + + // BoundCRS to BoundCRS of vertical CRS auto vertCRSOfBaseOfBoundSrc = boundSrc->baseCRS()->extractVerticalCRS(); auto vertCRSOfBaseOfBoundDst = boundDst->baseCRS()->extractVerticalCRS(); if (hubSrcGeog && hubDstGeog && diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index b2a99e64..3d002a17 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -7531,8 +7531,8 @@ TEST( auto dst = nn_dynamic_pointer_cast<CRS>(objDst); ASSERT_TRUE(dst != nullptr); - auto authFactory = - AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto dbContext = DatabaseContext::create(); + auto authFactory = AuthorityFactory::create(dbContext, "EPSG"); auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); ctxt->setGridAvailabilityUse( CoordinateOperationContext::GridAvailabilityUse:: @@ -7545,11 +7545,11 @@ TEST( 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"); + auto grids = list[0]->gridsNeeded(dbContext, false); + EXPECT_TRUE(grids.empty()); EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline " "+step +inv +proj=tmerc +lat_0=30 +lon_0=-87.5 +k=0.999933333 " |
