aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2022-03-16 14:00:35 +0100
committergithub-actions[bot] <github-actions[bot]@users.noreply.github.com>2022-03-16 13:01:01 +0000
commit9296f97e45ace4afb574f93af8de0734cc34eae1 (patch)
tree427524ce97649db5fc9e014acc0d790911837255
parentcd8609b915bbcd2fe6948dbc30e248fb5dcefb55 (diff)
downloadPROJ-9296f97e45ace4afb574f93af8de0734cc34eae1.tar.gz
PROJ-9296f97e45ace4afb574f93af8de0734cc34eae1.zip
Merge pull request #3118 from rouault/dynamic_datum_isequivalentto
Fix comparison of GeodeticRefrenceFrame vs DynamicGeodeticReferenceFrame
-rw-r--r--include/proj/datum.hpp8
-rw-r--r--src/iso19111/datum.cpp61
-rw-r--r--test/unit/test_datum.cpp53
3 files changed, 114 insertions, 8 deletions
diff --git a/include/proj/datum.hpp b/include/proj/datum.hpp
index bf3dbcb7..ad388908 100644
--- a/include/proj/datum.hpp
+++ b/include/proj/datum.hpp
@@ -432,6 +432,10 @@ class PROJ_GCC_DLL GeodeticReferenceFrame : public Datum {
util::IComparable::Criterion criterion =
util::IComparable::Criterion::STRICT,
const io::DatabaseContextPtr &dbContext = nullptr) const override;
+
+ PROJ_INTERNAL bool isEquivalentToNoExactTypeCheck(
+ const util::IComparable *other, util::IComparable::Criterion criterion,
+ const io::DatabaseContextPtr &dbContext) const;
//! @endcond
protected:
@@ -587,6 +591,10 @@ class PROJ_GCC_DLL VerticalReferenceFrame : public Datum {
util::IComparable::Criterion::STRICT,
const io::DatabaseContextPtr &dbContext = nullptr) const override;
+ PROJ_INTERNAL bool isEquivalentToNoExactTypeCheck(
+ const util::IComparable *other, util::IComparable::Criterion criterion,
+ const io::DatabaseContextPtr &dbContext) const;
+
PROJ_INTERNAL void _exportToWKT(io::WKTFormatter *formatter)
const override; // throw(io::FormattingException)
diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp
index 7c76061e..758eaec3 100644
--- a/src/iso19111/datum.cpp
+++ b/src/iso19111/datum.cpp
@@ -1414,7 +1414,8 @@ void GeodeticReferenceFrame::_exportToJSON(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
-bool GeodeticReferenceFrame::_isEquivalentTo(
+
+bool GeodeticReferenceFrame::isEquivalentToNoExactTypeCheck(
const util::IComparable *other, util::IComparable::Criterion criterion,
const io::DatabaseContextPtr &dbContext) const {
auto otherGRF = dynamic_cast<const GeodeticReferenceFrame *>(other);
@@ -1427,6 +1428,19 @@ bool GeodeticReferenceFrame::_isEquivalentTo(
ellipsoid()->_isEquivalentTo(otherGRF->ellipsoid().get(), criterion,
dbContext);
}
+
+// ---------------------------------------------------------------------------
+
+bool GeodeticReferenceFrame::_isEquivalentTo(
+ const util::IComparable *other, util::IComparable::Criterion criterion,
+ const io::DatabaseContextPtr &dbContext) const {
+ if (criterion == Criterion::STRICT &&
+ !util::isOfExactType<GeodeticReferenceFrame>(*other)) {
+ return false;
+ }
+ return isEquivalentToNoExactTypeCheck(other, criterion, dbContext);
+}
+
//! @endcond
// ---------------------------------------------------------------------------
@@ -1558,11 +1572,20 @@ DynamicGeodeticReferenceFrame::deformationModelName() const {
bool DynamicGeodeticReferenceFrame::_isEquivalentTo(
const util::IComparable *other, util::IComparable::Criterion criterion,
const io::DatabaseContextPtr &dbContext) const {
- auto otherDGRF = dynamic_cast<const DynamicGeodeticReferenceFrame *>(other);
- if (otherDGRF == nullptr ||
- !GeodeticReferenceFrame::_isEquivalentTo(other, criterion, dbContext)) {
+ if (criterion == Criterion::STRICT &&
+ !util::isOfExactType<DynamicGeodeticReferenceFrame>(*other)) {
return false;
}
+ if (!GeodeticReferenceFrame::isEquivalentToNoExactTypeCheck(
+ other, criterion, dbContext)) {
+ return false;
+ }
+ auto otherDGRF = dynamic_cast<const DynamicGeodeticReferenceFrame *>(other);
+ if (otherDGRF == nullptr) {
+ // we can go here only if criterion != Criterion::STRICT, and thus
+ // given the above check we can consider the objects equivalent.
+ return true;
+ }
return frameReferenceEpoch()._isEquivalentTo(
otherDGRF->frameReferenceEpoch(), criterion) &&
metadata::Identifier::isEquivalentName(
@@ -2101,7 +2124,7 @@ void VerticalReferenceFrame::_exportToJSON(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
-bool VerticalReferenceFrame::_isEquivalentTo(
+bool VerticalReferenceFrame::isEquivalentToNoExactTypeCheck(
const util::IComparable *other, util::IComparable::Criterion criterion,
const io::DatabaseContextPtr &dbContext) const {
auto otherVRF = dynamic_cast<const VerticalReferenceFrame *>(other);
@@ -2121,6 +2144,19 @@ bool VerticalReferenceFrame::_isEquivalentTo(
}
return true;
}
+
+// ---------------------------------------------------------------------------
+
+bool VerticalReferenceFrame::_isEquivalentTo(
+ const util::IComparable *other, util::IComparable::Criterion criterion,
+ const io::DatabaseContextPtr &dbContext) const {
+ if (criterion == Criterion::STRICT &&
+ !util::isOfExactType<VerticalReferenceFrame>(*other)) {
+ return false;
+ }
+ return isEquivalentToNoExactTypeCheck(other, criterion, dbContext);
+}
+
//! @endcond
// ---------------------------------------------------------------------------
@@ -2195,11 +2231,20 @@ DynamicVerticalReferenceFrame::deformationModelName() const {
bool DynamicVerticalReferenceFrame::_isEquivalentTo(
const util::IComparable *other, util::IComparable::Criterion criterion,
const io::DatabaseContextPtr &dbContext) const {
- auto otherDGRF = dynamic_cast<const DynamicVerticalReferenceFrame *>(other);
- if (otherDGRF == nullptr ||
- !VerticalReferenceFrame::_isEquivalentTo(other, criterion, dbContext)) {
+ if (criterion == Criterion::STRICT &&
+ !util::isOfExactType<DynamicVerticalReferenceFrame>(*other)) {
return false;
}
+ if (!VerticalReferenceFrame::isEquivalentToNoExactTypeCheck(
+ other, criterion, dbContext)) {
+ return false;
+ }
+ auto otherDGRF = dynamic_cast<const DynamicVerticalReferenceFrame *>(other);
+ if (otherDGRF == nullptr) {
+ // we can go here only if criterion != Criterion::STRICT, and thus
+ // given the above check we can consider the objects equivalent.
+ return true;
+ }
return frameReferenceEpoch()._isEquivalentTo(
otherDGRF->frameReferenceEpoch(), criterion) &&
metadata::Identifier::isEquivalentName(
diff --git a/test/unit/test_datum.cpp b/test/unit/test_datum.cpp
index 26098d5c..457bde4d 100644
--- a/test/unit/test_datum.cpp
+++ b/test/unit/test_datum.cpp
@@ -287,6 +287,33 @@ TEST(datum, dynamic_geodetic_reference_frame) {
drf->exportToWKT(
WKTFormatter::create(WKTFormatter::Convention::WKT2_2019).get()),
expected_wtk2_2019);
+
+ EXPECT_TRUE(drf->isEquivalentTo(drf.get()));
+ EXPECT_TRUE(
+ drf->isEquivalentTo(drf.get(), IComparable::Criterion::EQUIVALENT));
+ EXPECT_FALSE(drf->isEquivalentTo(createUnrelatedObject().get()));
+
+ // "Same" datum, except that it is a non-dynamic one
+ auto datum = GeodeticReferenceFrame::create(
+ PropertyMap().set(IdentifiedObject::NAME_KEY, "test"), Ellipsoid::WGS84,
+ optional<std::string>("My anchor"), PrimeMeridian::GREENWICH);
+ EXPECT_FALSE(datum->isEquivalentTo(drf.get()));
+ EXPECT_FALSE(drf->isEquivalentTo(datum.get()));
+ EXPECT_TRUE(
+ datum->isEquivalentTo(drf.get(), IComparable::Criterion::EQUIVALENT));
+ EXPECT_TRUE(
+ drf->isEquivalentTo(datum.get(), IComparable::Criterion::EQUIVALENT));
+
+ auto unrelated_datum = GeodeticReferenceFrame::create(
+ PropertyMap().set(IdentifiedObject::NAME_KEY, "test2"),
+ Ellipsoid::WGS84, optional<std::string>("My anchor"),
+ PrimeMeridian::GREENWICH);
+ EXPECT_FALSE(unrelated_datum->isEquivalentTo(drf.get()));
+ EXPECT_FALSE(drf->isEquivalentTo(unrelated_datum.get()));
+ EXPECT_FALSE(unrelated_datum->isEquivalentTo(
+ drf.get(), IComparable::Criterion::EQUIVALENT));
+ EXPECT_FALSE(drf->isEquivalentTo(unrelated_datum.get(),
+ IComparable::Criterion::EQUIVALENT));
}
// ---------------------------------------------------------------------------
@@ -395,6 +422,32 @@ TEST(datum, dynamic_vertical_reference_frame) {
drf->exportToWKT(
WKTFormatter::create(WKTFormatter::Convention::WKT2_2019).get()),
expected_wtk2_2019);
+
+ EXPECT_TRUE(drf->isEquivalentTo(drf.get()));
+ EXPECT_TRUE(
+ drf->isEquivalentTo(drf.get(), IComparable::Criterion::EQUIVALENT));
+ EXPECT_FALSE(drf->isEquivalentTo(createUnrelatedObject().get()));
+
+ // "Same" datum, except that it is a non-dynamic one
+ auto datum = VerticalReferenceFrame::create(
+ PropertyMap().set(IdentifiedObject::NAME_KEY, "test"),
+ optional<std::string>("My anchor"), optional<RealizationMethod>());
+ EXPECT_FALSE(datum->isEquivalentTo(drf.get()));
+ EXPECT_FALSE(drf->isEquivalentTo(datum.get()));
+ EXPECT_TRUE(
+ datum->isEquivalentTo(drf.get(), IComparable::Criterion::EQUIVALENT));
+ EXPECT_TRUE(
+ drf->isEquivalentTo(datum.get(), IComparable::Criterion::EQUIVALENT));
+
+ auto unrelated_datum = VerticalReferenceFrame::create(
+ PropertyMap().set(IdentifiedObject::NAME_KEY, "test2"),
+ optional<std::string>("My anchor"), optional<RealizationMethod>());
+ EXPECT_FALSE(unrelated_datum->isEquivalentTo(drf.get()));
+ EXPECT_FALSE(drf->isEquivalentTo(unrelated_datum.get()));
+ EXPECT_FALSE(unrelated_datum->isEquivalentTo(
+ drf.get(), IComparable::Criterion::EQUIVALENT));
+ EXPECT_FALSE(drf->isEquivalentTo(unrelated_datum.get(),
+ IComparable::Criterion::EQUIVALENT));
}
// ---------------------------------------------------------------------------