diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-03-28 16:33:26 +0000 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-03-28 16:33:26 +0000 |
| commit | 45ce4a8c780c4408c4dbe58f8dce0713086ea50b (patch) | |
| tree | eade55bee10bf4cccb3b246c6e654599932597fb /src | |
| parent | a42cfd4d82ef8010bebbf3fa591c538620bc1e49 (diff) | |
| download | PROJ-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.cpp | 31 |
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); } |
