From b4c0550511828d35032fff0ee3baffce72f898ef Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 4 Dec 2024 23:46:46 +0100 Subject: [PATCH] createOperations(): do Helmert transformation in 2D when one of source or target CRS is compound Fixes #4335 --- src/iso19111/operation/singleoperation.cpp | 6 +++- test/unit/test_operationfactory.cpp | 38 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/iso19111/operation/singleoperation.cpp b/src/iso19111/operation/singleoperation.cpp index 354975d386..031327c0f5 100644 --- a/src/iso19111/operation/singleoperation.cpp +++ b/src/iso19111/operation/singleoperation.cpp @@ -3545,7 +3545,11 @@ bool SingleOperation::exportToPROJStringGeneric( ((sourceCRSGeog && sourceCRSGeog->coordinateSystem()->axisList().size() == 2) || (targetCRSGeog && - targetCRSGeog->coordinateSystem()->axisList().size() == 2)); + targetCRSGeog->coordinateSystem()->axisList().size() == 2)) || + (!sourceCRSGeog && + dynamic_cast(l_sourceCRS.get())) || + (!targetCRSGeog && + dynamic_cast(l_targetCRS.get())); if (l_sourceCRS) { setupPROJGeodeticSourceCRS(formatter, NN_NO_CHECK(l_sourceCRS), diff --git a/test/unit/test_operationfactory.cpp b/test/unit/test_operationfactory.cpp index e406834a81..ad38690999 100644 --- a/test/unit/test_operationfactory.cpp +++ b/test/unit/test_operationfactory.cpp @@ -5954,6 +5954,44 @@ TEST(operation, // --------------------------------------------------------------------------- +TEST(operation, compoundCRS_to_compoundCRS_context_helmert) { + auto dbContext = DatabaseContext::create(); + auto authFactory = AuthorityFactory::create(dbContext, "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + ctxt->setGridAvailabilityUse( + CoordinateOperationContext::GridAvailabilityUse:: + IGNORE_GRID_AVAILABILITY); + ctxt->setSpatialCriterion( + CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION); + // GDA94 + AHD height + auto objSrc = createFromUserInput("EPSG:9464", dbContext); + auto srcCrs = nn_dynamic_pointer_cast(objSrc); + ASSERT_TRUE(srcCrs != nullptr); + // GDA2020 + AHD height + auto objDest = createFromUserInput("EPSG:9463", dbContext); + auto destCrs = nn_dynamic_pointer_cast(objDest); + ASSERT_TRUE(destCrs != nullptr); + auto list = CoordinateOperationFactory::create()->createOperations( + NN_NO_CHECK(srcCrs), NN_NO_CHECK(destCrs), ctxt); + ASSERT_GE(list.size(), 1U); + // Check presence of push/pop v_3 + EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline " + "+step +proj=axisswap +order=2,1 " + "+step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=push +v_3 " + "+step +proj=cart +ellps=GRS80 " + "+step +proj=helmert +x=0.06155 +y=-0.01087 +z=-0.04019 " + "+rx=-0.0394924 +ry=-0.0327221 +rz=-0.0328979 +s=-0.009994 " + "+convention=coordinate_frame " + "+step +inv +proj=cart +ellps=GRS80 " + "+step +proj=pop +v_3 " + "+step +proj=unitconvert +xy_in=rad +xy_out=deg " + "+step +proj=axisswap +order=2,1"); +} + +// --------------------------------------------------------------------------- + TEST( operation, compoundCRS_to_compoundCRS_concatenated_operation_with_two_vert_transformation) {