Skip to content

Commit f1d29da

Browse files
committed
fixStepsDirection(): enable to define a concatenated operationg ending with a NADCOND (3D) transformation (use case of refs OSGeo#3819)
1 parent 2e52000 commit f1d29da

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/iso19111/operation/concatenatedoperation.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,47 @@ void ConcatenatedOperation::fixStepsDirection(
498498
auto newOp(Conversion::createGeographicGeocentric(
499499
NN_NO_CHECK(prevOpTarget), NN_NO_CHECK(l_targetCRS)));
500500
operationsInOut.insert(operationsInOut.begin() + i, newOp);
501+
// Particular case for https://github.com/OSGeo/PROJ/issues/3819
502+
// where the antepenultimate transformation goes to A
503+
// (geographic 3D) // and the last transformation is a NADCON 3D
504+
// but between A (geographic 2D) to B (geographic 2D), and the
505+
// concatenated transformation target CRS is B (geographic 3D)
506+
// This is due to an oddity of the EPSG database that registers
507+
// the NADCON 3D transformation between the 2D geographic CRS
508+
// and not the 3D ones.
509+
} else if (i + 1 == operationsInOut.size() &&
510+
l_sourceCRS->nameStr() == prevOpTarget->nameStr() &&
511+
l_targetCRS->nameStr() == concatOpTargetCRS->nameStr() &&
512+
isGeographic(l_targetCRS.get()) &&
513+
isGeographic(concatOpTargetCRS.get()) &&
514+
isGeographic(l_sourceCRS.get()) &&
515+
isGeographic(prevOpTarget.get()) &&
516+
dynamic_cast<const crs::GeographicCRS *>(
517+
prevOpTarget.get())
518+
->coordinateSystem()
519+
->axisList()
520+
.size() == 3 &&
521+
dynamic_cast<const crs::GeographicCRS *>(
522+
l_sourceCRS.get())
523+
->coordinateSystem()
524+
->axisList()
525+
.size() == 2 &&
526+
dynamic_cast<const crs::GeographicCRS *>(
527+
l_targetCRS.get())
528+
->coordinateSystem()
529+
->axisList()
530+
.size() == 2) {
531+
const auto transf =
532+
dynamic_cast<const Transformation *>(op.get());
533+
if (transf &&
534+
(transf->method()->getEPSGCode() ==
535+
EPSG_CODE_METHOD_NADCON5_3D ||
536+
transf->parameterValue(
537+
PROJ_WKT2_PARAMETER_LATITUDE_LONGITUDE_ELLIPOISDAL_HEIGHT_DIFFERENCE_FILE,
538+
0))) {
539+
op->setCRSs(NN_NO_CHECK(prevOpTarget), concatOpTargetCRS,
540+
nullptr);
541+
}
501542
}
502543
}
503544
}

0 commit comments

Comments
 (0)