@@ -6467,17 +6467,23 @@ void CoordinateOperationFactory::Private::createOperationsCompoundToCompound(
64676467 if (srcGeog == nullptr || dstGeog == nullptr ) {
64686468 return ;
64696469 }
6470-
6471- // Use PointMotionOperations if appropriate and available
6470+ const bool srcGeogIsSameAsDstGeog = srcGeog-> _isEquivalentTo (
6471+ dstGeog. get (), util::IComparable::Criterion::EQUIVALENT);
64726472 const auto &authFactory = context.context ->getAuthorityFactory ();
64736473 auto dbContext =
64746474 authFactory ? authFactory->databaseContext ().as_nullable () : nullptr ;
6475+ const auto intermGeogSrc = srcGeog->promoteTo3D (std::string (), dbContext);
6476+ const auto intermGeogDst =
6477+ srcGeogIsSameAsDstGeog ? intermGeogSrc
6478+ : dstGeog->promoteTo3D (std::string (), dbContext);
6479+ const auto opsGeogSrcToGeogDst = createOperations (
6480+ intermGeogSrc, sourceEpoch, intermGeogDst, targetEpoch, context);
64756481
6482+ // Use PointMotionOperations if appropriate and available
64766483 if (authFactory && sourceEpoch.has_value () && targetEpoch.has_value () &&
64776484 !sourceEpoch->coordinateEpoch ()._isEquivalentTo (
64786485 targetEpoch->coordinateEpoch ()) &&
6479- srcGeog->_isEquivalentTo (dstGeog.get (),
6480- util::IComparable::Criterion::EQUIVALENT)) {
6486+ srcGeogIsSameAsDstGeog) {
64816487 const auto pmoSrc = authFactory->getPointMotionOperationsFor (
64826488 NN_NO_CHECK (srcGeog), true );
64836489 if (!pmoSrc.empty ()) {
@@ -6603,9 +6609,20 @@ void CoordinateOperationFactory::Private::createOperationsCompoundToCompound(
66036609 // If we didn't find a non-ballpark transformation between
66046610 // the 2 vertical CRS, then try through intermediate geographic
66056611 // CRS
6612+ // Do that although when the geographic CRS of the source and
6613+ // target CRS are not the same, but only if they have a 3D
6614+ // known version, and there is a non-ballpark transformation
6615+ // between them.
6616+ // This helps for "GDA94 + AHD height" to "GDA2020 + AVWS
6617+ // height" going through GDA94 3D and GDA2020 3D
66066618 bTryThroughIntermediateGeogCRS =
66076619 (verticalTransforms.size () == 1 &&
6608- verticalTransforms.front ()->hasBallparkTransformation ());
6620+ verticalTransforms.front ()->hasBallparkTransformation ()) ||
6621+ (!srcGeogIsSameAsDstGeog &&
6622+ !intermGeogSrc->identifiers ().empty () &&
6623+ !intermGeogDst->identifiers ().empty () &&
6624+ !opsGeogSrcToGeogDst.empty () &&
6625+ !opsGeogSrcToGeogDst.front ()->hasBallparkTransformation ());
66096626 }
66106627 }
66116628 }
@@ -6663,14 +6680,6 @@ void CoordinateOperationFactory::Private::createOperationsCompoundToCompound(
66636680 // WGS 84 + EGM96 --> ETRS89 + Belfast height where
66646681 // there is a geoid model for EGM96 referenced to WGS 84
66656682 // and a geoid model for Belfast height referenced to ETRS89
6666- const auto intermGeogSrc =
6667- srcGeog->promoteTo3D (std::string (), dbContext);
6668- const bool intermGeogSrcIsSameAsIntermGeogDst =
6669- srcGeog->_isEquivalentTo (dstGeog.get ());
6670- const auto intermGeogDst =
6671- intermGeogSrcIsSameAsIntermGeogDst
6672- ? intermGeogSrc
6673- : dstGeog->promoteTo3D (std::string (), dbContext);
66746683 const auto opsSrcToGeog = createOperations (
66756684 sourceCRS, sourceEpoch, intermGeogSrc, sourceEpoch, context);
66766685 const auto opsGeogToTarget = createOperations (
@@ -6710,9 +6719,6 @@ void CoordinateOperationFactory::Private::createOperationsCompoundToCompound(
67106719 double bestAccuracy = -1 ;
67116720 size_t bestStepCount = 0 ;
67126721 if (hasNonTrivialSrcTransf && hasNonTrivialTargetTransf) {
6713- const auto opsGeogSrcToGeogDst =
6714- createOperations (intermGeogSrc, sourceEpoch, intermGeogDst,
6715- targetEpoch, context);
67166722 // In first pass, exclude (horizontal) ballpark operations, but
67176723 // accept them in second pass.
67186724 for (int pass = 0 ; pass <= 1 && res.empty (); pass++) {
@@ -6741,7 +6747,7 @@ void CoordinateOperationFactory::Private::createOperationsCompoundToCompound(
67416747 try {
67426748 res.emplace_back (
67436749 ConcatenatedOperation::createComputeMetadata (
6744- intermGeogSrcIsSameAsIntermGeogDst
6750+ srcGeogIsSameAsDstGeog
67456751 ? std::vector<
67466752 CoordinateOperationNNPtr>{op1,
67476753 op3}
0 commit comments