From 056226ee668f027e22baf6897da7507bcc98e132 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 14 May 2020 19:08:41 +0200 Subject: createOperations(): optimize BoundCRS to BoundCRS of vertical CRS using the same vertical datum --- src/iso19111/coordinateoperation.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/iso19111/coordinateoperation.cpp') 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(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(boundSrc->baseCRS().get()); + auto baseOfBoundDstAsVertCRS = + dynamic_cast(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 && -- cgit v1.2.3