diff options
| -rw-r--r-- | include/proj/coordinateoperation.hpp | 8 | ||||
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 25 | ||||
| -rw-r--r-- | src/iso19111/crs.cpp | 28 | ||||
| -rw-r--r-- | test/unit/test_crs.cpp | 30 |
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); } } |
