aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/crs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/iso19111/crs.cpp')
-rw-r--r--src/iso19111/crs.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index d0e23f95..b98e5937 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -843,6 +843,49 @@ CRSNNPtr CRS::promoteTo3D(const std::string &newName,
return NN_NO_CHECK(
std::static_pointer_cast<CRS>(shared_from_this().as_nullable()));
}
+// ---------------------------------------------------------------------------
+
+/** \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 7.0
+ */
+CRSNNPtr CRS::demoteTo2D(const std::string &newName,
+ const io::DatabaseContextPtr &dbContext) const {
+ const auto geogCRS = dynamic_cast<const GeographicCRS *>(this);
+ if (geogCRS) {
+ return geogCRS->demoteTo2D(newName, dbContext);
+ }
+
+ const auto projCRS = dynamic_cast<const ProjectedCRS *>(this);
+ if (projCRS) {
+ return projCRS->demoteTo2D(newName, dbContext);
+ }
+
+ const auto boundCRS = dynamic_cast<const BoundCRS *>(this);
+ if (boundCRS) {
+ return BoundCRS::create(
+ boundCRS->baseCRS()->demoteTo2D(newName, dbContext),
+ boundCRS->hubCRS(), boundCRS->transformation());
+ }
+
+ const auto compoundCRS = dynamic_cast<const CompoundCRS *>(this);
+ if (compoundCRS) {
+ const auto &components = compoundCRS->componentReferenceSystems();
+ if (components.size() >= 2) {
+ return components[0];
+ }
+ }
+
+ return NN_NO_CHECK(
+ std::static_pointer_cast<CRS>(shared_from_this().as_nullable()));
+}
// ---------------------------------------------------------------------------
@@ -3650,6 +3693,44 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
// ---------------------------------------------------------------------------
+/** \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 7.0
+ */
+ProjectedCRSNNPtr
+ProjectedCRS::demoteTo2D(const std::string &newName,
+ const io::DatabaseContextPtr &dbContext) const {
+
+ const auto &axisList = coordinateSystem()->axisList();
+ if (axisList.size() == 3) {
+ auto cs = cs::CartesianCS::create(util::PropertyMap(), axisList[0],
+ axisList[1]);
+ const auto &l_baseCRS = baseCRS();
+ const auto geogCRS =
+ dynamic_cast<const GeographicCRS *>(l_baseCRS.get());
+ const auto newBaseCRS =
+ geogCRS ? util::nn_static_pointer_cast<GeodeticCRS>(
+ geogCRS->demoteTo2D(std::string(), dbContext))
+ : l_baseCRS;
+ return ProjectedCRS::create(
+ util::PropertyMap().set(common::IdentifiedObject::NAME_KEY,
+ !newName.empty() ? newName : nameStr()),
+ newBaseCRS, derivingConversionRef(), cs);
+ }
+
+ return NN_NO_CHECK(std::dynamic_pointer_cast<ProjectedCRS>(
+ shared_from_this().as_nullable()));
+}
+
+// ---------------------------------------------------------------------------
+
//! @cond Doxygen_Suppress
std::list<std::pair<CRSNNPtr, int>>