Skip to content

Commit

Permalink
Add method DerivedProjectedCRS::demoteTo2D and implement promoteTo3D (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jjimenezshaw authored Sep 11, 2022
1 parent 524ceda commit 137caf7
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/proj/crs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,10 @@ class PROJ_GCC_DLL DerivedProjectedCRS final : public DerivedCRS {
const operation::ConversionNNPtr &derivingConversionIn,
const cs::CoordinateSystemNNPtr &csIn);

PROJ_DLL DerivedProjectedCRSNNPtr
demoteTo2D(const std::string &newName,
const io::DatabaseContextPtr &dbContext) const;

//! @cond Doxygen_Suppress
PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
const override; // throw(io::FormattingException)
Expand Down
1 change: 1 addition & 0 deletions scripts/reference_exported_symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ osgeo::proj::crs::DerivedGeographicCRS::demoteTo2D(std::string const&, std::shar
osgeo::proj::crs::DerivedGeographicCRS::~DerivedGeographicCRS()
osgeo::proj::crs::DerivedProjectedCRS::baseCRS() const
osgeo::proj::crs::DerivedProjectedCRS::create(osgeo::proj::util::PropertyMap const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::ProjectedCRS> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::operation::Conversion> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::cs::CoordinateSystem> > const&)
osgeo::proj::crs::DerivedProjectedCRS::demoteTo2D(std::string const&, std::shared_ptr<osgeo::proj::io::DatabaseContext> const&) const
osgeo::proj::crs::DerivedProjectedCRS::~DerivedProjectedCRS()
osgeo::proj::crs::DerivedVerticalCRS::baseCRS() const
osgeo::proj::crs::DerivedVerticalCRS::create(osgeo::proj::util::PropertyMap const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::VerticalCRS> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::operation::Conversion> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::cs::VerticalCS> > const&)
Expand Down
55 changes: 55 additions & 0 deletions src/iso19111/crs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,23 @@ CRSNNPtr CRS::promoteTo3D(const std::string &newName,
}
}

else if (auto derivedProjCRS =
dynamic_cast<const DerivedProjectedCRS *>(this)) {
const auto &axisList = derivedProjCRS->coordinateSystem()->axisList();
if (axisList.size() == 2) {
auto cs = cs::CartesianCS::create(util::PropertyMap(), axisList[0],
axisList[1],
verticalAxisIfNotAlreadyPresent);
auto baseProj3DCRS = util::nn_dynamic_pointer_cast<ProjectedCRS>(
derivedProjCRS->baseCRS()->promoteTo3D(
std::string(), dbContext, verticalAxisIfNotAlreadyPresent));
return util::nn_static_pointer_cast<CRS>(
DerivedProjectedCRS::create(
createProperties(), NN_CHECK_THROW(baseProj3DCRS),
derivedProjCRS->derivingConversion(), cs));
}
}

else if (auto geogCRS = dynamic_cast<const GeographicCRS *>(this)) {
const auto &axisList = geogCRS->coordinateSystem()->axisList();
if (axisList.size() == 2) {
Expand Down Expand Up @@ -1358,6 +1375,11 @@ CRSNNPtr CRS::demoteTo2D(const std::string &newName,
return derivedGeogCRS->demoteTo2D(newName, dbContext);
}

else if (auto derivedProjCRS =
dynamic_cast<const DerivedProjectedCRS *>(this)) {
return derivedProjCRS->demoteTo2D(newName, dbContext);
}

else if (auto geogCRS = dynamic_cast<const GeographicCRS *>(this)) {
return geogCRS->demoteTo2D(newName, dbContext);
}
Expand Down Expand Up @@ -6493,6 +6515,39 @@ DerivedProjectedCRSNNPtr DerivedProjectedCRS::create(

// ---------------------------------------------------------------------------

/** \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 9.1.1
*/
DerivedProjectedCRSNNPtr
DerivedProjectedCRS::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]);
auto baseProj2DCRS = util::nn_dynamic_pointer_cast<ProjectedCRS>(
baseCRS()->demoteTo2D(std::string(), dbContext));
return DerivedProjectedCRS::create(
util::PropertyMap().set(common::IdentifiedObject::NAME_KEY,
!newName.empty() ? newName : nameStr()),
NN_CHECK_THROW(baseProj2DCRS), derivingConversion(), cs);
}

return NN_NO_CHECK(std::dynamic_pointer_cast<DerivedProjectedCRS>(
shared_from_this().as_nullable()));
}

// ---------------------------------------------------------------------------

//! @cond Doxygen_Suppress
void DerivedProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const {
const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2;
Expand Down
26 changes: 26 additions & 0 deletions test/unit/test_crs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6791,6 +6791,32 @@ TEST(crs, promoteTo3D_and_demoteTo2D) {
EXPECT_TRUE(demoted->demoteTo2D(std::string(), nullptr)
->isEquivalentTo(demoted.get()));
}

{
auto crs = createDerivedProjectedCRS();
auto crs3D = crs->promoteTo3D(std::string(), dbContext);
auto crs3DAsDerivedProj =
nn_dynamic_pointer_cast<DerivedProjectedCRS>(crs3D);
ASSERT_TRUE(crs3DAsDerivedProj != nullptr);
EXPECT_EQ(crs3DAsDerivedProj->baseCRS()
->coordinateSystem()
->axisList()
.size(),
3U);
EXPECT_EQ(crs3DAsDerivedProj->coordinateSystem()->axisList().size(),
3U);
EXPECT_TRUE(crs3DAsDerivedProj->promoteTo3D(std::string(), nullptr)
->isEquivalentTo(crs3DAsDerivedProj.get()));

auto demoted = crs3DAsDerivedProj->demoteTo2D(std::string(), dbContext);
EXPECT_EQ(demoted->baseCRS()->coordinateSystem()->axisList().size(),
2U);
EXPECT_EQ(demoted->coordinateSystem()->axisList().size(), 2U);
EXPECT_TRUE(demoted->isEquivalentTo(
crs.get(), IComparable::Criterion::EQUIVALENT));
EXPECT_TRUE(demoted->demoteTo2D(std::string(), nullptr)
->isEquivalentTo(demoted.get()));
}
}

// ---------------------------------------------------------------------------
Expand Down

0 comments on commit 137caf7

Please sign in to comment.