aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/source/apps/projinfo.rst9
-rw-r--r--src/apps/projinfo.cpp40
-rw-r--r--src/iso19111/c_api.cpp5
-rw-r--r--src/iso19111/coordinateoperation.cpp7
-rwxr-xr-xtest/cli/testprojinfo6
-rw-r--r--test/cli/testprojinfo_out.dist51
6 files changed, 72 insertions, 46 deletions
diff --git a/docs/source/apps/projinfo.rst b/docs/source/apps/projinfo.rst
index 8fbf0546..f6bf9ab0 100644
--- a/docs/source/apps/projinfo.rst
+++ b/docs/source/apps/projinfo.rst
@@ -224,9 +224,12 @@ The following control parameters can appear in any order:
.. versionadded:: 7.0
- "Promote" the CRS(s) to their 3D version. Useful for example when wanting
- to transform between a 2D projected CRS with elevations as ellipsoidal
- height to a 3D geographic CRS or a compoundCRS.
+ "Promote" the CRS(s) to their 3D version. In the context of researching
+ available coordinate transformations, explicitly specifying this option is
+ not necessary, because when one of the source or target CRS has a vertical
+ component but not the other one, the one that has no vertical component is
+ automatically promoted to a 3D version, where its vertical axis is the
+ ellipsoidal height in metres, using the ellipsoid of the base geodetic CRS.
.. option:: --c-ify
diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp
index 1760ae29..fd9b2f46 100644
--- a/src/apps/projinfo.cpp
+++ b/src/apps/projinfo.cpp
@@ -601,37 +601,6 @@ static void outputOperationSummary(const CoordinateOperationNNPtr &op,
// ---------------------------------------------------------------------------
-static size_t getAxisCount(const CRSNNPtr &crs) {
- const auto singleCRS = dynamic_cast<const SingleCRS *>(crs.get());
- if (singleCRS) {
- return singleCRS->coordinateSystem()->axisList().size();
- }
- const auto compoundCRS = dynamic_cast<const CompoundCRS *>(crs.get());
- if (compoundCRS) {
- size_t axisCount = 0;
- const auto &components = compoundCRS->componentReferenceSystems();
- for (const auto &subCRS : components) {
- axisCount += getAxisCount(subCRS);
- }
- return axisCount;
- }
- const auto boundCRS = dynamic_cast<const BoundCRS *>(crs.get());
- if (boundCRS) {
- return getAxisCount(boundCRS->baseCRS());
- }
- return 0;
-}
-
-// ---------------------------------------------------------------------------
-
-static bool is2D(const CRSNNPtr &crs) { return getAxisCount(crs) == 2; }
-
-// ---------------------------------------------------------------------------
-
-static bool is3D(const CRSNNPtr &crs) { return getAxisCount(crs) == 3; }
-
-// ---------------------------------------------------------------------------
-
static void outputOperations(
DatabaseContextPtr dbContext, const std::string &sourceCRSStr,
const std::string &targetCRSStr, const ExtentPtr &bboxFilter,
@@ -666,15 +635,6 @@ static void outputOperations(
}
auto nnTargetCRS = NN_NO_CHECK(targetCRS);
- if (!promoteTo3D && !outputOpt.quiet &&
- ((is2D(nnSourceCRS) && is3D(nnTargetCRS)) ||
- (is3D(nnSourceCRS) && is2D(nnTargetCRS)))) {
- std::cerr << "Warning: mix of 2D and 3D CRS. Vertical transformations, "
- "if available, will not be applied. Consider using 3D "
- "version of the CRS, or the --3d switch"
- << std::endl;
- }
-
std::vector<CoordinateOperationNNPtr> list;
size_t spatialCriterionPartialIntersectionResultCount = 0;
try {
diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp
index fd4090b2..090d59a1 100644
--- a/src/iso19111/c_api.cpp
+++ b/src/iso19111/c_api.cpp
@@ -7080,6 +7080,11 @@ void PROJ_DLL proj_operation_factory_context_set_discard_superseded(
* by increasing accuracy. Operations with unknown accuracy are sorted last,
* whatever their area.
*
+ * When one of the source or target CRS has a vertical component but not the
+ * other one, the one that has no vertical component is automatically promoted
+ * to a 3D version, where its vertical axis is the ellipsoidal height in metres,
+ * using the ellipsoid of the base geodetic CRS.
+ *
* @param ctx PROJ context, or NULL for default context
* @param source_crs source CRS. Must not be NULL.
* @param target_crs source CRS. Must not be NULL.
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index aea8400c..56a3b38c 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -13445,8 +13445,13 @@ getResolvedCRS(const crs::CRSNNPtr &crs,
* by increasing accuracy. Operations with unknown accuracy are sorted last,
* whatever their area.
*
+ * When one of the source or target CRS has a vertical component but not the
+ * other one, the one that has no vertical component is automatically promoted
+ * to a 3D version, where its vertical axis is the ellipsoidal height in metres,
+ * using the ellipsoid of the base geodetic CRS.
+ *
* @param sourceCRS source CRS.
- * @param targetCRS source CRS.
+ * @param targetCRS target CRS.
* @param context Search context.
* @return a list
*/
diff --git a/test/cli/testprojinfo b/test/cli/testprojinfo
index 2b3432a9..81d0d3e4 100755
--- a/test/cli/testprojinfo
+++ b/test/cli/testprojinfo
@@ -115,8 +115,12 @@ echo "Testing NGF IGN69 height to RGF93: projinfo -s EPSG:5720 -t EPSG:4965 -o P
$EXE -s EPSG:5720 -t EPSG:4965 -o PROJ >>${OUT} 2>&1
echo "" >>${OUT}
+echo "Testing EPSG:32631 --3d" >> ${OUT}
+$EXE EPSG:32631 --3d >>${OUT} 2>&1
+echo "" >>${OUT}
+
echo "Testing -s EPSG:32631 -t EPSG:4326+3855 --summary" >> ${OUT}
-$EXE -s EPSG:32631 -t EPSG:4326+3855 --summary 2>>${OUT}
+$EXE -s EPSG:32631 -t EPSG:4326+3855 --summary >>${OUT} 2>&1
echo "" >>${OUT}
echo "Testing -s EPSG:32631 -t EPSG:4326+3855 --3d --summary" >> ${OUT}
diff --git a/test/cli/testprojinfo_out.dist b/test/cli/testprojinfo_out.dist
index 9ec74fde..2a3b35a6 100644
--- a/test/cli/testprojinfo_out.dist
+++ b/test/cli/testprojinfo_out.dist
@@ -821,8 +821,57 @@ INVERSE(EPSG):10000, Inverse of RGF93 to NGF IGN69 height (1), 0.5 m, France - m
PROJ string:
+proj=pipeline +step +inv +proj=vgridshift +grids=ggf97a.txt +multiplier=1
+Testing EPSG:32631 --3d
+PROJ.4 string:
++proj=utm +zone=31 +datum=WGS84 +units=m +no_defs +type=crs
+
+WKT2:2019 string:
+PROJCRS["WGS 84 / UTM zone 31N",
+ BASEGEOGCRS["WGS 84",
+ DATUM["World Geodetic System 1984",
+ ELLIPSOID["WGS 84",6378137,298.257223563,
+ LENGTHUNIT["metre",1]]],
+ PRIMEM["Greenwich",0,
+ ANGLEUNIT["degree",0.0174532925199433]],
+ ID["EPSG",4979]],
+ CONVERSION["UTM zone 31N",
+ METHOD["Transverse Mercator",
+ ID["EPSG",9807]],
+ PARAMETER["Latitude of natural origin",0,
+ ANGLEUNIT["degree",0.0174532925199433],
+ ID["EPSG",8801]],
+ PARAMETER["Longitude of natural origin",3,
+ ANGLEUNIT["degree",0.0174532925199433],
+ ID["EPSG",8802]],
+ PARAMETER["Scale factor at natural origin",0.9996,
+ SCALEUNIT["unity",1],
+ ID["EPSG",8805]],
+ PARAMETER["False easting",500000,
+ LENGTHUNIT["metre",1],
+ ID["EPSG",8806]],
+ PARAMETER["False northing",0,
+ LENGTHUNIT["metre",1],
+ ID["EPSG",8807]],
+ ID["EPSG",16031]],
+ CS[Cartesian,3],
+ AXIS["(E)",east,
+ ORDER[1],
+ LENGTHUNIT["metre",1,
+ ID["EPSG",9001]]],
+ AXIS["(N)",north,
+ ORDER[2],
+ LENGTHUNIT["metre",1,
+ ID["EPSG",9001]]],
+ AXIS["ellipsoidal height (h)",up,
+ ORDER[3],
+ LENGTHUNIT["metre",1,
+ ID["EPSG",9001]]]]
+
Testing -s EPSG:32631 -t EPSG:4326+3855 --summary
-Warning: mix of 2D and 3D CRS. Vertical transformations, if available, will not be applied. Consider using 3D version of the CRS, or the --3d switch
+Candidate operations found: 3
+unknown id, Inverse of UTM zone 31N + WGS 84 to EGM2008 height (1), 1 m, World
+unknown id, Inverse of UTM zone 31N + WGS 84 to EGM2008 height (2), 0.5 m, World
+unknown id, Inverse of UTM zone 31N + Inverse of Transformation from EGM2008 height to WGS 84 (ballpark vertical transformation, without ellipsoid height to vertical height correction), unknown accuracy, World, has ballpark transformation
Testing -s EPSG:32631 -t EPSG:4326+3855 --3d --summary
Candidate operations found: 3