diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-05-14 00:25:42 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-14 00:25:42 +0200 |
| commit | 0c9cf39297a24d5e56aa488820a5ba3edaace90e (patch) | |
| tree | f277183066a322b4ebf09c8d0192f569b1b8d108 /src | |
| parent | 475e7fd9f11af184e7e1e1618b3e1bb110a79714 (diff) | |
| parent | 4e9d559d6c1cdb2ea9ace5894088b26332ad9a42 (diff) | |
| download | PROJ-0c9cf39297a24d5e56aa488820a5ba3edaace90e.tar.gz PROJ-0c9cf39297a24d5e56aa488820a5ba3edaace90e.zip | |
Merge pull request #2215 from rouault/fix_2214
ProjectedCRS::identify(): fix identification of EPSG:3059 (fixes #2214)
Diffstat (limited to 'src')
| -rw-r--r-- | src/iso19111/c_api.cpp | 4 | ||||
| -rw-r--r-- | src/iso19111/crs.cpp | 136 |
2 files changed, 72 insertions, 68 deletions
diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 200ac454..340d9fb9 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -2236,8 +2236,8 @@ PJ *proj_get_target_crs(PJ_CONTEXT *ctx, const PJ *obj) { * </li> * <li>90% means that CRS are equivalent, but the names are not exactly the * same.</li> - * <li>70% means that CRS are equivalent), but the names do not match at - * all.</li> + * <li>70% means that CRS are equivalent, but the names are not equivalent. + * </li> * <li>25% means that the CRS are not equivalent, but there is some similarity * in * the names.</li> diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index de02eb35..c23bd29b 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1703,7 +1703,7 @@ static bool hasCodeCompatibleOfAuthorityFactory( * same. * <li>70% means that CRS are equivalent (equivalent datum and coordinate * system), - * but the names do not match at all.</li> + * but the names are not equivalent.</li> * <li>60% means that ellipsoid, prime meridian and coordinate systems are * equivalent, but the CRS and datum names do not match.</li> * <li>25% means that the CRS are not equivalent, but there is some similarity @@ -2808,7 +2808,7 @@ bool VerticalCRS::_isEquivalentTo( * single result is returned. * 90% means that CRS are equivalent, but the names are not exactly the same. * 70% means that CRS are equivalent (equivalent datum and coordinate system), - * but the names do not match at all. + * but the names are not equivalent. * 25% means that the CRS are not equivalent, but there is some similarity in * the names. * @@ -3630,8 +3630,11 @@ void ProjectedCRS::addUnitConvertAndAxisSwap(io::PROJStringFormatter *formatter, * single result is returned. * 90% means that CRS are equivalent, but the names are not exactly the same. * 70% means that CRS are equivalent (equivalent base CRS, conversion and - * coordinate system), but the names do not match at all. - * 50% means that CRS have similarity (equivalent base CRS and conversion), + * coordinate system), but the names are not equivalent. + * 60% means that CRS have strong similarity (equivalent base datum, conversion + * and coordinate system), but the names are not equivalent. + * 50% means that CRS have similarity (equivalent base ellipsoid and + * conversion), * but the coordinate system do not match (e.g. different axis ordering or * axis unit). * 25% means that the CRS are not equivalent, but there is some similarity in @@ -3655,6 +3658,11 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { std::list<std::pair<GeodeticCRSNNPtr, int>> baseRes; const auto &l_baseCRS(baseCRS()); + const auto l_datum = l_baseCRS->datum(); + const bool significantNameForDatum = + l_datum != nullptr && !ci_starts_with(l_datum->nameStr(), "unknown") && + l_datum->nameStr() != "unnamed"; + const auto &ellipsoid = l_baseCRS->ellipsoid(); auto geogCRS = dynamic_cast<const GeographicCRS *>(l_baseCRS.get()); if (geogCRS && geogCRS->coordinateSystem()->axisOrder() == @@ -3742,6 +3750,59 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { } } + const bool l_implicitCS = CRS::getPrivate()->implicitCS_; + const auto addCRS = [&](const ProjectedCRSNNPtr &crs, const bool eqName) { + 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 (crs->nameStr() == thisName) { + res.clear(); + res.emplace_back(crs, 100); + } else { + res.emplace_back(crs, eqName ? 90 : 70); + } + } else if (ellipsoid->_isEquivalentTo( + crs->baseCRS()->ellipsoid().get(), + util::IComparable::Criterion::EQUIVALENT, dbContext) && + derivingConversionRef()->_isEquivalentTo( + crs->derivingConversionRef().get(), + util::IComparable::Criterion::EQUIVALENT, dbContext)) { + if ((l_implicitCS && + l_unit._isEquivalentTo( + crs->coordinateSystem()->axisList()[0]->unit(), + util::IComparable::Criterion::EQUIVALENT)) || + cs->_isEquivalentTo(crs->coordinateSystem().get(), + util::IComparable::Criterion::EQUIVALENT, + dbContext)) { + if (!significantNameForDatum || + (crs->baseCRS()->datum() && + l_datum->_isEquivalentTo( + crs->baseCRS()->datum().get(), + util::IComparable::Criterion::EQUIVALENT))) { + res.emplace_back(crs, 70); + } else { + res.emplace_back(crs, 60); + } + } else { + res.emplace_back(crs, 50); + } + } else { + res.emplace_back(crs, 25); + } + }; + if (authorityFactory) { const bool unsignificantName = thisName.empty() || @@ -3782,43 +3843,10 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { const bool eqName = metadata::Identifier::isEquivalentName( thisName.c_str(), crs->nameStr().c_str()); foundEquivalentName |= eqName; - if (_isEquivalentTo( - crs.get(), util::IComparable::Criterion:: - EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS, - dbContext)) { - if (crs->nameStr() == thisName) { - res.clear(); - res.emplace_back(crsNN, 100); - return res; - } - res.emplace_back(crsNN, eqName ? 90 : 70); - } else if (objects.size() == 1 && - CRS::getPrivate()->implicitCS_ && - coordinateSystem() - ->axisList()[0] - ->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)) { - res.clear(); - res.emplace_back(crsNN, crs->nameStr() == thisName - ? 100 - : eqName ? 90 : 70); + + addCRS(crsNN, eqName); + if (res.back().second == 100) { return res; - } else { - res.emplace_back(crsNN, 25); } } if (!res.empty()) { @@ -3867,7 +3895,6 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { shared_from_this().as_nullable())); auto candidates = authorityFactory->createProjectedCRSFromExisting(self); - const auto &ellipsoid = l_baseCRS->ellipsoid(); for (const auto &crs : candidates) { const auto &ids = crs->identifiers(); assert(!ids.empty()); @@ -3877,30 +3904,7 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { continue; } - if (_isEquivalentTo(crs.get(), - util::IComparable::Criterion:: - EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS, - dbContext)) { - res.emplace_back(crs, unsignificantName ? 90 : 70); - } else if (ellipsoid->_isEquivalentTo( - crs->baseCRS()->ellipsoid().get(), - util::IComparable::Criterion::EQUIVALENT, - dbContext) && - derivingConversionRef()->_isEquivalentTo( - crs->derivingConversionRef().get(), - util::IComparable::Criterion::EQUIVALENT, - dbContext)) { - if (coordinateSystem()->_isEquivalentTo( - crs->coordinateSystem().get(), - util::IComparable::Criterion::EQUIVALENT, - dbContext)) { - res.emplace_back(crs, 70); - } else { - res.emplace_back(crs, 50); - } - } else { - res.emplace_back(crs, 25); - } + addCRS(crs, unsignificantName); } res.sort(lambdaSort); @@ -4293,7 +4297,7 @@ bool CompoundCRS::_isEquivalentTo( * single result is returned. * 90% means that CRS are equivalent, but the names are not exactly the same. * 70% means that CRS are equivalent (equivalent horizontal and vertical CRS), - * but the names do not match at all. + * but the names are not equivalent. * 25% means that the CRS are not equivalent, but there is some similarity in * the names. * |
