aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/proj/coordinateoperation.hpp8
-rw-r--r--src/iso19111/coordinateoperation.cpp25
-rw-r--r--src/iso19111/crs.cpp28
-rw-r--r--test/unit/test_crs.cpp30
4 files changed, 85 insertions, 6 deletions
diff --git a/include/proj/coordinateoperation.hpp b/include/proj/coordinateoperation.hpp
index 686a0c73..7868de4d 100644
--- a/include/proj/coordinateoperation.hpp
+++ b/include/proj/coordinateoperation.hpp
@@ -1593,6 +1593,14 @@ class PROJ_GCC_DLL Transformation : public SingleOperation {
PROJ_INTERNAL TransformationNNPtr shallowClone() const;
+ PROJ_INTERNAL TransformationNNPtr
+ promoteTo3D(const std::string &newName,
+ const io::DatabaseContextPtr &dbContext) const;
+
+ PROJ_INTERNAL TransformationNNPtr
+ demoteTo2D(const std::string &newName,
+ const io::DatabaseContextPtr &dbContext) const;
+
//! @endcond
protected:
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index 0f5e4c4d..6b552721 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -6590,6 +6590,31 @@ TransformationNNPtr Transformation::shallowClone() const {
CoordinateOperationNNPtr Transformation::_shallowClone() const {
return util::nn_static_pointer_cast<CoordinateOperation>(shallowClone());
}
+
+// ---------------------------------------------------------------------------
+
+TransformationNNPtr
+Transformation::promoteTo3D(const std::string &,
+ const io::DatabaseContextPtr &dbContext) const {
+ auto transf = shallowClone();
+ transf->setCRSs(sourceCRS()->promoteTo3D(std::string(), dbContext),
+ targetCRS()->promoteTo3D(std::string(), dbContext),
+ interpolationCRS());
+ return transf;
+}
+
+// ---------------------------------------------------------------------------
+
+TransformationNNPtr
+Transformation::demoteTo2D(const std::string &,
+ const io::DatabaseContextPtr &dbContext) const {
+ auto transf = shallowClone();
+ transf->setCRSs(sourceCRS()->demoteTo2D(std::string(), dbContext),
+ targetCRS()->demoteTo2D(std::string(), dbContext),
+ interpolationCRS());
+ return transf;
+}
+
//! @endcond
// ---------------------------------------------------------------------------
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index c23bd29b..0d461d64 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -902,9 +902,17 @@ CRSNNPtr CRS::promoteTo3D(const std::string &newName,
const auto boundCRS = dynamic_cast<const BoundCRS *>(this);
if (boundCRS) {
- return BoundCRS::create(
- boundCRS->baseCRS()->promoteTo3D(newName, dbContext),
- boundCRS->hubCRS(), boundCRS->transformation());
+ auto base3DCRS = boundCRS->baseCRS()->promoteTo3D(newName, dbContext);
+ auto transf = boundCRS->transformation();
+ try {
+ transf->getTOWGS84Parameters();
+ return BoundCRS::create(
+ base3DCRS,
+ boundCRS->hubCRS()->promoteTo3D(std::string(), dbContext),
+ transf->promoteTo3D(std::string(), dbContext));
+ } catch (const io::FormattingException &) {
+ return BoundCRS::create(base3DCRS, boundCRS->hubCRS(), transf);
+ }
}
return NN_NO_CHECK(
@@ -937,9 +945,17 @@ CRSNNPtr CRS::demoteTo2D(const std::string &newName,
const auto boundCRS = dynamic_cast<const BoundCRS *>(this);
if (boundCRS) {
- return BoundCRS::create(
- boundCRS->baseCRS()->demoteTo2D(newName, dbContext),
- boundCRS->hubCRS(), boundCRS->transformation());
+ auto base2DCRS = boundCRS->baseCRS()->demoteTo2D(newName, dbContext);
+ auto transf = boundCRS->transformation();
+ try {
+ transf->getTOWGS84Parameters();
+ return BoundCRS::create(
+ base2DCRS,
+ boundCRS->hubCRS()->demoteTo2D(std::string(), dbContext),
+ transf->demoteTo2D(std::string(), dbContext));
+ } catch (const io::FormattingException &) {
+ return BoundCRS::create(base2DCRS, boundCRS->hubCRS(), transf);
+ }
}
const auto compoundCRS = dynamic_cast<const CompoundCRS *>(this);
diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp
index c00556a7..cf285b0a 100644
--- a/test/unit/test_crs.cpp
+++ b/test/unit/test_crs.cpp
@@ -5794,6 +5794,21 @@ TEST(crs, promoteTo3D_and_demoteTo2D) {
nn_dynamic_pointer_cast<ProjectedCRS>(crs3DAsBound->baseCRS());
ASSERT_TRUE(baseCRS != nullptr);
EXPECT_EQ(baseCRS->coordinateSystem()->axisList().size(), 3U);
+
+ auto hubCRS =
+ nn_dynamic_pointer_cast<GeographicCRS>(crs3DAsBound->hubCRS());
+ ASSERT_TRUE(hubCRS != nullptr);
+ EXPECT_EQ(hubCRS->coordinateSystem()->axisList().size(), 3U);
+
+ auto transfSrcCRS = nn_dynamic_pointer_cast<GeographicCRS>(
+ crs3DAsBound->transformation()->sourceCRS());
+ ASSERT_TRUE(transfSrcCRS != nullptr);
+ EXPECT_EQ(transfSrcCRS->coordinateSystem()->axisList().size(), 3U);
+
+ auto transfDstCRS = nn_dynamic_pointer_cast<GeographicCRS>(
+ crs3DAsBound->transformation()->targetCRS());
+ ASSERT_TRUE(transfDstCRS != nullptr);
+ EXPECT_EQ(transfDstCRS->coordinateSystem()->axisList().size(), 3U);
}
auto demoted = crs3DAsBound->demoteTo2D(std::string(), nullptr);
@@ -5804,6 +5819,21 @@ TEST(crs, promoteTo3D_and_demoteTo2D) {
nn_dynamic_pointer_cast<ProjectedCRS>(crs2DAsBound->baseCRS());
ASSERT_TRUE(baseCRS != nullptr);
EXPECT_EQ(baseCRS->coordinateSystem()->axisList().size(), 2U);
+
+ auto hubCRS =
+ nn_dynamic_pointer_cast<GeographicCRS>(crs2DAsBound->hubCRS());
+ ASSERT_TRUE(hubCRS != nullptr);
+ EXPECT_EQ(hubCRS->coordinateSystem()->axisList().size(), 2U);
+
+ auto transfSrcCRS = nn_dynamic_pointer_cast<GeographicCRS>(
+ crs2DAsBound->transformation()->sourceCRS());
+ ASSERT_TRUE(transfSrcCRS != nullptr);
+ EXPECT_EQ(transfSrcCRS->coordinateSystem()->axisList().size(), 2U);
+
+ auto transfDstCRS = nn_dynamic_pointer_cast<GeographicCRS>(
+ crs2DAsBound->transformation()->targetCRS());
+ ASSERT_TRUE(transfDstCRS != nullptr);
+ EXPECT_EQ(transfDstCRS->coordinateSystem()->axisList().size(), 2U);
}
}