aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/coordinateoperation.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-02-29 13:24:58 +0100
committerKristian Evers <kristianevers@gmail.com>2020-03-01 11:51:08 +0100
commit641df65880087ae40b4aef94cc5c104f016b6bdc (patch)
treee37e0fd332eaadeab64b41b698944577276db209 /src/iso19111/coordinateoperation.cpp
parente8c150186fec758cc44d90b8efeb756534ae9338 (diff)
downloadPROJ-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.cpp39
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 &) {
}
}