diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-03-28 15:26:00 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-03-29 00:47:41 +0100 |
| commit | 6a7e24dce79f93b73f4919f267df2fdf3ee95713 (patch) | |
| tree | 5f770f21274e82d5b09cbb4cfe299f41e3fb6585 /src/iso19111/crs.cpp | |
| parent | f4baf035dac9e8f1dd37d2121ffc3d1b3f440073 (diff) | |
| download | PROJ-6a7e24dce79f93b73f4919f267df2fdf3ee95713.tar.gz PROJ-6a7e24dce79f93b73f4919f267df2fdf3ee95713.zip | |
Add proj_normalize_for_visualization()
Fixes #1301
This function takes the output PJ from proj_create_crs_to_crs(),
and add (or undo) the needed axis swap operations so that the
object returned by proj_normalize_for_visualization() has the usual
GIS axis order.
In this implementation, this does something only if the coordinate
system of the source or target CRS, geographic or projected, has
NORTH, EAST ordering.
CompoundCRS wrapping those objects are also handled.
Diffstat (limited to 'src/iso19111/crs.cpp')
| -rw-r--r-- | src/iso19111/crs.cpp | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index b51d03c9..1ef7dcda 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -591,6 +591,104 @@ CRSNNPtr CRS::alterId(const std::string &authName, // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress + +static bool isAxisListNorthEast( + const std::vector<cs::CoordinateSystemAxisNNPtr> &axisList) { + const auto &dir0 = axisList[0]->direction(); + const auto &dir1 = axisList[1]->direction(); + return (&dir0 == &cs::AxisDirection::NORTH && + &dir1 == &cs::AxisDirection::EAST); +} +// --------------------------------------------------------------------------- + +bool CRS::mustAxisOrderBeSwitchedForVisualization() const { + + const CompoundCRS *compoundCRS = dynamic_cast<const CompoundCRS *>(this); + if (compoundCRS) { + const auto &comps = compoundCRS->componentReferenceSystems(); + if (!comps.empty()) { + return comps[0]->mustAxisOrderBeSwitchedForVisualization(); + } + } + + const GeographicCRS *geogCRS = dynamic_cast<const GeographicCRS *>(this); + if (geogCRS) { + return isAxisListNorthEast(geogCRS->coordinateSystem()->axisList()); + } + + const ProjectedCRS *projCRS = dynamic_cast<const ProjectedCRS *>(this); + if (projCRS) { + return isAxisListNorthEast(projCRS->coordinateSystem()->axisList()); + } + + return false; +} + +//! @endcond + +// --------------------------------------------------------------------------- + +//! @cond Doxygen_Suppress + +CRSNNPtr CRS::normalizeForVisualization() const { + auto props = util::PropertyMap().set( + common::IdentifiedObject::NAME_KEY, + nameStr() + " (with axis order normalized for visualization)"); + + const CompoundCRS *compoundCRS = dynamic_cast<const CompoundCRS *>(this); + if (compoundCRS) { + const auto &comps = compoundCRS->componentReferenceSystems(); + if (!comps.empty()) { + std::vector<CRSNNPtr> newComps; + newComps.emplace_back(comps[0]->normalizeForVisualization()); + for (size_t i = 1; i < comps.size(); i++) { + newComps.emplace_back(comps[i]); + } + return util::nn_static_pointer_cast<CRS>( + CompoundCRS::create(props, newComps)); + } + } + + const GeographicCRS *geogCRS = dynamic_cast<const GeographicCRS *>(this); + if (geogCRS) { + const auto &axisList = geogCRS->coordinateSystem()->axisList(); + if (isAxisListNorthEast(axisList)) { + auto cs = axisList.size() == 2 + ? cs::EllipsoidalCS::create(util::PropertyMap(), + axisList[1], axisList[0]) + : cs::EllipsoidalCS::create(util::PropertyMap(), + axisList[1], axisList[0], + axisList[2]); + return util::nn_static_pointer_cast<CRS>(GeographicCRS::create( + props, geogCRS->datum(), geogCRS->datumEnsemble(), cs)); + } + } + + const ProjectedCRS *projCRS = dynamic_cast<const ProjectedCRS *>(this); + if (projCRS) { + const auto &axisList = projCRS->coordinateSystem()->axisList(); + if (isAxisListNorthEast(axisList)) { + auto cs = + axisList.size() == 2 + ? cs::CartesianCS::create(util::PropertyMap(), axisList[1], + 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 NN_NO_CHECK( + std::static_pointer_cast<CRS>(shared_from_this().as_nullable())); +} + +//! @endcond + +// --------------------------------------------------------------------------- + /** \brief Identify the CRS with reference CRSs. * * The candidate CRSs are either hard-coded, or looked in the database when |
