aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-06-06 20:35:00 +0200
committerEven Rouault <even.rouault@spatialys.com>2020-06-06 22:24:13 +0200
commita96e8f5f4e2a2145656c533271d1461ea077a35d (patch)
tree9993c3df25f84090872931319ea76b7815850c48 /src/iso19111
parent325d8e157dc4e5132b843c1a799897a92f096044 (diff)
downloadPROJ-a96e8f5f4e2a2145656c533271d1461ea077a35d.tar.gz
PROJ-a96e8f5f4e2a2145656c533271d1461ea077a35d.zip
createOperations(): changes so that EPSG:9635 'Geog3D to Geog2D+GravityRelatedHeight (US .gtx)' method used by Slovakian geoids correctly deal with axis order and unit conversion, to be used as 'standalone'. Also improves when using directly 'Geographic3D to GravityRelatedHeight' method
Diffstat (limited to 'src/iso19111')
-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;
}