aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/datum.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/iso19111/datum.cpp')
-rw-r--r--src/iso19111/datum.cpp151
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;