aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-12-13 16:23:01 +0100
committerEven Rouault <even.rouault@spatialys.com>2018-12-13 16:30:48 +0100
commit13625a0c3f5a8a1b3a6ac63b4f49234a3722f62c (patch)
treeaf44cafeaff73b6843576222e2b8bafefb8425ae
parent048cd320b4e63b9378cf6332c8bff11f03a6c39b (diff)
downloadPROJ-13625a0c3f5a8a1b3a6ac63b4f49234a3722f62c.tar.gz
PROJ-13625a0c3f5a8a1b3a6ac63b4f49234a3722f62c.zip
Tune behaviour for LAEA vs LAEA Spherical or EQC vs EQC Spherical
-rw-r--r--src/coordinateoperation.cpp27
-rw-r--r--src/io.cpp12
-rw-r--r--test/unit/test_io.cpp48
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) {
diff --git a/src/io.cpp b/src/io.cpp
index 71d029ea..caf9b53d 100644
--- a/src/io.cpp
+++ b/src/io.cpp
@@ -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");