From bc97ca635668e5457afc9dbb491c5aa5525ca7de Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 16 Aug 2021 11:58:38 +0200 Subject: Merge pull request #2805 from rouault/fix_2803 Implement promoteTo3D() / demoteTo2D() for DerivedGeographicCRS (fixes #2803) --- src/iso19111/crs.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 28f55ffe..62bb24c3 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1079,8 +1079,24 @@ CRSNNPtr CRS::promoteTo3D(const std::string &newName, return props; }; - const auto geogCRS = dynamic_cast(this); - if (geogCRS) { + if (auto derivedGeogCRS = + dynamic_cast(this)) { + const auto &axisList = derivedGeogCRS->coordinateSystem()->axisList(); + if (axisList.size() == 2) { + auto cs = cs::EllipsoidalCS::create( + util::PropertyMap(), axisList[0], axisList[1], + verticalAxisIfNotAlreadyPresent); + auto baseGeog3DCRS = util::nn_dynamic_pointer_cast( + derivedGeogCRS->baseCRS()->promoteTo3D( + std::string(), dbContext, verticalAxisIfNotAlreadyPresent)); + return util::nn_static_pointer_cast( + DerivedGeographicCRS::create( + createProperties(), NN_CHECK_THROW(baseGeog3DCRS), + derivedGeogCRS->derivingConversion(), cs)); + } + } + + else if (auto geogCRS = dynamic_cast(this)) { const auto &axisList = geogCRS->coordinateSystem()->axisList(); if (axisList.size() == 2) { const auto &l_identifiers = identifiers(); @@ -1120,8 +1136,7 @@ CRSNNPtr CRS::promoteTo3D(const std::string &newName, } } - const auto projCRS = dynamic_cast(this); - if (projCRS) { + else if (auto projCRS = dynamic_cast(this)) { const auto &axisList = projCRS->coordinateSystem()->axisList(); if (axisList.size() == 2) { auto base3DCRS = @@ -1137,8 +1152,7 @@ CRSNNPtr CRS::promoteTo3D(const std::string &newName, } } - const auto boundCRS = dynamic_cast(this); - if (boundCRS) { + else if (auto boundCRS = dynamic_cast(this)) { auto base3DCRS = boundCRS->baseCRS()->promoteTo3D( newName, dbContext, verticalAxisIfNotAlreadyPresent); auto transf = boundCRS->transformation(); @@ -1174,18 +1188,21 @@ CRSNNPtr CRS::promoteTo3D(const std::string &newName, */ CRSNNPtr CRS::demoteTo2D(const std::string &newName, const io::DatabaseContextPtr &dbContext) const { - const auto geogCRS = dynamic_cast(this); - if (geogCRS) { + + if (auto derivedGeogCRS = + dynamic_cast(this)) { + return derivedGeogCRS->demoteTo2D(newName, dbContext); + } + + else if (auto geogCRS = dynamic_cast(this)) { return geogCRS->demoteTo2D(newName, dbContext); } - const auto projCRS = dynamic_cast(this); - if (projCRS) { + else if (auto projCRS = dynamic_cast(this)) { return projCRS->demoteTo2D(newName, dbContext); } - const auto boundCRS = dynamic_cast(this); - if (boundCRS) { + else if (auto boundCRS = dynamic_cast(this)) { auto base2DCRS = boundCRS->baseCRS()->demoteTo2D(newName, dbContext); auto transf = boundCRS->transformation(); try { @@ -1199,8 +1216,7 @@ CRSNNPtr CRS::demoteTo2D(const std::string &newName, } } - const auto compoundCRS = dynamic_cast(this); - if (compoundCRS) { + else if (auto compoundCRS = dynamic_cast(this)) { const auto &components = compoundCRS->componentReferenceSystems(); if (components.size() >= 2) { return components[0]; @@ -5898,6 +5914,38 @@ bool DerivedGeographicCRS::_isEquivalentTo( // --------------------------------------------------------------------------- +/** \brief Return a variant of this CRS "demoted" to a 2D one, if not already + * the case. + * + * + * @param newName Name of the new CRS. If empty, nameStr() will be used. + * @param dbContext Database context to look for potentially already registered + * 2D CRS. May be nullptr. + * @return a new CRS demoted to 2D, or the current one if already 2D or not + * applicable. + * @since 8.1.1 + */ +DerivedGeographicCRSNNPtr DerivedGeographicCRS::demoteTo2D( + const std::string &newName, const io::DatabaseContextPtr &dbContext) const { + + const auto &axisList = coordinateSystem()->axisList(); + if (axisList.size() == 3) { + auto cs = cs::EllipsoidalCS::create(util::PropertyMap(), axisList[0], + axisList[1]); + auto baseGeog2DCRS = util::nn_dynamic_pointer_cast( + baseCRS()->demoteTo2D(std::string(), dbContext)); + return DerivedGeographicCRS::create( + util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, + !newName.empty() ? newName : nameStr()), + NN_CHECK_THROW(baseGeog2DCRS), derivingConversion(), cs); + } + + return NN_NO_CHECK(std::dynamic_pointer_cast( + shared_from_this().as_nullable())); +} + +// --------------------------------------------------------------------------- + //! @cond Doxygen_Suppress std::list> -- cgit v1.2.3