diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-03-28 17:33:26 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-03-28 17:33:26 +0100 |
| commit | 5893c7ddef817df0c42c7ee636e6e083b0c65aed (patch) | |
| tree | 7806b1ff28f462a51436d56e2ca4a7a06e7a3467 /src | |
| parent | f4baf035dac9e8f1dd37d2121ffc3d1b3f440073 (diff) | |
| download | PROJ-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.cpp | 31 |
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); } |
