aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/io.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-02-29 13:24:58 +0100
committerKristian Evers <kristianevers@gmail.com>2020-03-01 11:51:21 +0100
commitb0d27b2cc33c8ffde5cac7ec69947d74dc8408c5 (patch)
tree1b2977a45f8d164fe236300ebf4e9a73da7212f9 /src/iso19111/io.cpp
parentdf73b75b3dc4c6517558abc41eb9f511414a4e45 (diff)
downloadPROJ-b0d27b2cc33c8ffde5cac7ec69947d74dc8408c5.tar.gz
PROJ-b0d27b2cc33c8ffde5cac7ec69947d74dc8408c5.zip
createOperations(): fix wrong pipeline generation with CRS that has +nadgrids= and +pm= (#1998)
Fixes issue reported at https://lists.osgeo.org/pipermail/gdal-dev/2020-February/051749.html The generated pipeline assumes that the input coordinates for the grid transformation were related to the non-Greenwich based datum, so we must compensate for that and add logic to go back to Greenwich.
Diffstat (limited to 'src/iso19111/io.cpp')
-rw-r--r--src/iso19111/io.cpp86
1 files changed, 53 insertions, 33 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 9d463091..d5d0d1c0 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -4057,6 +4057,52 @@ WKTParser::Private::buildCompoundCRS(const WKTNodeNNPtr &node) {
// ---------------------------------------------------------------------------
+static CRSNNPtr
+createBoundCRSSourceTransformationCRS(const crs::CRSPtr &sourceCRS,
+ const crs::CRSPtr &targetCRS) {
+ CRSPtr sourceTransformationCRS;
+ if (dynamic_cast<GeographicCRS *>(targetCRS.get())) {
+ GeographicCRSPtr sourceGeographicCRS =
+ sourceCRS->extractGeographicCRS();
+ sourceTransformationCRS = sourceGeographicCRS;
+ if (sourceGeographicCRS) {
+ if (sourceGeographicCRS->datum() != nullptr &&
+ sourceGeographicCRS->primeMeridian()
+ ->longitude()
+ .getSIValue() != 0.0) {
+ sourceTransformationCRS =
+ GeographicCRS::create(
+ util::PropertyMap().set(
+ common::IdentifiedObject::NAME_KEY,
+ sourceGeographicCRS->nameStr() +
+ " (with Greenwich prime meridian)"),
+ datum::GeodeticReferenceFrame::create(
+ util::PropertyMap().set(
+ common::IdentifiedObject::NAME_KEY,
+ sourceGeographicCRS->datum()->nameStr() +
+ " (with Greenwich prime meridian)"),
+ sourceGeographicCRS->datum()->ellipsoid(),
+ util::optional<std::string>(),
+ datum::PrimeMeridian::GREENWICH),
+ sourceGeographicCRS->coordinateSystem())
+ .as_nullable();
+ }
+ } else {
+ sourceTransformationCRS =
+ std::dynamic_pointer_cast<VerticalCRS>(sourceCRS);
+ if (!sourceTransformationCRS) {
+ throw ParsingException(
+ "Cannot find GeographicCRS or VerticalCRS in sourceCRS");
+ }
+ }
+ } else {
+ sourceTransformationCRS = sourceCRS;
+ }
+ return NN_NO_CHECK(sourceTransformationCRS);
+}
+
+// ---------------------------------------------------------------------------
+
BoundCRSNNPtr WKTParser::Private::buildBoundCRS(const WKTNodeNNPtr &node) {
const auto *nodeP = node->GP();
auto &abridgedNode =
@@ -4100,23 +4146,10 @@ BoundCRSNNPtr WKTParser::Private::buildBoundCRS(const WKTNodeNNPtr &node) {
consumeParameters(abridgedNode, true, parameters, values, defaultLinearUnit,
defaultAngularUnit);
- CRSPtr sourceTransformationCRS;
- if (dynamic_cast<GeographicCRS *>(targetCRS.get())) {
- sourceTransformationCRS = sourceCRS->extractGeographicCRS();
- if (!sourceTransformationCRS) {
- sourceTransformationCRS =
- std::dynamic_pointer_cast<VerticalCRS>(sourceCRS);
- if (!sourceTransformationCRS) {
- throw ParsingException(
- "Cannot find GeographicCRS or VerticalCRS in sourceCRS");
- }
- }
- } else {
- sourceTransformationCRS = sourceCRS;
- }
-
+ const auto sourceTransformationCRS(
+ createBoundCRSSourceTransformationCRS(sourceCRS, targetCRS));
auto transformation = Transformation::create(
- buildProperties(abridgedNode), NN_NO_CHECK(sourceTransformationCRS),
+ buildProperties(abridgedNode), sourceTransformationCRS,
NN_NO_CHECK(targetCRS), nullptr, buildProperties(methodNode),
parameters, values, std::vector<PositionalAccuracyNNPtr>());
@@ -5262,24 +5295,11 @@ BoundCRSNNPtr JSONParser::buildBoundCRS(const json &j) {
values.emplace_back(ParameterValue::create(getMeasure(param)));
}
- CRSPtr sourceTransformationCRS;
- if (dynamic_cast<GeographicCRS *>(targetCRS.get())) {
- sourceTransformationCRS = sourceCRS->extractGeographicCRS();
- if (!sourceTransformationCRS) {
- sourceTransformationCRS =
- std::dynamic_pointer_cast<VerticalCRS>(sourceCRS.as_nullable());
- if (!sourceTransformationCRS) {
- throw ParsingException(
- "Cannot find GeographicCRS or VerticalCRS in sourceCRS");
- }
- }
- } else {
- sourceTransformationCRS = sourceCRS;
- }
-
+ const auto sourceTransformationCRS(
+ createBoundCRSSourceTransformationCRS(sourceCRS, targetCRS));
auto transformation = Transformation::create(
- buildProperties(transformationJ), NN_NO_CHECK(sourceTransformationCRS),
- targetCRS, nullptr, buildProperties(methodJ), parameters, values,
+ buildProperties(transformationJ), sourceTransformationCRS, targetCRS,
+ nullptr, buildProperties(methodJ), parameters, values,
std::vector<PositionalAccuracyNNPtr>());
return BoundCRS::create(sourceCRS, targetCRS, transformation);