diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2021-08-20 18:31:00 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-20 18:31:00 +0200 |
| commit | 6ee8c26b60e99e347dad8b7d6fb33b5316973f9d (patch) | |
| tree | 53c200362db2f11f599b958b235b074805d19675 /src | |
| parent | 4766b7c3a17dc98f99c59d2b64076fd924df5804 (diff) | |
| parent | fa3163365869b15e14715378a826338e942bbfe4 (diff) | |
| download | PROJ-6ee8c26b60e99e347dad8b7d6fb33b5316973f9d.tar.gz PROJ-6ee8c26b60e99e347dad8b7d6fb33b5316973f9d.zip | |
Merge pull request #2818 from rouault/fix_2817
ConcatenatedOperation::fixStepsDirection(): fix bad chaining of steps…
Diffstat (limited to 'src')
| -rw-r--r-- | src/iso19111/io.cpp | 2 | ||||
| -rw-r--r-- | src/iso19111/operation/concatenatedoperation.cpp | 26 |
2 files changed, 24 insertions, 4 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 867e08ed..c11fc5dc 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -7425,6 +7425,8 @@ const std::string &PROJStringFormatter::toString() const { } else if (step.name == "pop" && step.inverted) { step.name = "push"; step.inverted = false; + } else if (step.name == "noop" && d->steps_.size() > 1) { + iter = d->steps_.erase(iter); } else { ++iter; } diff --git a/src/iso19111/operation/concatenatedoperation.cpp b/src/iso19111/operation/concatenatedoperation.cpp index 20bbce6f..185ebb4a 100644 --- a/src/iso19111/operation/concatenatedoperation.cpp +++ b/src/iso19111/operation/concatenatedoperation.cpp @@ -335,13 +335,26 @@ void ConcatenatedOperation::fixStepsDirection( } } } else if (conv && i > 0 && i < operationsInOut.size() - 1) { - // For an intermediate conversion, use the target CRS of the - // previous step and the source CRS of the next step + l_sourceCRS = operationsInOut[i - 1]->targetCRS(); l_targetCRS = operationsInOut[i + 1]->sourceCRS(); + // For an intermediate conversion, use the target CRS of the + // previous step and the source CRS of the next step if (l_sourceCRS && l_targetCRS) { - op->setCRSs(NN_NO_CHECK(l_sourceCRS), NN_NO_CHECK(l_targetCRS), - nullptr); + // If the sourceCRS is a projectedCRS and the target a + // geographic one, then we must inverse the operation. See + // https://github.com/OSGeo/PROJ/issues/2817 + if (dynamic_cast<const crs::ProjectedCRS *>( + l_sourceCRS.get()) && + dynamic_cast<const crs::GeographicCRS *>( + l_targetCRS.get())) { + op->setCRSs(NN_NO_CHECK(l_targetCRS), + NN_NO_CHECK(l_sourceCRS), nullptr); + op = op->inverse(); + } else { + op->setCRSs(NN_NO_CHECK(l_sourceCRS), + NN_NO_CHECK(l_targetCRS), nullptr); + } } else if (l_sourceCRS && l_targetCRS == nullptr && conv->method()->getEPSGCode() == EPSG_CODE_METHOD_HEIGHT_DEPTH_REVERSAL) { @@ -380,6 +393,11 @@ void ConcatenatedOperation::fixStepsDirection( // whereas we should instead use the reverse path. auto prevOpTarget = (i == 0) ? concatOpSourceCRS.as_nullable() : operationsInOut[i - 1]->targetCRS(); + if (prevOpTarget == nullptr) { + throw InvalidOperation( + "Cannot determine targetCRS of operation at step " + + toString(static_cast<int>(i))); + } if (compareStepCRS(l_sourceCRS.get(), prevOpTarget.get())) { // do nothing } else if (compareStepCRS(l_targetCRS.get(), prevOpTarget.get())) { |
