aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/proj/crs.hpp3
-rw-r--r--src/iso19111/crs.cpp21
-rw-r--r--test/unit/test_crs.cpp80
3 files changed, 93 insertions, 11 deletions
diff --git a/include/proj/crs.hpp b/include/proj/crs.hpp
index 2b919c71..356c29d9 100644
--- a/include/proj/crs.hpp
+++ b/include/proj/crs.hpp
@@ -514,6 +514,9 @@ class PROJ_GCC_DLL DerivedCRS : virtual public SingleCRS {
PROJ_PRIVATE :
//! @cond Doxygen_Suppress
+
+ // Use this method with extreme care ! It should never be used
+ // to recreate a new Derived/ProjectedCRS !
PROJ_INTERNAL const operation::ConversionNNPtr &
derivingConversionRef() PROJ_PURE_DECL;
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index cf533bd3..eb15b0d8 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -237,7 +237,7 @@ CRSNNPtr CRS::alterGeodeticCRS(const GeodeticCRSNNPtr &newGeodCRS) const {
auto projCRS = dynamic_cast<const ProjectedCRS *>(this);
if (projCRS) {
return ProjectedCRS::create(createPropertyMap(this), newGeodCRS,
- projCRS->derivingConversionRef(),
+ projCRS->derivingConversion(),
projCRS->coordinateSystem());
}
@@ -264,7 +264,7 @@ CRSNNPtr CRS::alterCSLinearUnit(const common::UnitOfMeasure &unit) const {
if (projCRS) {
return ProjectedCRS::create(
createPropertyMap(this), projCRS->baseCRS(),
- projCRS->derivingConversionRef(),
+ projCRS->derivingConversion(),
projCRS->coordinateSystem()->alterUnit(unit));
}
}
@@ -675,9 +675,8 @@ CRSNNPtr CRS::normalizeForVisualization() const {
axisList[0])
: cs::CartesianCS::create(util::PropertyMap(), axisList[1],
axisList[0], axisList[2]);
- return util::nn_static_pointer_cast<CRS>(
- ProjectedCRS::create(props, projCRS->baseCRS(),
- projCRS->derivingConversionRef(), cs));
+ return util::nn_static_pointer_cast<CRS>(ProjectedCRS::create(
+ props, projCRS->baseCRS(), projCRS->derivingConversion(), cs));
}
}
@@ -844,7 +843,7 @@ CRSNNPtr CRS::promoteTo3D(const std::string &newName,
!newName.empty() ? newName : nameStr()),
NN_NO_CHECK(
util::nn_dynamic_pointer_cast<GeodeticCRS>(base3DCRS)),
- projCRS->derivingConversionRef(), cs));
+ projCRS->derivingConversion(), cs));
}
}
@@ -3379,10 +3378,10 @@ bool ProjectedCRS::_isEquivalentTo(
ProjectedCRSNNPtr
ProjectedCRS::alterParametersLinearUnit(const common::UnitOfMeasure &unit,
bool convertToNewUnit) const {
- return create(createPropertyMap(this), baseCRS(),
- derivingConversionRef()->alterParametersLinearUnit(
- unit, convertToNewUnit),
- coordinateSystem());
+ return create(
+ createPropertyMap(this), baseCRS(),
+ derivingConversion()->alterParametersLinearUnit(unit, convertToNewUnit),
+ coordinateSystem());
}
//! @endcond
@@ -3791,7 +3790,7 @@ ProjectedCRS::demoteTo2D(const std::string &newName,
return ProjectedCRS::create(
util::PropertyMap().set(common::IdentifiedObject::NAME_KEY,
!newName.empty() ? newName : nameStr()),
- newBaseCRS, derivingConversionRef(), cs);
+ newBaseCRS, derivingConversion(), cs);
}
return NN_NO_CHECK(std::dynamic_pointer_cast<ProjectedCRS>(
diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp
index 24f4ba52..427fd741 100644
--- a/test/unit/test_crs.cpp
+++ b/test/unit/test_crs.cpp
@@ -5320,3 +5320,83 @@ TEST(crs, promoteTo3D_and_demoteTo2D) {
nullptr);
}
}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, projected_normalizeForVisualization_do_not_mess_deriving_conversion) {
+
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), "EPSG");
+ // Something with non standard order
+ auto projCRS = authFactory->createProjectedCRS("3035");
+ {
+ auto src = GeographicCRS::EPSG_4326;
+ auto op =
+ CoordinateOperationFactory::create()->createOperation(src, projCRS);
+ ASSERT_TRUE(op != nullptr);
+ // Make sure to run that in a scope, so that the object get destroyed
+ op->normalizeForVisualization();
+ }
+ EXPECT_EQ(projCRS->derivingConversion()->targetCRS().get(), projCRS.get());
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, projected_promoteTo3D_do_not_mess_deriving_conversion) {
+
+ auto projCRS = createProjected();
+ {
+ // Make sure to run that in a scope, so that the object get destroyed
+ projCRS->promoteTo3D(std::string(), nullptr);
+ }
+ EXPECT_EQ(projCRS->derivingConversion()->targetCRS().get(), projCRS.get());
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, projected_demoteTo2D_do_not_mess_deriving_conversion) {
+
+ auto projCRS = nn_dynamic_pointer_cast<ProjectedCRS>(
+ createProjected()->promoteTo3D(std::string(), nullptr));
+ {
+ // Make sure to run that in a scope, so that the object get destroyed
+ projCRS->demoteTo2D(std::string(), nullptr);
+ }
+ EXPECT_EQ(projCRS->derivingConversion()->targetCRS().get(), projCRS.get());
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, projected_alterGeodeticCRS_do_not_mess_deriving_conversion) {
+
+ auto projCRS = createProjected();
+ {
+ // Make sure to run that in a scope, so that the object get destroyed
+ projCRS->alterGeodeticCRS(NN_NO_CHECK(projCRS->extractGeographicCRS()));
+ }
+ EXPECT_EQ(projCRS->derivingConversion()->targetCRS().get(), projCRS.get());
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, projected_alterCSLinearUnit_do_not_mess_deriving_conversion) {
+
+ auto projCRS = createProjected();
+ {
+ // Make sure to run that in a scope, so that the object get destroyed
+ projCRS->alterCSLinearUnit(UnitOfMeasure("my unit", 2));
+ }
+ EXPECT_EQ(projCRS->derivingConversion()->targetCRS().get(), projCRS.get());
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, projected_alterParametersLinearUnit_do_not_mess_deriving_conversion) {
+
+ auto projCRS = createProjected();
+ {
+ // Make sure to run that in a scope, so that the object get destroyed
+ projCRS->alterParametersLinearUnit(UnitOfMeasure::METRE, false);
+ }
+ EXPECT_EQ(projCRS->derivingConversion()->targetCRS().get(), projCRS.get());
+}