Skip to content

Commit

Permalink
Implement normalizeForVisualization for DerivedProjected (#3477)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjimenezshaw authored and github-actions[bot] committed Nov 19, 2022
1 parent 4908792 commit 8c0c12d
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 18 deletions.
64 changes: 46 additions & 18 deletions src/iso19111/crs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -871,26 +871,32 @@ static bool mustAxisOrderBeSwitchedForVisualizationInternal(

bool CRS::mustAxisOrderBeSwitchedForVisualization() const {

const CompoundCRS *compoundCRS = dynamic_cast<const CompoundCRS *>(this);
if (compoundCRS) {
if (const CompoundCRS *compoundCRS =
dynamic_cast<const CompoundCRS *>(this)) {
const auto &comps = compoundCRS->componentReferenceSystems();
if (!comps.empty()) {
return comps[0]->mustAxisOrderBeSwitchedForVisualization();
}
}

const GeographicCRS *geogCRS = dynamic_cast<const GeographicCRS *>(this);
if (geogCRS) {
if (const GeographicCRS *geogCRS =
dynamic_cast<const GeographicCRS *>(this)) {
return mustAxisOrderBeSwitchedForVisualizationInternal(
geogCRS->coordinateSystem()->axisList());
}

const ProjectedCRS *projCRS = dynamic_cast<const ProjectedCRS *>(this);
if (projCRS) {
if (const ProjectedCRS *projCRS =
dynamic_cast<const ProjectedCRS *>(this)) {
return mustAxisOrderBeSwitchedForVisualizationInternal(
projCRS->coordinateSystem()->axisList());
}

if (const DerivedProjectedCRS *derivedProjCRS =
dynamic_cast<const DerivedProjectedCRS *>(this)) {
return mustAxisOrderBeSwitchedForVisualizationInternal(
derivedProjCRS->coordinateSystem()->axisList());
}

return false;
}

Expand Down Expand Up @@ -1009,8 +1015,8 @@ CRSNNPtr CRS::applyAxisOrderReversal(const char *nameSuffix) const {
return props;
};

const CompoundCRS *compoundCRS = dynamic_cast<const CompoundCRS *>(this);
if (compoundCRS) {
if (const CompoundCRS *compoundCRS =
dynamic_cast<const CompoundCRS *>(this)) {
const auto &comps = compoundCRS->componentReferenceSystems();
if (!comps.empty()) {
std::vector<CRSNNPtr> newComps;
Expand All @@ -1026,8 +1032,8 @@ CRSNNPtr CRS::applyAxisOrderReversal(const char *nameSuffix) const {
}
}

const GeographicCRS *geogCRS = dynamic_cast<const GeographicCRS *>(this);
if (geogCRS) {
if (const GeographicCRS *geogCRS =
dynamic_cast<const GeographicCRS *>(this)) {
const auto &axisList = geogCRS->coordinateSystem()->axisList();
auto cs =
axisList.size() == 2
Expand All @@ -1040,8 +1046,8 @@ CRSNNPtr CRS::applyAxisOrderReversal(const char *nameSuffix) const {
geogCRS->datumEnsemble(), cs));
}

const ProjectedCRS *projCRS = dynamic_cast<const ProjectedCRS *>(this);
if (projCRS) {
if (const ProjectedCRS *projCRS =
dynamic_cast<const ProjectedCRS *>(this)) {
const auto &axisList = projCRS->coordinateSystem()->axisList();
auto cs =
axisList.size() == 2
Expand All @@ -1054,6 +1060,20 @@ CRSNNPtr CRS::applyAxisOrderReversal(const char *nameSuffix) const {
projCRS->derivingConversion(), cs));
}

if (const DerivedProjectedCRS *derivedProjCRS =
dynamic_cast<const DerivedProjectedCRS *>(this)) {
const auto &axisList = derivedProjCRS->coordinateSystem()->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>(DerivedProjectedCRS::create(
createProperties(), derivedProjCRS->baseCRS(),
derivedProjCRS->derivingConversion(), cs));
}

throw util::UnsupportedOperationException(
"axis order reversal not supported on this type of CRS");
}
Expand All @@ -1062,31 +1082,39 @@ CRSNNPtr CRS::applyAxisOrderReversal(const char *nameSuffix) const {

CRSNNPtr CRS::normalizeForVisualization() const {

const CompoundCRS *compoundCRS = dynamic_cast<const CompoundCRS *>(this);
if (compoundCRS) {
if (const CompoundCRS *compoundCRS =
dynamic_cast<const CompoundCRS *>(this)) {
const auto &comps = compoundCRS->componentReferenceSystems();
if (!comps.empty() &&
comps[0]->mustAxisOrderBeSwitchedForVisualization()) {
return applyAxisOrderReversal(NORMALIZED_AXIS_ORDER_SUFFIX_STR);
}
}

const GeographicCRS *geogCRS = dynamic_cast<const GeographicCRS *>(this);
if (geogCRS) {
if (const GeographicCRS *geogCRS =
dynamic_cast<const GeographicCRS *>(this)) {
const auto &axisList = geogCRS->coordinateSystem()->axisList();
if (mustAxisOrderBeSwitchedForVisualizationInternal(axisList)) {
return applyAxisOrderReversal(NORMALIZED_AXIS_ORDER_SUFFIX_STR);
}
}

const ProjectedCRS *projCRS = dynamic_cast<const ProjectedCRS *>(this);
if (projCRS) {
if (const ProjectedCRS *projCRS =
dynamic_cast<const ProjectedCRS *>(this)) {
const auto &axisList = projCRS->coordinateSystem()->axisList();
if (mustAxisOrderBeSwitchedForVisualizationInternal(axisList)) {
return applyAxisOrderReversal(NORMALIZED_AXIS_ORDER_SUFFIX_STR);
}
}

if (const DerivedProjectedCRS *derivedProjCRS =
dynamic_cast<const DerivedProjectedCRS *>(this)) {
const auto &axisList = derivedProjCRS->coordinateSystem()->axisList();
if (mustAxisOrderBeSwitchedForVisualizationInternal(axisList)) {
return applyAxisOrderReversal(NORMALIZED_AXIS_ORDER_SUFFIX_STR);
}
}

return NN_NO_CHECK(
std::static_pointer_cast<CRS>(shared_from_this().as_nullable()));
}
Expand Down
85 changes: 85 additions & 0 deletions test/unit/test_crs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4218,6 +4218,20 @@ static DerivedProjectedCRSNNPtr createDerivedProjectedCRS() {
CartesianCS::createEastingNorthing(UnitOfMeasure::METRE));
}

static DerivedProjectedCRSNNPtr createDerivedProjectedCRSNorthingEasting() {

auto derivingConversion = Conversion::create(
PropertyMap().set(IdentifiedObject::NAME_KEY, "unnamed"),
PropertyMap().set(IdentifiedObject::NAME_KEY, "PROJ unimplemented"),
std::vector<OperationParameterNNPtr>{},
std::vector<ParameterValueNNPtr>{});

return DerivedProjectedCRS::create(
PropertyMap().set(IdentifiedObject::NAME_KEY, "derived projectedCRS"),
createProjected(), derivingConversion,
CartesianCS::createNorthingEasting(UnitOfMeasure::FOOT));
}

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

static DerivedVerticalCRSNNPtr createDerivedVerticalCRS() {
Expand Down Expand Up @@ -6858,6 +6872,77 @@ TEST(crs, promoteTo3D_and_demoteTo2D) {

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

TEST(crs, normalizeForVisualization_derivedprojected_operation) {
auto crs = createDerivedProjectedCRSNorthingEasting();

auto op = CoordinateOperationFactory::create()->createOperation(
GeographicCRS::EPSG_4326, crs);

auto proj_string =
"+proj=pipeline +step +proj=axisswap +order=2,1 +step "
"+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=utm +zone=31 "
"+ellps=WGS84 +step +proj=unimplemented +step +proj=unitconvert "
"+xy_in=m +xy_out=ft +step +proj=axisswap +order=2,1";

ASSERT_TRUE(op != nullptr);
EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
proj_string);

auto opNormalized = op->normalizeForVisualization();
auto proj_string_normalized =
"+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad +step "
"+proj=utm +zone=31 +ellps=WGS84 +step +proj=unimplemented +step "
"+proj=unitconvert +xy_in=m +xy_out=ft";
EXPECT_EQ(
opNormalized->exportToPROJString(PROJStringFormatter::create().get()),
proj_string_normalized);
}

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

TEST(crs, normalizeForVisualization_derivedprojected) {

auto crs = createDerivedProjectedCRSNorthingEasting();

{
const auto &axisList = crs->coordinateSystem()->axisList();
ASSERT_EQ(axisList.size(), 2U);
EXPECT_EQ(axisList[0]->direction(),
osgeo::proj::cs::AxisDirection::NORTH);
EXPECT_EQ(axisList[1]->direction(),
osgeo::proj::cs::AxisDirection::EAST);
}

{
auto normalized = nn_dynamic_pointer_cast<SingleCRS>(
crs->normalizeForVisualization());
const auto &normalizedAxisList =
normalized->coordinateSystem()->axisList();
ASSERT_EQ(normalizedAxisList.size(), 2U);
EXPECT_EQ(normalizedAxisList[0]->direction(),
osgeo::proj::cs::AxisDirection::EAST);
EXPECT_EQ(normalizedAxisList[1]->direction(),
osgeo::proj::cs::AxisDirection::NORTH);
}

{
auto normalized3D = nn_dynamic_pointer_cast<SingleCRS>(
crs->promoteTo3D(std::string(), nullptr)
->normalizeForVisualization());
const auto &normalized3DAxisList =
normalized3D->coordinateSystem()->axisList();
ASSERT_EQ(normalized3DAxisList.size(), 3U);
EXPECT_EQ(normalized3DAxisList[0]->direction(),
osgeo::proj::cs::AxisDirection::EAST);
EXPECT_EQ(normalized3DAxisList[1]->direction(),
osgeo::proj::cs::AxisDirection::NORTH);
EXPECT_EQ(normalized3DAxisList[2]->direction(),
osgeo::proj::cs::AxisDirection::UP);
}
}

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

TEST(crs, projected_normalizeForVisualization_do_not_mess_deriving_conversion) {

auto authFactory =
Expand Down

0 comments on commit 8c0c12d

Please sign in to comment.