aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/coordinateoperation.cpp54
-rw-r--r--src/iso19111/io.cpp20
2 files changed, 74 insertions, 0 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index bdb2ad2e..c64dab5f 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -8662,6 +8662,7 @@ isGeographic3DToGravityRelatedHeight(const OperationMethodNNPtr &method,
"9663", // Geographic3D to GravityRelatedHeight (OSGM-GB)
"9664", // Geographic3D to GravityRelatedHeight (IGN1997)
"9665", // Geographic3D to GravityRelatedHeight (US .gtx)
+ "9635", // Geog3D to Geog2D+GravityRelatedHeight (US .gtx)
};
if (ci_find(methodName, "Geographic3D to GravityRelatedHeight") == 0) {
@@ -9697,6 +9698,21 @@ void Transformation::_exportToPROJString(
const auto &heightFilename = _getHeightToGeographic3DFilename(this, true);
if (!heightFilename.empty()) {
+ auto targetCRSGeog =
+ extractGeographicCRSIfGeographicCRSOrEquivalent(targetCRS());
+ if (!targetCRSGeog) {
+ throw io::FormattingException(
+ concat("Can apply ", methodName, " only to GeographicCRS"));
+ }
+
+ if (!formatter->omitHorizontalConversionInVertTransformation()) {
+ formatter->startInversion();
+ formatter->pushOmitZUnitConversion();
+ targetCRSGeog->addAngularUnitConvertAndAxisSwap(formatter);
+ formatter->popOmitZUnitConversion();
+ formatter->stopInversion();
+ }
+
if (isMethodInverseOf) {
formatter->startInversion();
}
@@ -9706,6 +9722,13 @@ void Transformation::_exportToPROJString(
if (isMethodInverseOf) {
formatter->stopInversion();
}
+
+ if (!formatter->omitHorizontalConversionInVertTransformation()) {
+ formatter->pushOmitZUnitConversion();
+ targetCRSGeog->addAngularUnitConvertAndAxisSwap(formatter);
+ formatter->popOmitZUnitConversion();
+ }
+
return;
}
@@ -9716,6 +9739,22 @@ void Transformation::_exportToPROJString(
if (fileParameter &&
fileParameter->type() == ParameterValue::Type::FILENAME) {
auto filename = fileParameter->valueFile();
+
+ auto sourceCRSGeog =
+ extractGeographicCRSIfGeographicCRSOrEquivalent(sourceCRS());
+ if (!sourceCRSGeog) {
+ throw io::FormattingException(
+ concat("Can apply ", methodName, " only to GeographicCRS"));
+ }
+
+ if (!formatter->omitHorizontalConversionInVertTransformation()) {
+ formatter->startInversion();
+ formatter->pushOmitZUnitConversion();
+ sourceCRSGeog->addAngularUnitConvertAndAxisSwap(formatter);
+ formatter->popOmitZUnitConversion();
+ formatter->stopInversion();
+ }
+
bool doInversion = isMethodInverseOf;
// The EPSG Geog3DToHeight is the reverse convention of PROJ !
doInversion = !doInversion;
@@ -9728,6 +9767,13 @@ void Transformation::_exportToPROJString(
if (doInversion) {
formatter->stopInversion();
}
+
+ if (!formatter->omitHorizontalConversionInVertTransformation()) {
+ formatter->pushOmitZUnitConversion();
+ sourceCRSGeog->addAngularUnitConvertAndAxisSwap(formatter);
+ formatter->popOmitZUnitConversion();
+ }
+
return;
}
}
@@ -12286,6 +12332,8 @@ createBallparkGeographicOffset(const crs::CRSNNPtr &sourceCRS,
//! @cond Doxygen_Suppress
+// ---------------------------------------------------------------------------
+
struct MyPROJStringExportableGeodToGeod final
: public io::IPROJStringExportable {
crs::GeodeticCRSPtr geodSrc{};
@@ -12332,14 +12380,18 @@ struct MyPROJStringExportableHorizVertical final
_exportToPROJString(io::PROJStringFormatter *formatter) const override {
formatter->pushOmitZUnitConversion();
+
horizTransform->_exportToPROJString(formatter);
formatter->startInversion();
geogDst->addAngularUnitConvertAndAxisSwap(formatter);
formatter->stopInversion();
+
formatter->popOmitZUnitConversion();
+ formatter->pushOmitHorizontalConversionInVertTransformation();
verticalTransform->_exportToPROJString(formatter);
+ formatter->popOmitHorizontalConversionInVertTransformation();
formatter->pushOmitZUnitConversion();
geogDst->addAngularUnitConvertAndAxisSwap(formatter);
@@ -12385,7 +12437,9 @@ struct MyPROJStringExportableHorizVerticalHorizPROJBased final
formatter->popOmitZUnitConversion();
+ formatter->pushOmitHorizontalConversionInVertTransformation();
verticalTransform->_exportToPROJString(formatter);
+ formatter->popOmitHorizontalConversionInVertTransformation();
formatter->pushOmitZUnitConversion();
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index e7f8769c..38b407ee 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -6635,6 +6635,7 @@ struct PROJStringFormatter::Private {
std::vector<InversionStackElt> inversionStack_{InversionStackElt()};
bool omitProjLongLatIfPossible_ = false;
std::vector<bool> omitZUnitConversion_{false};
+ std::vector<bool> omitHorizontalConversionInVertTransformation_{false};
DatabaseContextPtr dbContext_{};
bool useApproxTMerc_ = false;
bool addNoDefs_ = true;
@@ -7739,6 +7740,25 @@ bool PROJStringFormatter::omitZUnitConversion() const {
// ---------------------------------------------------------------------------
+void PROJStringFormatter::pushOmitHorizontalConversionInVertTransformation() {
+ d->omitHorizontalConversionInVertTransformation_.push_back(true);
+}
+
+// ---------------------------------------------------------------------------
+
+void PROJStringFormatter::popOmitHorizontalConversionInVertTransformation() {
+ assert(d->omitHorizontalConversionInVertTransformation_.size() > 1);
+ d->omitHorizontalConversionInVertTransformation_.pop_back();
+}
+
+// ---------------------------------------------------------------------------
+
+bool PROJStringFormatter::omitHorizontalConversionInVertTransformation() const {
+ return d->omitHorizontalConversionInVertTransformation_.back();
+}
+
+// ---------------------------------------------------------------------------
+
void PROJStringFormatter::setLegacyCRSToCRSContext(bool legacyContext) {
d->legacyCRSToCRSContext_ = legacyContext;
}