diff options
Diffstat (limited to 'src/iso19111/datum.cpp')
| -rw-r--r-- | src/iso19111/datum.cpp | 151 |
1 files changed, 114 insertions, 37 deletions
diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 321fe93f..d9d9c261 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -213,11 +213,13 @@ void Datum::setProperties( // --------------------------------------------------------------------------- -bool Datum::__isEquivalentTo(const util::IComparable *other, - util::IComparable::Criterion criterion) const { +//! @cond Doxygen_Suppress +bool Datum::_isEquivalentTo(const util::IComparable *other, + util::IComparable::Criterion criterion, + const io::DatabaseContextPtr &dbContext) const { auto otherDatum = dynamic_cast<const Datum *>(other); if (otherDatum == nullptr || - !ObjectUsage::_isEquivalentTo(other, criterion)) { + !ObjectUsage::_isEquivalentTo(other, criterion, dbContext)) { return false; } if (criterion == util::IComparable::Criterion::STRICT) { @@ -248,12 +250,13 @@ bool Datum::__isEquivalentTo(const util::IComparable *other, } if (conventionalRS() && otherDatum->conventionalRS() && conventionalRS()->_isEquivalentTo( - otherDatum->conventionalRS().get(), criterion)) { + otherDatum->conventionalRS().get(), criterion, dbContext)) { return false; } } return true; } +//! @endcond // --------------------------------------------------------------------------- @@ -450,11 +453,11 @@ void PrimeMeridian::_exportToPROJString( //! @cond Doxygen_Suppress bool PrimeMeridian::_isEquivalentTo( - const util::IComparable *other, - util::IComparable::Criterion criterion) const { + const util::IComparable *other, util::IComparable::Criterion criterion, + const io::DatabaseContextPtr &dbContext) const { auto otherPM = dynamic_cast<const PrimeMeridian *>(other); if (otherPM == nullptr || - !IdentifiedObject::_isEquivalentTo(other, criterion)) { + !IdentifiedObject::_isEquivalentTo(other, criterion, dbContext)) { return false; } // In MapInfo, the Paris prime meridian is returned as 2.3372291666667 @@ -984,11 +987,12 @@ EllipsoidNNPtr Ellipsoid::identify() const { //! @cond Doxygen_Suppress bool Ellipsoid::_isEquivalentTo(const util::IComparable *other, - util::IComparable::Criterion criterion) const { + util::IComparable::Criterion criterion, + const io::DatabaseContextPtr &dbContext) const { auto otherEllipsoid = dynamic_cast<const Ellipsoid *>(other); if (otherEllipsoid == nullptr || (criterion == util::IComparable::Criterion::STRICT && - !IdentifiedObject::_isEquivalentTo(other, criterion))) { + !IdentifiedObject::_isEquivalentTo(other, criterion, dbContext))) { return false; } @@ -1197,7 +1201,8 @@ void GeodeticReferenceFrame::_exportToWKT( io::WKTFormatter *formatter) const // throw(FormattingException) { const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2; - formatter->startNode(io::WKTConstants::DATUM, !identifiers().empty()); + const auto &ids = identifiers(); + formatter->startNode(io::WKTConstants::DATUM, !ids.empty()); auto l_name = nameStr(); if (l_name.empty()) { l_name = "unnamed"; @@ -1232,10 +1237,35 @@ void GeodeticReferenceFrame::_exportToWKT( } } } - // Replace spaces by underscore, except if it is a special MapInfo - // datum name - } else if (!starts_with(l_name, "MIF ")) { - l_name = io::WKTFormatter::morphNameToESRI(l_name); + } else { + // Replace spaces by underscore for datum names coming from EPSG + // so as to emulate GDAL < 3 importFromEPSG() + if (ids.size() == 1 && *(ids.front()->codeSpace()) == "EPSG") { + l_name = io::WKTFormatter::morphNameToESRI(l_name); + } else if (ids.empty()) { + const auto &dbContext = formatter->databaseContext(); + if (dbContext) { + auto factory = io::AuthorityFactory::create( + NN_NO_CHECK(dbContext), std::string()); + // We use anonymous autority and approximate matching, so + // as to trigger the caching done in createObjectsFromName() + // in that case. + auto matches = factory->createObjectsFromName( + l_name, {io::AuthorityFactory::ObjectType:: + GEODETIC_REFERENCE_FRAME}, + true, 2); + if (matches.size() == 1) { + const auto &match = matches.front(); + const auto &matchId = match->identifiers(); + if (matchId.size() == 1 && + *(matchId.front()->codeSpace()) == "EPSG" && + metadata::Identifier::isEquivalentName( + l_name.c_str(), match->nameStr().c_str())) { + l_name = io::WKTFormatter::morphNameToESRI(l_name); + } + } + } + } if (l_name == "World_Geodetic_System_1984") { l_name = "WGS_1984"; } @@ -1324,20 +1354,63 @@ void GeodeticReferenceFrame::_exportToJSON( //! @cond Doxygen_Suppress bool GeodeticReferenceFrame::_isEquivalentTo( - const util::IComparable *other, - util::IComparable::Criterion criterion) const { + const util::IComparable *other, util::IComparable::Criterion criterion, + const io::DatabaseContextPtr &dbContext) const { auto otherGRF = dynamic_cast<const GeodeticReferenceFrame *>(other); - if (otherGRF == nullptr || !Datum::_isEquivalentTo(other, criterion)) { + if (otherGRF == nullptr || + !Datum::_isEquivalentTo(other, criterion, dbContext)) { return false; } return primeMeridian()->_isEquivalentTo(otherGRF->primeMeridian().get(), - criterion) && - ellipsoid()->_isEquivalentTo(otherGRF->ellipsoid().get(), criterion); + criterion, dbContext) && + ellipsoid()->_isEquivalentTo(otherGRF->ellipsoid().get(), criterion, + dbContext); } //! @endcond // --------------------------------------------------------------------------- +bool GeodeticReferenceFrame::hasEquivalentNameToUsingAlias( + const IdentifiedObject *other, + const io::DatabaseContextPtr &dbContext) const { + if (dbContext) { + if (!identifiers().empty()) { + const auto &id = identifiers().front(); + auto aliases = + dbContext->getAliases(*(id->codeSpace()), id->code(), nameStr(), + "geodetic_datum", std::string()); + const char *otherName = other->nameStr().c_str(); + for (const auto &alias : aliases) { + if (metadata::Identifier::isEquivalentName(otherName, + alias.c_str())) { + return true; + } + } + return false; + } else if (!other->identifiers().empty()) { + auto otherGRF = dynamic_cast<const GeodeticReferenceFrame *>(other); + if (otherGRF) { + return otherGRF->hasEquivalentNameToUsingAlias(this, dbContext); + } + return false; + } + + auto aliases = + dbContext->getAliases(std::string(), std::string(), nameStr(), + "geodetic_datum", std::string()); + const char *otherName = other->nameStr().c_str(); + for (const auto &alias : aliases) { + if (metadata::Identifier::isEquivalentName(otherName, + alias.c_str())) { + return true; + } + } + } + return false; +} + +// --------------------------------------------------------------------------- + //! @cond Doxygen_Suppress struct DynamicGeodeticReferenceFrame::Private { common::Measure frameReferenceEpoch{}; @@ -1407,11 +1480,11 @@ DynamicGeodeticReferenceFrame::deformationModelName() const { //! @cond Doxygen_Suppress bool DynamicGeodeticReferenceFrame::_isEquivalentTo( - const util::IComparable *other, - util::IComparable::Criterion criterion) const { + 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)) { + !GeodeticReferenceFrame::_isEquivalentTo(other, criterion, dbContext)) { return false; } return frameReferenceEpoch()._isEquivalentTo( @@ -1842,10 +1915,11 @@ void VerticalReferenceFrame::_exportToJSON( //! @cond Doxygen_Suppress bool VerticalReferenceFrame::_isEquivalentTo( - const util::IComparable *other, - util::IComparable::Criterion criterion) const { + const util::IComparable *other, util::IComparable::Criterion criterion, + const io::DatabaseContextPtr &dbContext) const { auto otherVRF = dynamic_cast<const VerticalReferenceFrame *>(other); - if (otherVRF == nullptr || !Datum::_isEquivalentTo(other, criterion)) { + if (otherVRF == nullptr || + !Datum::_isEquivalentTo(other, criterion, dbContext)) { return false; } if ((realizationMethod().has_value() ^ @@ -1932,11 +2006,11 @@ DynamicVerticalReferenceFrame::deformationModelName() const { //! @cond Doxygen_Suppress bool DynamicVerticalReferenceFrame::_isEquivalentTo( - const util::IComparable *other, - util::IComparable::Criterion criterion) const { + 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)) { + !VerticalReferenceFrame::_isEquivalentTo(other, criterion, dbContext)) { return false; } return frameReferenceEpoch()._isEquivalentTo( @@ -2131,10 +2205,11 @@ void TemporalDatum::_exportToJSON( //! @cond Doxygen_Suppress bool TemporalDatum::_isEquivalentTo( - const util::IComparable *other, - util::IComparable::Criterion criterion) const { + const util::IComparable *other, util::IComparable::Criterion criterion, + const io::DatabaseContextPtr &dbContext) const { auto otherTD = dynamic_cast<const TemporalDatum *>(other); - if (otherTD == nullptr || !Datum::_isEquivalentTo(other, criterion)) { + if (otherTD == nullptr || + !Datum::_isEquivalentTo(other, criterion, dbContext)) { return false; } return temporalOrigin().toString() == @@ -2223,10 +2298,11 @@ void EngineeringDatum::_exportToJSON( //! @cond Doxygen_Suppress bool EngineeringDatum::_isEquivalentTo( - const util::IComparable *other, - util::IComparable::Criterion criterion) const { + const util::IComparable *other, util::IComparable::Criterion criterion, + const io::DatabaseContextPtr &dbContext) const { auto otherTD = dynamic_cast<const EngineeringDatum *>(other); - if (otherTD == nullptr || !Datum::_isEquivalentTo(other, criterion)) { + if (otherTD == nullptr || + !Datum::_isEquivalentTo(other, criterion, dbContext)) { return false; } return true; @@ -2308,10 +2384,11 @@ void ParametricDatum::_exportToJSON( //! @cond Doxygen_Suppress bool ParametricDatum::_isEquivalentTo( - const util::IComparable *other, - util::IComparable::Criterion criterion) const { + const util::IComparable *other, util::IComparable::Criterion criterion, + const io::DatabaseContextPtr &dbContext) const { auto otherTD = dynamic_cast<const ParametricDatum *>(other); - if (otherTD == nullptr || !Datum::_isEquivalentTo(other, criterion)) { + if (otherTD == nullptr || + !Datum::_isEquivalentTo(other, criterion, dbContext)) { return false; } return true; |
