aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-12-13 00:55:10 +0100
committerEven Rouault <even.rouault@spatialys.com>2018-12-13 00:55:10 +0100
commitbe7adb85aa92dd601a92313d5b725270596b1a95 (patch)
treee67af5c817e54aebed540876e185a1159a87eb09
parentc566213d28d488df622eeebb52b9aa44fd231189 (diff)
downloadPROJ-be7adb85aa92dd601a92313d5b725270596b1a95.tar.gz
PROJ-be7adb85aa92dd601a92313d5b725270596b1a95.zip
improve isEquivalentTo() when comparing Helmert transformations
-rw-r--r--src/coordinateoperation.cpp51
-rw-r--r--src/crs.cpp3
-rw-r--r--test/unit/test_operation.cpp36
3 files changed, 89 insertions, 1 deletions
diff --git a/src/coordinateoperation.cpp b/src/coordinateoperation.cpp
index ac2c4196..ef03edf8 100644
--- a/src/coordinateoperation.cpp
+++ b/src/coordinateoperation.cpp
@@ -1463,6 +1463,57 @@ bool SingleOperation::_isEquivalentTo(
// Check it by using convertToOtherMethod()
const int otherMethodEPSGCode = otherSO->d->method_->getEPSGCode();
+
+ if ((methodEPSGCode ==
+ EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOCENTRIC &&
+ (otherMethodEPSGCode ==
+ EPSG_CODE_METHOD_POSITION_VECTOR_GEOCENTRIC ||
+ otherMethodEPSGCode ==
+ EPSG_CODE_METHOD_COORDINATE_FRAME_GEOCENTRIC)) ||
+ (methodEPSGCode ==
+ EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D &&
+ (otherMethodEPSGCode ==
+ EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_2D ||
+ otherMethodEPSGCode ==
+ EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_2D)) ||
+ (methodEPSGCode ==
+ EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_3D &&
+ (otherMethodEPSGCode ==
+ EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_3D ||
+ otherMethodEPSGCode ==
+ EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_3D))) {
+ auto transf = static_cast<const Transformation *>(this);
+ auto otherTransf = static_cast<const Transformation *>(otherSO);
+ auto params = transf->getTOWGS84Parameters();
+ auto otherParams = otherTransf->getTOWGS84Parameters();
+ return params == otherParams;
+ }
+
+ if ((otherMethodEPSGCode ==
+ EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOCENTRIC &&
+ (methodEPSGCode ==
+ EPSG_CODE_METHOD_POSITION_VECTOR_GEOCENTRIC ||
+ methodEPSGCode ==
+ EPSG_CODE_METHOD_COORDINATE_FRAME_GEOCENTRIC)) ||
+ (otherMethodEPSGCode ==
+ EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D &&
+ (methodEPSGCode ==
+ EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_2D ||
+ methodEPSGCode ==
+ EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_2D)) ||
+ (otherMethodEPSGCode ==
+ EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_3D &&
+ (methodEPSGCode ==
+ EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_3D ||
+ methodEPSGCode ==
+ EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_3D))) {
+ auto transf = static_cast<const Transformation *>(this);
+ auto otherTransf = static_cast<const Transformation *>(otherSO);
+ auto params = transf->getTOWGS84Parameters();
+ auto otherParams = otherTransf->getTOWGS84Parameters();
+ return params == otherParams;
+ }
+
if (methodEPSGCode ==
EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP &&
otherMethodEPSGCode ==
diff --git a/src/crs.cpp b/src/crs.cpp
index 40a8e2e1..10bec815 100644
--- a/src/crs.cpp
+++ b/src/crs.cpp
@@ -3806,12 +3806,13 @@ bool BoundCRS::_isEquivalentTo(const util::IComparable *other,
!ObjectUsage::_isEquivalentTo(other, criterion))) {
return false;
}
+ const auto standardCriterion = getStandardCriterion(criterion);
return d->baseCRS_->_isEquivalentTo(otherBoundCRS->d->baseCRS_.get(),
criterion) &&
d->hubCRS_->_isEquivalentTo(otherBoundCRS->d->hubCRS_.get(),
criterion) &&
d->transformation_->_isEquivalentTo(
- otherBoundCRS->d->transformation_.get(), criterion);
+ otherBoundCRS->d->transformation_.get(), standardCriterion);
}
// ---------------------------------------------------------------------------
diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp
index 3d1cfc42..b5bd188c 100644
--- a/test/unit/test_operation.cpp
+++ b/test/unit/test_operation.cpp
@@ -6654,3 +6654,39 @@ TEST(operation, lcc2sp_to_lcc1sp_invalid_eccentricity) {
EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP);
EXPECT_FALSE(targetConv != nullptr);
}
+
+// ---------------------------------------------------------------------------
+
+TEST(operation, three_param_equivalent_to_seven_param) {
+
+ auto three_param = Transformation::createGeocentricTranslations(
+ PropertyMap(), GeographicCRS::EPSG_4269, GeographicCRS::EPSG_4326, 1.0,
+ 2.0, 3.0, {});
+
+ auto seven_param_pv = Transformation::createPositionVector(
+ PropertyMap(), GeographicCRS::EPSG_4269, GeographicCRS::EPSG_4326, 1.0,
+ 2.0, 3.0, 0.0, 0.0, 0.0, 0.0, {});
+
+ auto seven_param_cf = Transformation::createCoordinateFrameRotation(
+ PropertyMap(), GeographicCRS::EPSG_4269, GeographicCRS::EPSG_4326, 1.0,
+ 2.0, 3.0, 0.0, 0.0, 0.0, 0.0, {});
+
+ auto seven_param_non_eq = Transformation::createPositionVector(
+ PropertyMap(), GeographicCRS::EPSG_4269, GeographicCRS::EPSG_4326, 1.0,
+ 2.0, 3.0, 1.0, 0.0, 0.0, 0.0, {});
+
+ EXPECT_TRUE(three_param->isEquivalentTo(
+ seven_param_pv.get(), IComparable::Criterion::EQUIVALENT));
+
+ EXPECT_TRUE(three_param->isEquivalentTo(
+ seven_param_cf.get(), IComparable::Criterion::EQUIVALENT));
+
+ EXPECT_TRUE(seven_param_cf->isEquivalentTo(
+ three_param.get(), IComparable::Criterion::EQUIVALENT));
+
+ EXPECT_TRUE(seven_param_pv->isEquivalentTo(
+ three_param.get(), IComparable::Criterion::EQUIVALENT));
+
+ EXPECT_FALSE(three_param->isEquivalentTo(
+ seven_param_non_eq.get(), IComparable::Criterion::EQUIVALENT));
+}