diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-05-19 13:15:40 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2020-05-19 14:21:02 +0200 |
| commit | 5aa99d497433377fc08cb569b6826473dc0c46d1 (patch) | |
| tree | 782bf900d35e2406f0e439e539478162c5c9e8fd /src | |
| parent | 8dc8e1de06dcb71da11facaaff6af9e46294deb0 (diff) | |
| download | PROJ-5aa99d497433377fc08cb569b6826473dc0c46d1.tar.gz PROJ-5aa99d497433377fc08cb569b6826473dc0c46d1.zip | |
createOperations(): take correctly into account vertical unit change in a case of transformation between Compound of BoundVerticalCRS to GeographicCRS (contributes to fixes #2232)
Diffstat (limited to 'src')
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 32a4b9c7..6dff57c1 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -14221,8 +14221,57 @@ void CoordinateOperationFactory::Private::createOperationsBoundToGeog( if (vertCRSOfBaseOfBoundSrc && hubSrcGeog) { auto opsFirst = createOperations(sourceCRS, hubSrc, context); if (context.skipHorizontalTransformation) { - if (!opsFirst.empty()) - res = opsFirst; + if (!opsFirst.empty()) { + const auto &hubAxisList = + hubSrcGeog->coordinateSystem()->axisList(); + const auto &targetAxisList = + geogDst->coordinateSystem()->axisList(); + if (hubAxisList.size() == 3 && hubAxisList.size() == 3 && + !hubAxisList[2]->_isEquivalentTo( + targetAxisList[2].get(), + util::IComparable::Criterion::EQUIVALENT)) { + + const auto &srcAxis = hubAxisList[2]; + const double convSrc = srcAxis->unit().conversionToSI(); + const auto &dstAxis = targetAxisList[2]; + const double convDst = dstAxis->unit().conversionToSI(); + const bool srcIsUp = + srcAxis->direction() == cs::AxisDirection::UP; + const bool srcIsDown = + srcAxis->direction() == cs::AxisDirection::DOWN; + const bool dstIsUp = + dstAxis->direction() == cs::AxisDirection::UP; + const bool dstIsDown = + dstAxis->direction() == cs::AxisDirection::DOWN; + const bool heightDepthReversal = + ((srcIsUp && dstIsDown) || (srcIsDown && dstIsUp)); + + const double factor = convSrc / convDst; + auto conv = Conversion::createChangeVerticalUnit( + util::PropertyMap().set( + common::IdentifiedObject::NAME_KEY, + "Change of vertical unit"), + common::Scale(heightDepthReversal ? -factor : factor)); + auto dbContext = context.context->getAuthorityFactory() + ->databaseContext(); + conv->setCRSs( + hubSrc, + hubSrc->demoteTo2D(std::string(), dbContext) + ->promoteTo3D(std::string(), dbContext, dstAxis), + nullptr); + + for (const auto &op : opsFirst) { + try { + res.emplace_back( + ConcatenatedOperation::createComputeMetadata( + {op, conv}, !allowEmptyIntersection)); + } catch (const InvalidOperationEmptyIntersection &) { + } + } + } else { + res = opsFirst; + } + } return; } else { auto opsSecond = createOperations(hubSrc, targetCRS, context); |
