diff options
| author | Kristian Evers <kristianevers@gmail.com> | 2020-01-30 11:08:49 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-30 11:08:49 +0100 |
| commit | 91c40b654bb2b07ae79367a683e45c86d29ba0a4 (patch) | |
| tree | 69a55fe57d65fdd604b9c03aab0b9003489a5e3c /src | |
| parent | 3ab34eb940302bb564968309a3dfc4c3050e9c3e (diff) | |
| parent | 6f6c53c8553541690a16775ab2c92f7703196e59 (diff) | |
| download | PROJ-91c40b654bb2b07ae79367a683e45c86d29ba0a4.tar.gz PROJ-91c40b654bb2b07ae79367a683e45c86d29ba0a4.zip | |
Merge pull request #1897 from rouault/map_geocentric_translation_method
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.cpp | 129 | ||||
| -rw-r--r-- | src/proj_constants.h | 8 |
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 \ |
