From 45ce4a8c780c4408c4dbe58f8dce0713086ea50b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 28 Mar 2019 16:33:26 +0000 Subject: createOperations(): improve BoundCRS<-->non-bound-CRS case Fixes #1388 Typically helps for projinfo -s "+proj=longlat +ellps=GRS80 +towgs84=1,2,3 +type=crs" -t EPSG:4258 by researching operations from the pivot WGS84 implied by the towgs84 clause to EPSG:4258. --- src/iso19111/coordinateoperation.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 50a6a003..957d47cd 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -11690,7 +11690,6 @@ CoordinateOperationFactory::Private::createOperations( return applyInverse(createOperations(targetCRS, sourceCRS, context)); } - // boundCRS to a geogCRS that is the same as the hubCRS auto boundSrc = dynamic_cast(sourceCRS.get()); auto geogDst = dynamic_cast(targetCRS.get()); if (boundSrc && geogDst) { @@ -11699,6 +11698,7 @@ CoordinateOperationFactory::Private::createOperations( dynamic_cast(hubSrc.get()); auto geogCRSOfBaseOfBoundSrc = boundSrc->baseCRS()->extractGeographicCRS(); + // Is it: boundCRS to a geogCRS that is the same as the hubCRS ? if (hubSrcGeog && geogCRSOfBaseOfBoundSrc && (hubSrcGeog->_isEquivalentTo( geogDst, util::IComparable::Criterion::EQUIVALENT) || @@ -11816,6 +11816,35 @@ CoordinateOperationFactory::Private::createOperations( return res; } + if (hubSrcGeog && geogCRSOfBaseOfBoundSrc) { + // This one should go to the above 'Is it: boundCRS to a geogCRS + // that is the same as the hubCRS ?' case + auto opsFirst = createOperations(sourceCRS, hubSrc, context); + auto opsLast = createOperations(hubSrc, targetCRS, context); + if (!opsFirst.empty() && !opsLast.empty()) { + for (const auto &opFirst : opsFirst) { + for (const auto &opLast : opsLast) { + // Exclude artificial transformations from the hub + // to the target CRS + if (!opLast->hasBallparkTransformation()) { + try { + res.emplace_back( + ConcatenatedOperation:: + createComputeMetadata( + {opFirst, opLast}, + !allowEmptyIntersection)); + } catch ( + const InvalidOperationEmptyIntersection &) { + } + } + } + } + if (!res.empty()) { + return res; + } + } + } + return createOperations(boundSrc->baseCRS(), targetCRS, context); } -- cgit v1.2.3