Skip to content

Commit

Permalink
Merge pull request #3883 from OSGeo/backport-3879-to-9.3
Browse files Browse the repository at this point in the history
[Backport 9.3] isEquivalentTo(): make a datum name 'unknown' equivalent to another one
  • Loading branch information
rouault authored Sep 6, 2023
2 parents fd5caa1 + 882376e commit 93868c1
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 34 deletions.
50 changes: 29 additions & 21 deletions src/iso19111/crs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,16 +636,18 @@ CRSNNPtr CRS::createBoundCRSToWGS84IfPossible(
auto geogCRS = extractGeographicCRS();
auto hubCRS = util::nn_static_pointer_cast<CRS>(GeographicCRS::EPSG_4326);
if (geodCRS && !geogCRS) {
if (geodCRS->_isEquivalentTo(GeographicCRS::EPSG_4978.get(),
if (geodCRS->datumNonNull(dbContext)->nameStr() != "unknown" &&
geodCRS->_isEquivalentTo(GeographicCRS::EPSG_4978.get(),
util::IComparable::Criterion::EQUIVALENT,
dbContext)) {
return thisAsCRS;
}
hubCRS = util::nn_static_pointer_cast<CRS>(GeodeticCRS::EPSG_4978);
} else if (!geogCRS ||
geogCRS->_isEquivalentTo(
GeographicCRS::EPSG_4326.get(),
util::IComparable::Criterion::EQUIVALENT, dbContext)) {
(geogCRS->datumNonNull(dbContext)->nameStr() != "unknown" &&
geogCRS->_isEquivalentTo(
GeographicCRS::EPSG_4326.get(),
util::IComparable::Criterion::EQUIVALENT, dbContext))) {
return thisAsCRS;
} else {
geodCRS = geogCRS;
Expand Down Expand Up @@ -2432,7 +2434,7 @@ void GeodeticCRS::addDatumInfoToPROJString(
const auto &nadgrids = formatter->getHDatumExtension();
const auto l_datum = datumNonNull(formatter->databaseContext());
if (formatter->getCRSExport() && TOWGS84Params.empty() &&
nadgrids.empty()) {
nadgrids.empty() && l_datum->nameStr() != "unknown") {
if (l_datum->_isEquivalentTo(
datum::GeodeticReferenceFrame::EPSG_6326.get(),
util::IComparable::Criterion::EQUIVALENT)) {
Expand Down Expand Up @@ -4846,22 +4848,28 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
const auto addCRS = [&](const ProjectedCRSNNPtr &crs, const bool eqName,
bool hasNonMatchingId) {
const auto &l_unit = cs->axisList()[0]->unit();
if (_isEquivalentTo(crs.get(),
util::IComparable::Criterion::
EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS,
dbContext) ||
(l_implicitCS &&
l_unit._isEquivalentTo(
crs->coordinateSystem()->axisList()[0]->unit(),
util::IComparable::Criterion::EQUIVALENT) &&
l_baseCRS->_isEquivalentTo(
crs->baseCRS().get(),
util::IComparable::Criterion::
EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS,
dbContext) &&
derivingConversionRef()->_isEquivalentTo(
crs->derivingConversionRef().get(),
util::IComparable::Criterion::EQUIVALENT, dbContext))) {
if ((_isEquivalentTo(crs.get(),
util::IComparable::Criterion::
EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS,
dbContext) ||
(l_implicitCS &&
l_unit._isEquivalentTo(
crs->coordinateSystem()->axisList()[0]->unit(),
util::IComparable::Criterion::EQUIVALENT) &&
l_baseCRS->_isEquivalentTo(
crs->baseCRS().get(),
util::IComparable::Criterion::
EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS,
dbContext) &&
derivingConversionRef()->_isEquivalentTo(
crs->derivingConversionRef().get(),
util::IComparable::Criterion::EQUIVALENT, dbContext))) &&
!((baseCRS()->datumNonNull(dbContext)->nameStr() == "unknown" &&
crs->baseCRS()->datumNonNull(dbContext)->nameStr() !=
"unknown") ||
(baseCRS()->datumNonNull(dbContext)->nameStr() != "unknown" &&
crs->baseCRS()->datumNonNull(dbContext)->nameStr() ==
"unknown"))) {
if (crs->nameStr() == thisName) {
res.clear();
res.emplace_back(crs, hasNonMatchingId ? 70 : 100);
Expand Down
3 changes: 3 additions & 0 deletions src/iso19111/datum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,9 @@ bool GeodeticReferenceFrame::_isEquivalentTo(
bool GeodeticReferenceFrame::hasEquivalentNameToUsingAlias(
const IdentifiedObject *other,
const io::DatabaseContextPtr &dbContext) const {
if (nameStr() == "unknown" || other->nameStr() == "unknown") {
return true;
}
if (dbContext) {
if (!identifiers().empty()) {
const auto &id = identifiers().front();
Expand Down
35 changes: 22 additions & 13 deletions src/iso19111/operation/coordinateoperationfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1946,6 +1946,20 @@ findCandidateGeodCRSForDatum(const io::AuthorityFactoryPtr &authFactory,

//! @cond Doxygen_Suppress

static bool
isSameGeodeticDatum(const datum::GeodeticReferenceFrameNNPtr &datum1,
const datum::GeodeticReferenceFrameNNPtr &datum2,
const io::DatabaseContextPtr &dbContext) {
if (datum1->nameStr() == "unknown" && datum2->nameStr() != "unknown")
return false;
if (datum2->nameStr() == "unknown" && datum1->nameStr() != "unknown")
return false;
return datum1->_isEquivalentTo(
datum2.get(), util::IComparable::Criterion::EQUIVALENT, dbContext);
}

// ---------------------------------------------------------------------------

// Look in the authority registry for operations from sourceCRS to targetCRS
// using an intermediate pivot
std::vector<CoordinateOperationNNPtr>
Expand Down Expand Up @@ -1985,10 +1999,7 @@ CoordinateOperationFactory::Private::findsOpsInRegistryWithIntermediate(
candidateSrcGeod->datumNonNull(dbContext);
const auto dstDatum = geodDst->datumNonNull(dbContext);
const bool sameGeodeticDatum =
srcDatum->_isEquivalentTo(
dstDatum.get(),
util::IComparable::Criterion::EQUIVALENT,
dbContext);
isSameGeodeticDatum(srcDatum, dstDatum, dbContext);
if (sameGeodeticDatum) {
continue;
}
Expand Down Expand Up @@ -2140,9 +2151,8 @@ createBallparkGeographicOffset(const crs::CRSNNPtr &sourceCRS,
dynamic_cast<const crs::GeographicCRS *>(targetCRS.get());
const bool isSameDatum =
geogSrc && geogDst &&
geogSrc->datumNonNull(dbContext)->_isEquivalentTo(
geogDst->datumNonNull(dbContext).get(),
util::IComparable::Criterion::EQUIVALENT, dbContext);
isSameGeodeticDatum(geogSrc->datumNonNull(dbContext),
geogDst->datumNonNull(dbContext), dbContext);

auto name = buildOpName(isSameDatum ? NULL_GEOGRAPHIC_OFFSET
: BALLPARK_GEOGRAPHIC_OFFSET,
Expand Down Expand Up @@ -2771,9 +2781,9 @@ CoordinateOperationFactory::Private::createOperationsGeogToGeog(
const auto dbContext =
authFactory ? authFactory->databaseContext().as_nullable() : nullptr;

const bool sameDatum = geogSrc->datumNonNull(dbContext)->_isEquivalentTo(
geogDst->datumNonNull(dbContext).get(),
util::IComparable::Criterion::EQUIVALENT, dbContext);
const bool sameDatum =
isSameGeodeticDatum(geogSrc->datumNonNull(dbContext),
geogDst->datumNonNull(dbContext), dbContext);

// Do the CRS differ by their axis order ?
bool axisReversal2D = false;
Expand Down Expand Up @@ -3675,9 +3685,8 @@ bool CoordinateOperationFactory::Private::createOperationsFromDatabase(

const auto srcDatum = geodSrc->datumNonNull(dbContext);
const auto dstDatum = geodDst->datumNonNull(dbContext);
sameGeodeticDatum = srcDatum->_isEquivalentTo(
dstDatum.get(), util::IComparable::Criterion::EQUIVALENT,
dbContext);

sameGeodeticDatum = isSameGeodeticDatum(srcDatum, dstDatum, dbContext);

if (res.empty() && !sameGeodeticDatum &&
!context.inCreateOperationsWithDatumPivotAntiRecursion) {
Expand Down
22 changes: 22 additions & 0 deletions test/unit/test_datum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,28 @@ TEST(datum, datum_with_ANCHOREPOCH) {

// ---------------------------------------------------------------------------

TEST(datum, unknown_datum) {
auto datum = GeodeticReferenceFrame::create(
PropertyMap().set(IdentifiedObject::NAME_KEY, "my_datum"),
Ellipsoid::GRS1980, optional<std::string>(), optional<Measure>(),
PrimeMeridian::GREENWICH);
auto unknown_datum = GeodeticReferenceFrame::create(
PropertyMap().set(IdentifiedObject::NAME_KEY, "unknown"),
Ellipsoid::GRS1980, optional<std::string>(), optional<Measure>(),
PrimeMeridian::GREENWICH);

EXPECT_FALSE(datum->isEquivalentTo(unknown_datum.get(),
IComparable::Criterion::STRICT));
EXPECT_TRUE(datum->isEquivalentTo(unknown_datum.get(),
IComparable::Criterion::EQUIVALENT));
EXPECT_FALSE(unknown_datum->isEquivalentTo(datum.get(),
IComparable::Criterion::STRICT));
EXPECT_TRUE(unknown_datum->isEquivalentTo(
datum.get(), IComparable::Criterion::EQUIVALENT));
}

// ---------------------------------------------------------------------------

TEST(datum, dynamic_geodetic_reference_frame) {
auto drf = DynamicGeodeticReferenceFrame::create(
PropertyMap().set(IdentifiedObject::NAME_KEY, "test"), Ellipsoid::WGS84,
Expand Down

0 comments on commit 93868c1

Please sign in to comment.