diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-02-29 13:24:58 +0100 |
|---|---|---|
| committer | Kristian Evers <kristianevers@gmail.com> | 2020-03-01 11:51:08 +0100 |
| commit | 641df65880087ae40b4aef94cc5c104f016b6bdc (patch) | |
| tree | e37e0fd332eaadeab64b41b698944577276db209 /src/iso19111/coordinateoperation.cpp | |
| parent | e8c150186fec758cc44d90b8efeb756534ae9338 (diff) | |
| download | PROJ-641df65880087ae40b4aef94cc5c104f016b6bdc.tar.gz PROJ-641df65880087ae40b4aef94cc5c104f016b6bdc.zip | |
createOperations(): fix wrong pipeline generation with CRS that has +nadgrids= and +pm= (#1998)
Fixes issue reported at
https://lists.osgeo.org/pipermail/gdal-dev/2020-February/051749.html
The generated pipeline assumes that the input coordinates for the grid transformation
were related to the non-Greenwich based datum, so we must compensate for that and
add logic to go back to Greenwich.
Diffstat (limited to 'src/iso19111/coordinateoperation.cpp')
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index c97763e4..af117cc4 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -13848,12 +13848,27 @@ void CoordinateOperationFactory::Private::createOperationsBoundToGeog( auto opsFirst = createOperations( boundSrc->baseCRS(), NN_NO_CHECK(geogCRSOfBaseOfBoundSrc), context); if (!opsFirst.empty()) { + CoordinateOperationPtr opIntermediate; + if (!geogCRSOfBaseOfBoundSrc->_isEquivalentTo( + boundSrc->transformation()->sourceCRS().get(), + util::IComparable::Criterion::EQUIVALENT)) { + auto opsIntermediate = createOperations( + NN_NO_CHECK(geogCRSOfBaseOfBoundSrc), + boundSrc->transformation()->sourceCRS(), context); + assert(!opsIntermediate.empty()); + opIntermediate = opsIntermediate.front(); + } for (const auto &opFirst : opsFirst) { try { + std::vector<CoordinateOperationNNPtr> subops; + subops.emplace_back(opFirst); + if (opIntermediate) { + subops.emplace_back(NN_NO_CHECK(opIntermediate)); + } + subops.emplace_back(boundSrc->transformation()); res.emplace_back( ConcatenatedOperation::createComputeMetadata( - {opFirst, boundSrc->transformation()}, - !allowEmptyIntersection)); + subops, !allowEmptyIntersection)); } catch (const InvalidOperationEmptyIntersection &) { } } @@ -13871,13 +13886,29 @@ void CoordinateOperationFactory::Private::createOperationsBoundToGeog( boundSrc->baseCRS(), NN_NO_CHECK(geogCRSOfBaseOfBoundSrc), context); auto opsLast = createOperations(hubSrc, targetCRS, context); if (!opsFirst.empty() && !opsLast.empty()) { + CoordinateOperationPtr opIntermediate; + if (!geogCRSOfBaseOfBoundSrc->_isEquivalentTo( + boundSrc->transformation()->sourceCRS().get(), + util::IComparable::Criterion::EQUIVALENT)) { + auto opsIntermediate = createOperations( + NN_NO_CHECK(geogCRSOfBaseOfBoundSrc), + boundSrc->transformation()->sourceCRS(), context); + assert(!opsIntermediate.empty()); + opIntermediate = opsIntermediate.front(); + } for (const auto &opFirst : opsFirst) { for (const auto &opLast : opsLast) { try { + std::vector<CoordinateOperationNNPtr> subops; + subops.emplace_back(opFirst); + if (opIntermediate) { + subops.emplace_back(NN_NO_CHECK(opIntermediate)); + } + subops.emplace_back(boundSrc->transformation()); + subops.emplace_back(opLast); res.emplace_back( ConcatenatedOperation::createComputeMetadata( - {opFirst, boundSrc->transformation(), opLast}, - !allowEmptyIntersection)); + subops, !allowEmptyIntersection)); } catch (const InvalidOperationEmptyIntersection &) { } } |
