aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/crs.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-09-26 11:57:37 +0200
committerEven Rouault <even.rouault@spatialys.com>2019-09-26 14:18:21 +0200
commit862f04e7d9114cfbb1502ce257de0966aa5c362a (patch)
tree4097387cecc2f4718862e7689b1ec72bcaa62a5a /src/iso19111/crs.cpp
parentc1efe4ae328593c29c6d9b6be3566fc9545e70cc (diff)
downloadPROJ-862f04e7d9114cfbb1502ce257de0966aa5c362a.tar.gz
PROJ-862f04e7d9114cfbb1502ce257de0966aa5c362a.zip
Improve vertical transformation support
When we had a transformation between a compoundCRS and a target geographicCRS, we did not take into account that in the vertical->other_geog_CRS transformation we used, the other_geog_CRS was an implicit interpolation CRS. Thus before doing vertical adjustment, we must go to this interpolation CRS. The workflow is thus: source CRS -> interpolation CRS + vertical adjustment + interplation CRS -> target CRS
Diffstat (limited to 'src/iso19111/crs.cpp')
-rw-r--r--src/iso19111/crs.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index 1b7078c3..e4e05166 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -2111,6 +2111,58 @@ GeographicCRSNNPtr GeographicCRS::createEPSG_4807() {
// ---------------------------------------------------------------------------
+/** \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
+ */
+GeographicCRSNNPtr
+GeographicCRS::demoteTo2D(const std::string &newName,
+ const io::DatabaseContextPtr &dbContext) const {
+
+ const auto &axisList = coordinateSystem()->axisList();
+ if (axisList.size() == 3) {
+ const auto &l_identifiers = identifiers();
+ // First check if there is a Geographic 3D CRS in the database
+ // of the same name.
+ // This is the common practice in the EPSG dataset.
+ if (dbContext && l_identifiers.size() == 1) {
+ auto authFactory = io::AuthorityFactory::create(
+ NN_NO_CHECK(dbContext), *(l_identifiers[0]->codeSpace()));
+ auto res = authFactory->createObjectsFromName(
+ nameStr(),
+ {io::AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS}, false);
+ if (!res.empty()) {
+ const auto &firstRes = res.front();
+ auto firstResAsGeogCRS =
+ util::nn_dynamic_pointer_cast<GeographicCRS>(firstRes);
+ if (firstResAsGeogCRS &&
+ firstResAsGeogCRS->is2DPartOf3D(NN_NO_CHECK(this))) {
+ return NN_NO_CHECK(firstResAsGeogCRS);
+ }
+ }
+ }
+
+ auto cs = cs::EllipsoidalCS::create(util::PropertyMap(), axisList[0],
+ axisList[1]);
+ return GeographicCRS::create(
+ util::PropertyMap().set(common::IdentifiedObject::NAME_KEY,
+ !newName.empty() ? newName : nameStr()),
+ datum(), datumEnsemble(), cs);
+ }
+
+ return NN_NO_CHECK(std::dynamic_pointer_cast<GeographicCRS>(
+ shared_from_this().as_nullable()));
+}
+
+// ---------------------------------------------------------------------------
+
//! @cond Doxygen_Suppress
void GeographicCRS::addAngularUnitConvertAndAxisSwap(
io::PROJStringFormatter *formatter) const {