diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2022-03-16 12:24:22 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2022-03-16 12:24:25 +0100 |
| commit | 3e7984f3b26e408e69b960f8e0d03b6ac0576188 (patch) | |
| tree | e8b57c5cd870103c5514438eeb388be0ca958410 /src/iso19111 | |
| parent | 77751f6c9e023748a90793774e8e4b554515e8b5 (diff) | |
| download | PROJ-3e7984f3b26e408e69b960f8e0d03b6ac0576188.tar.gz PROJ-3e7984f3b26e408e69b960f8e0d03b6ac0576188.zip | |
Transformation: no longer do vertical trasnformation when doing compound CRS to 2D CRS / add --3d to cs2cs
Previously, when computing transformation between a compound CRS and a
geographic/projected 2D CRS, the behaviour was similar to implicitly
promoting the 2D CRS to 3D CRS in the pipeline computation logic, hence
a geoid model could be applied. But note that when doing a geographic 3D
to geographic/projected 2D CRS transformation, we *did* not do this implicit
promotion and if a Helmert transformation existed between the datums, it
was done only in 2D. So this is a bit inconsistent and triggered the
comment in https://github.com/OSGeo/PROJ/issues/2318#issuecomment-1068924513
With this commit, we no longer do any vertical transformation when doing
compound CRS to the 2D CRS, but just take the transformation of the
horizontal part of the compound CRS to the 2D CRS.
Said otherwise, NAD83+NAVD88 to NAD83 will no longer lead to the
application of the geoid model. Unless you explicitly ask for the
promotion NAD83 to 3D.
Also related, in https://github.com/OSGeo/PROJ/issues/1563 that went to 6.3.0,
I changed cs2cs to automatically promote to 3D the CRS as soon as one of
them was compound, for the sake of being consistent with the past
behaviour. But it then becomes difficult to predict PROJ behaviour
depending on which level of it you consider...
This commit undoes that and adds an explicit --3d switch to cs2cs, similarly to
projinfo, to ask for promotion.
Other bug fix found in the process, when using legacy syntax, +init=epsg:4979,
(WGS 84 3D), the resulting CRS was 2D and not 3D.
Diffstat (limited to 'src/iso19111')
| -rw-r--r-- | src/iso19111/io.cpp | 10 | ||||
| -rw-r--r-- | src/iso19111/operation/coordinateoperationfactory.cpp | 13 |
2 files changed, 21 insertions, 2 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index d4c6aec1..e09aee93 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -10525,12 +10525,18 @@ PROJStringParser::createFromPROJString(const std::string &projString) { } auto geogCRS = dynamic_cast<GeographicCRS *>(crs); if (geogCRS) { + const auto &cs = geogCRS->coordinateSystem(); // Override with longitude latitude in degrees return GeographicCRS::create( properties, geogCRS->datum(), geogCRS->datumEnsemble(), - EllipsoidalCS::createLongitudeLatitude( - UnitOfMeasure::DEGREE)); + cs->axisList().size() == 2 + ? EllipsoidalCS::createLongitudeLatitude( + UnitOfMeasure::DEGREE) + : EllipsoidalCS:: + createLongitudeLatitudeEllipsoidalHeight( + UnitOfMeasure::DEGREE, + cs->axisList()[2]->unit())); } auto projCRS = dynamic_cast<ProjectedCRS *>(crs); if (projCRS) { diff --git a/src/iso19111/operation/coordinateoperationfactory.cpp b/src/iso19111/operation/coordinateoperationfactory.cpp index 20042f22..a6a2c986 100644 --- a/src/iso19111/operation/coordinateoperationfactory.cpp +++ b/src/iso19111/operation/coordinateoperationfactory.cpp @@ -4926,6 +4926,19 @@ void CoordinateOperationFactory::Private::createOperationsCompoundToGeog( } } + // Only do a vertical transformation if the target CRS is 3D. + const auto dstSingle = dynamic_cast<crs::SingleCRS *>(targetCRS.get()); + if (dstSingle && + dstSingle->coordinateSystem()->axisList().size() == 2) { + auto tmp = createOperations(componentsSrc[0], targetCRS, context); + for (const auto &op : tmp) { + auto opClone = op->shallowClone(); + setCRSs(opClone.get(), sourceCRS, targetCRS); + res.emplace_back(opClone); + } + return; + } + std::vector<CoordinateOperationNNPtr> horizTransforms; auto srcGeogCRS = componentsSrc[0]->extractGeographicCRS(); if (srcGeogCRS) { |
