aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-01-29 16:28:07 +0100
committerEven Rouault <even.rouault@spatialys.com>2020-01-29 16:28:07 +0100
commit6f6c53c8553541690a16775ab2c92f7703196e59 (patch)
tree329e634213191dc3d834f8254133a4222eeb61aa /src
parent9f6ab28f1d26561a547802a18b3a2f7877834ca8 (diff)
downloadPROJ-6f6c53c8553541690a16775ab2c92f7703196e59.tar.gz
PROJ-6f6c53c8553541690a16775ab2c92f7703196e59.zip
Add EPSG records for 'Geocentric translation by Grid Interpolation (IGN)' (gr3df97a.txt) and map them to new +proj=xyzgridshift
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/coordinateoperation.cpp129
-rw-r--r--src/proj_constants.h8
2 files changed, 137 insertions, 0 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index 8ca95223..53fa64bf 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -8471,6 +8471,33 @@ _getHorizontalShiftGTIFFFilename(const Transformation *op, bool allowInverse) {
//! @cond Doxygen_Suppress
static const std::string &
+_getGeocentricTranslationFilename(const Transformation *op, bool allowInverse) {
+
+ const auto &l_method = op->method();
+ const auto &methodName = l_method->nameStr();
+ if (l_method->getEPSGCode() ==
+ EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_BY_GRID_INTERPOLATION_IGN ||
+ (allowInverse &&
+ ci_equal(
+ methodName,
+ INVERSE_OF +
+ EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_BY_GRID_INTERPOLATION_IGN))) {
+ const auto &fileParameter =
+ op->parameterValue(EPSG_NAME_PARAMETER_GEOCENTRIC_TRANSLATION_FILE,
+ EPSG_CODE_PARAMETER_GEOCENTRIC_TRANSLATION_FILE);
+ if (fileParameter &&
+ fileParameter->type() == ParameterValue::Type::FILENAME) {
+ return fileParameter->valueFile();
+ }
+ }
+ return nullString;
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+static const std::string &
_getHeightToGeographic3DFilename(const Transformation *op, bool allowInverse) {
const auto &methodName = op->method()->nameStr();
@@ -8801,6 +8828,34 @@ TransformationNNPtr Transformation::substitutePROJAlternativeGridNames(
}
}
+ const auto &geocentricTranslationFilename =
+ _getGeocentricTranslationFilename(this, false);
+ if (!geocentricTranslationFilename.empty()) {
+ if (databaseContext->lookForGridAlternative(
+ geocentricTranslationFilename, projFilename, projGridFormat,
+ inverseDirection)) {
+
+ if (inverseDirection) {
+ throw util::UnsupportedOperationException(
+ "Inverse direction for "
+ "GeocentricTranslation not supported");
+ }
+
+ if (geocentricTranslationFilename == projFilename) {
+ return self;
+ }
+
+ auto parameters =
+ std::vector<OperationParameterNNPtr>{createOpParamNameEPSGCode(
+ EPSG_CODE_PARAMETER_GEOCENTRIC_TRANSLATION_FILE)};
+ return create(createSimilarPropertiesTransformation(self),
+ sourceCRS(), targetCRS(), interpolationCRS(),
+ createSimilarPropertiesMethod(method()), parameters,
+ {ParameterValue::createFilename(projFilename)},
+ coordinateOperationAccuracies());
+ }
+ }
+
if (methodEPSGCode == EPSG_CODE_METHOD_VERTCON ||
methodEPSGCode == EPSG_CODE_METHOD_VERTICALGRID_NZLVD ||
methodEPSGCode == EPSG_CODE_METHOD_VERTICALGRID_GTX) {
@@ -9423,6 +9478,80 @@ void Transformation::_exportToPROJString(
return;
}
+ const auto &geocentricTranslationFilename =
+ _getGeocentricTranslationFilename(this, true);
+ if (!geocentricTranslationFilename.empty()) {
+ auto sourceCRSGeog =
+ dynamic_cast<const crs::GeographicCRS *>(sourceCRS().get());
+ if (!sourceCRSGeog) {
+ throw io::FormattingException(
+ concat("Can apply ", methodName, " only to GeographicCRS"));
+ }
+
+ auto targetCRSGeog =
+ dynamic_cast<const crs::GeographicCRS *>(targetCRS().get());
+ if (!targetCRSGeog) {
+ throw io::FormattingException(
+ concat("Can apply ", methodName, " only to GeographicCRS"));
+ }
+
+ const auto &interpCRS = interpolationCRS();
+ if (!interpCRS) {
+ throw io::FormattingException(
+ "InterpolationCRS required "
+ "for"
+ " " EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_BY_GRID_INTERPOLATION_IGN);
+ }
+ const bool interpIsSrc = interpCRS->_isEquivalentTo(
+ sourceCRS().get(), util::IComparable::Criterion::EQUIVALENT);
+ const bool interpIsTarget = interpCRS->_isEquivalentTo(
+ targetCRS().get(), util::IComparable::Criterion::EQUIVALENT);
+ if (!interpIsSrc && !interpIsTarget) {
+ throw io::FormattingException(
+ "For"
+ " " EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_BY_GRID_INTERPOLATION_IGN
+ ", interpolation CRS should be the source or target CRS");
+ }
+
+ formatter->startInversion();
+ sourceCRSGeog->addAngularUnitConvertAndAxisSwap(formatter);
+ formatter->stopInversion();
+
+ if (isMethodInverseOf) {
+ formatter->startInversion();
+ }
+
+ formatter->addStep("push");
+ formatter->addParam("v_3");
+
+ formatter->addStep("cart");
+ sourceCRSGeog->ellipsoid()->_exportToPROJString(formatter);
+
+ formatter->addStep("xyzgridshift");
+ formatter->addParam("grids", geocentricTranslationFilename);
+ formatter->addParam("grid_ref",
+ interpIsTarget ? "output_crs" : "input_crs");
+ (interpIsTarget ? targetCRSGeog : sourceCRSGeog)
+ ->ellipsoid()
+ ->_exportToPROJString(formatter);
+
+ formatter->startInversion();
+ formatter->addStep("cart");
+ targetCRSGeog->ellipsoid()->_exportToPROJString(formatter);
+ formatter->stopInversion();
+
+ formatter->addStep("pop");
+ formatter->addParam("v_3");
+
+ if (isMethodInverseOf) {
+ formatter->stopInversion();
+ }
+
+ targetCRSGeog->addAngularUnitConvertAndAxisSwap(formatter);
+
+ return;
+ }
+
const auto &heightFilename = _getHeightToGeographic3DFilename(this, true);
if (!heightFilename.empty()) {
if (isMethodInverseOf) {
diff --git a/src/proj_constants.h b/src/proj_constants.h
index 54dc7873..91c7264c 100644
--- a/src/proj_constants.h
+++ b/src/proj_constants.h
@@ -501,6 +501,14 @@
"Geoid (height correction) model file"
#define EPSG_CODE_PARAMETER_GEOID_CORRECTION_FILENAME 8666
+#define EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_BY_GRID_INTERPOLATION_IGN \
+ "Geocentric translation by Grid Interpolation (IGN)"
+#define EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_BY_GRID_INTERPOLATION_IGN 1087
+
+#define EPSG_CODE_PARAMETER_GEOCENTRIC_TRANSLATION_FILE 8727
+#define EPSG_NAME_PARAMETER_GEOCENTRIC_TRANSLATION_FILE \
+ "Geocentric translation file"
+
/* ------------------------------------------------------------------------ */
#define PROJ_WKT2_NAME_METHOD_HEIGHT_TO_GEOG3D \