diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2018-12-13 16:23:01 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2018-12-13 16:30:48 +0100 |
| commit | 13625a0c3f5a8a1b3a6ac63b4f49234a3722f62c (patch) | |
| tree | af44cafeaff73b6843576222e2b8bafefb8425ae | |
| parent | 048cd320b4e63b9378cf6332c8bff11f03a6c39b (diff) | |
| download | PROJ-13625a0c3f5a8a1b3a6ac63b4f49234a3722f62c.tar.gz PROJ-13625a0c3f5a8a1b3a6ac63b4f49234a3722f62c.zip | |
Tune behaviour for LAEA vs LAEA Spherical or EQC vs EQC Spherical
| -rw-r--r-- | src/coordinateoperation.cpp | 27 | ||||
| -rw-r--r-- | src/io.cpp | 12 | ||||
| -rw-r--r-- | test/unit/test_io.cpp | 48 |
3 files changed, 84 insertions, 3 deletions
diff --git a/src/coordinateoperation.cpp b/src/coordinateoperation.cpp index a1f305bf..ac170bbf 100644 --- a/src/coordinateoperation.cpp +++ b/src/coordinateoperation.cpp @@ -1503,10 +1503,35 @@ bool SingleOperation::_isEquivalentTo(const util::IComparable *other, const int methodEPSGCode = d->method_->getEPSGCode(); const int otherMethodEPSGCode = otherSO->d->method_->getEPSGCode(); - const bool equivalentMethods = + bool equivalentMethods = (criterion == util::IComparable::Criterion::EQUIVALENT && methodEPSGCode != 0 && methodEPSGCode == otherMethodEPSGCode) || d->method_->_isEquivalentTo(otherSO->d->method_.get(), criterion); + if (!equivalentMethods && + criterion == util::IComparable::Criterion::EQUIVALENT) { + if ((methodEPSGCode == EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA && + otherMethodEPSGCode == + EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA_SPHERICAL) || + (otherMethodEPSGCode == + EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA && + methodEPSGCode == + EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA_SPHERICAL) || + (methodEPSGCode == EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL && + otherMethodEPSGCode == + EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL) || + (otherMethodEPSGCode == EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL && + methodEPSGCode == + EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL)) { + auto geodCRS = + dynamic_cast<const crs::GeodeticCRS *>(sourceCRS().get()); + auto otherGeodCRS = dynamic_cast<const crs::GeodeticCRS *>( + otherSO->sourceCRS().get()); + if (geodCRS && otherGeodCRS && geodCRS->ellipsoid()->isSphere() && + otherGeodCRS->ellipsoid()->isSphere()) { + equivalentMethods = true; + } + } + } if (!equivalentMethods) { if (criterion == util::IComparable::Criterion::EQUIVALENT) { @@ -6500,8 +6500,7 @@ CRSNNPtr PROJStringParser::Private::buildProjectedCRS( } } else if (step.name == "aeqd" && hasParamValue(step, "guam")) { mapping = getMapping(EPSG_CODE_METHOD_GUAM_PROJECTION); - } else if (step.name == "cea" && - !geogCRS->datum()->ellipsoid()->isSphere()) { + } else if (step.name == "cea" && !geogCRS->ellipsoid()->isSphere()) { mapping = getMapping(EPSG_CODE_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA); } else if (step.name == "geos" && getParamValue(step, "sweep") == "x") { mapping = @@ -6598,6 +6597,15 @@ CRSNNPtr PROJStringParser::Private::buildProjectedCRS( axisType = AxisType::SOUTH_POLE; } } + if (geogCRS->ellipsoid()->isSphere()) { + mapping = getMapping( + EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA_SPHERICAL); + } + } else if (step.name == "eqc") { + if (geogCRS->ellipsoid()->isSphere()) { + mapping = + getMapping(EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL); + } } UnitOfMeasure unit = buildUnit(step, "units", "to_meter"); diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index bd230b45..a385fe87 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -42,6 +42,8 @@ #include "proj/internal/internal.hpp" +#include "proj_constants.h" + #include <string> using namespace osgeo::proj::common; @@ -6973,6 +6975,52 @@ TEST(io, projparse_laea_south_pole) { // --------------------------------------------------------------------------- +TEST(io, projparse_laea_spherical) { + auto obj = PROJStringParser().createFromPROJString("+proj=laea +R=6371228"); + auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_EQ(crs->derivingConversion()->method()->getEPSGCode(), + EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA_SPHERICAL); + + auto crs2 = ProjectedCRS::create( + PropertyMap(), crs->baseCRS(), + Conversion::createLambertAzimuthalEqualArea( + PropertyMap(), Angle(0), Angle(0), Length(0), Length(0)), + crs->coordinateSystem()); + EXPECT_EQ(crs2->derivingConversion()->method()->getEPSGCode(), + EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA); + + EXPECT_TRUE( + crs->isEquivalentTo(crs2.get(), IComparable::Criterion::EQUIVALENT)); + EXPECT_TRUE( + crs2->isEquivalentTo(crs.get(), IComparable::Criterion::EQUIVALENT)); +} + +// --------------------------------------------------------------------------- + +TEST(io, projparse_eqc_spherical) { + auto obj = PROJStringParser().createFromPROJString("+proj=eqc +R=6371228"); + auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_EQ(crs->derivingConversion()->method()->getEPSGCode(), + EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL); + + auto crs2 = ProjectedCRS::create( + PropertyMap(), crs->baseCRS(), + Conversion::createEquidistantCylindrical( + PropertyMap(), Angle(0), Angle(0), Length(0), Length(0)), + crs->coordinateSystem()); + EXPECT_EQ(crs2->derivingConversion()->method()->getEPSGCode(), + EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL); + + EXPECT_TRUE( + crs->isEquivalentTo(crs2.get(), IComparable::Criterion::EQUIVALENT)); + EXPECT_TRUE( + crs2->isEquivalentTo(crs.get(), IComparable::Criterion::EQUIVALENT)); +} + +// --------------------------------------------------------------------------- + TEST(io, projparse_non_earth_ellipsoid) { std::string input("+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +R=1 +units=m " "+no_defs"); |
