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
committerGitHub <noreply@github.com>2020-02-29 13:24:58 +0100
commit10a8d5c98499127e5aa61d6cdeee466fcabb12ed (patch)
tree241ad35a9c6866c565d096fc9b0357747a347ec7 /src/iso19111/coordinateoperation.cpp
parent1f3a571d32fb311a7bd4528b04071dbf332498c4 (diff)
downloadPROJ-10a8d5c98499127e5aa61d6cdeee466fcabb12ed.tar.gz
PROJ-10a8d5c98499127e5aa61d6cdeee466fcabb12ed.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 16325423..63b11761 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -13850,12 +13850,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 &) {
}
}
@@ -13873,13 +13888,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 &) {
}
}