aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/operation/conversion.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-04-22 22:51:31 +0200
committerEven Rouault <even.rouault@spatialys.com>2021-04-23 01:07:04 +0200
commitf6abb7d75c647013dd83a82361b96c202e615d90 (patch)
tree6743cf5b5feab06004e85ff55f654cd1671a6dc9 /src/iso19111/operation/conversion.cpp
parentc6dba3fffb80fe6394f51aae0762f7e5db6d9edf (diff)
downloadPROJ-f6abb7d75c647013dd83a82361b96c202e615d90.tar.gz
PROJ-f6abb7d75c647013dd83a82361b96c202e615d90.zip
Database: update to EPSG v10.019
Non-trivial updates: - some vertical CRS are now encoded as DerivedVerticalCRS. e.g EPSG:8228 "NAVD88 height (ft)", with base EPSG:5703 "NAVD88 height". As we don't have support in our PROJ db model for DerivedVerticalCRS, modify the import script to 'resolve' the derivation up to the original datum. - Method EPSG:1069 'Change of Vertical Unit' is no longer used. It is replaced by a generic-purpose EPSG:1104 method that doesn't take any conversion factor. And generic conversions EPSG:7812 and EPSG:7813 are now used in concatenated operations, which require code changes as well.
Diffstat (limited to 'src/iso19111/operation/conversion.cpp')
-rw-r--r--src/iso19111/operation/conversion.cpp66
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());