aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-03-28 16:33:26 +0000
committerEven Rouault <even.rouault@spatialys.com>2019-03-28 16:33:26 +0000
commit45ce4a8c780c4408c4dbe58f8dce0713086ea50b (patch)
treeeade55bee10bf4cccb3b246c6e654599932597fb /src
parenta42cfd4d82ef8010bebbf3fa591c538620bc1e49 (diff)
downloadPROJ-45ce4a8c780c4408c4dbe58f8dce0713086ea50b.tar.gz
PROJ-45ce4a8c780c4408c4dbe58f8dce0713086ea50b.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 50a6a003..957d47cd 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -11690,7 +11690,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) {
@@ -11699,6 +11698,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) ||
@@ -11816,6 +11816,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);
}