diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-11-25 04:54:17 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-11-25 05:19:59 +0100 |
| commit | 685a64466a3bc25a8d0bdb0b0f932ad7e977620d (patch) | |
| tree | 5f4918085597e717cbf831462631e74d770d58aa /test | |
| parent | 875aba7c9d894f84f2c6a5efdfdeba9cf15245f5 (diff) | |
| download | PROJ-685a64466a3bc25a8d0bdb0b0f932ad7e977620d.tar.gz PROJ-685a64466a3bc25a8d0bdb0b0f932ad7e977620d.zip | |
normalizeForVisualization() and other methods applying on a ProjectedCRS: do not mess the derivingConversion object of the original object (fixes #1736)
normalizeForVisualization(), promoteTo3D(), demoteTo2D(), alterGeodeticCRS(),
alterCSLinearUnit() and alterParametersLinearUnit() all used the object
returned by derivingConversionRef() to create a new ProjectedCRS. While doing
so, this caused the derivingConversion of the original object to have its
targetCRS set to the object returned by normalizeForVisualization() and similar.
If that object died, then the weak pointer would be reset, and the original
ProjectedCRS() has now its derivingConversionRef()->targetCRS() nullptr
So bottom line is use derivingConversion() for anything that is not pure
reading !!!
This is confirmed to be the fix for the QGIS scenario in
https://github.com/qgis/QGIS/issues/30569#issuecomment-540060919
In QGIS use case, the issue arised when using a projected CRS with a non-GIS
friendly axis (that is where normalizeForVisualization() created a new projectedCRS)
Diffstat (limited to 'test')
| -rw-r--r-- | test/unit/test_crs.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
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()); +} |
