aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-03-28 17:33:26 +0100
committerEven Rouault <even.rouault@spatialys.com>2019-03-28 17:33:26 +0100
commit5893c7ddef817df0c42c7ee636e6e083b0c65aed (patch)
tree7806b1ff28f462a51436d56e2ca4a7a06e7a3467 /src
parentf4baf035dac9e8f1dd37d2121ffc3d1b3f440073 (diff)
downloadPROJ-5893c7ddef817df0c42c7ee636e6e083b0c65aed.tar.gz
PROJ-5893c7ddef817df0c42c7ee636e6e083b0c65aed.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/coordinateoperation.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index 1abb74b3..043d09bc 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -11689,7 +11689,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<const crs::BoundCRS *>(sourceCRS.get());
auto geogDst = dynamic_cast<const crs::GeographicCRS *>(targetCRS.get());
if (boundSrc && geogDst) {
@@ -11698,6 +11697,7 @@ CoordinateOperationFactory::Private::createOperations(
dynamic_cast<const crs::GeographicCRS *>(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) ||
@@ -11815,6 +11815,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);
}