diff options
Diffstat (limited to 'src/iso19111/operation/conversion.cpp')
| -rw-r--r-- | src/iso19111/operation/conversion.cpp | 66 |
1 files changed, 61 insertions, 5 deletions
diff --git a/src/iso19111/operation/conversion.cpp b/src/iso19111/operation/conversion.cpp index e9d688b7..e2e77562 100644 --- a/src/iso19111/operation/conversion.cpp +++ b/src/iso19111/operation/conversion.cpp @@ -2252,6 +2252,26 @@ Conversion::createChangeVerticalUnit(const util::PropertyMap &properties, // --------------------------------------------------------------------------- +/** \brief Instantiate a conversion based on the Change of Vertical Unit + * method (without explicit conversion factor) + * + * This method is defined as [EPSG:1104] + * (https://www.epsg-registry.org/export.htm?gml=urn:ogc:def:method:EPSG::1104) + * + * @param properties See \ref general_properties of the conversion. If the name + * is not provided, it is automatically set. + * @return a new Conversion. + */ +ConversionNNPtr +Conversion::createChangeVerticalUnit(const util::PropertyMap &properties) { + return create(properties, + createMethodMapNameEPSGCode( + EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT_NO_CONV_FACTOR), + VectorOfParameters{}, VectorOfValues{}); +} + +// --------------------------------------------------------------------------- + /** \brief Instantiate a conversion based on the Height Depth Reversal * method. * @@ -2409,6 +2429,14 @@ CoordinateOperationNNPtr Conversion::inverse() const { return conv; } + if (methodEPSGCode == + EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT_NO_CONV_FACTOR) { + auto conv = createChangeVerticalUnit( + createPropertiesForInverse(this, false, false)); + conv->setCRSs(this, true); + return conv; + } + const bool l_isAxisOrderReversal2D = isAxisOrderReversal2D(methodEPSGCode); const bool l_isAxisOrderReversal3D = isAxisOrderReversal3D(methodEPSGCode); if (l_isAxisOrderReversal2D || l_isAxisOrderReversal3D) { @@ -3345,7 +3373,8 @@ void Conversion::_exportToPROJString( const auto &methodName = l_method->nameStr(); const int methodEPSGCode = l_method->getEPSGCode(); const bool isZUnitConversion = - methodEPSGCode == EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT; + methodEPSGCode == EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT || + methodEPSGCode == EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT_NO_CONV_FACTOR; const bool isAffineParametric = methodEPSGCode == EPSG_CODE_METHOD_AFFINE_PARAMETRIC_TRANSFORMATION; const bool isGeographicGeocentric = @@ -3368,6 +3397,8 @@ void Conversion::_exportToPROJString( } auto l_sourceCRS = sourceCRS(); + auto l_targetCRS = targetCRS(); + crs::GeographicCRSPtr srcGeogCRS; if (!formatter->getCRSExport() && l_sourceCRS && applySourceCRSModifiers) { @@ -3633,8 +3664,35 @@ void Conversion::_exportToPROJString( } else if (formatter->convention() == io::PROJStringFormatter::Convention::PROJ_5 && isZUnitConversion) { - double convFactor = parameterValueNumericAsSI( - EPSG_CODE_PARAMETER_UNIT_CONVERSION_SCALAR); + double convFactor; + if (methodEPSGCode == EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT) { + convFactor = parameterValueNumericAsSI( + EPSG_CODE_PARAMETER_UNIT_CONVERSION_SCALAR); + } else { + assert(methodEPSGCode == + EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT_NO_CONV_FACTOR); + const auto vertSrcCRS = + dynamic_cast<const crs::VerticalCRS *>(l_sourceCRS.get()); + const auto vertTgtCRS = + dynamic_cast<const crs::VerticalCRS *>(l_targetCRS.get()); + if (vertSrcCRS && vertTgtCRS) { + const double convSrc = vertSrcCRS->coordinateSystem() + ->axisList()[0] + ->unit() + .conversionToSI(); + const double convDst = vertTgtCRS->coordinateSystem() + ->axisList()[0] + ->unit() + .conversionToSI(); + convFactor = convSrc / convDst; + } else { + throw io::FormattingException( + "Export of " + "EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT_NO_CONV_FACTOR " + "conversion to a PROJ string " + "requires an input and output vertical CRS"); + } + } auto uom = common::UnitOfMeasure(std::string(), convFactor, common::UnitOfMeasure::Type::LINEAR) .exportToPROJString(); @@ -3686,8 +3744,6 @@ void Conversion::_exportToPROJString( bConversionDone = true; } - auto l_targetCRS = targetCRS(); - bool bAxisSpecFound = false; if (!bConversionDone) { const MethodMapping *mapping = getMapping(l_method.get()); |
