diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2022-03-16 14:00:35 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-16 14:00:35 +0100 |
| commit | 1c1a3c5930229644440a7e41d032cc217cf2f8c0 (patch) | |
| tree | f0d089ce5146dad01d0d2d7db046bc61315cf169 | |
| parent | 77751f6c9e023748a90793774e8e4b554515e8b5 (diff) | |
| parent | fdf5111a9a790926aacec75a07d30508a8ed9c91 (diff) | |
| download | PROJ-1c1a3c5930229644440a7e41d032cc217cf2f8c0.tar.gz PROJ-1c1a3c5930229644440a7e41d032cc217cf2f8c0.zip | |
Merge pull request #3118 from rouault/dynamic_datum_isequivalentto
Fix comparison of GeodeticRefrenceFrame vs DynamicGeodeticReferenceFrame
| -rw-r--r-- | include/proj/datum.hpp | 8 | ||||
| -rw-r--r-- | src/iso19111/datum.cpp | 61 | ||||
| -rw-r--r-- | test/unit/test_datum.cpp | 53 |
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)); } // --------------------------------------------------------------------------- |
