aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-11-28 02:08:06 +0100
committerGitHub <noreply@github.com>2020-11-28 02:08:06 +0100
commit5283d926f7c6a255c9046bc9ffbd6a48fce1600c (patch)
tree9404b91022e079de90b2f80b8e0f84dc8220f3ba
parent24c3bbb299798db775ef10101ee8aa76f8320bbf (diff)
parent4de6f0bd24051ed60d9c0a98dbba1da376457f12 (diff)
downloadPROJ-5283d926f7c6a255c9046bc9ffbd6a48fce1600c.tar.gz
PROJ-5283d926f7c6a255c9046bc9ffbd6a48fce1600c.zip
Merge pull request #2462 from rouault/improve_createObjectsFromName
createObjectsFromName(): in exact match, make looking for 'ETRS89 / UTM zone 32N' return only the exact match
-rw-r--r--src/iso19111/factory.cpp31
-rw-r--r--test/unit/test_factory.cpp6
2 files changed, 36 insertions, 1 deletions
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp
index 03fd5267..7c9eac00 100644
--- a/src/iso19111/factory.cpp
+++ b/src/iso19111/factory.cpp
@@ -6155,6 +6155,8 @@ AuthorityFactory::createObjectsFromNameEx(
auto sqlRes = d->run(sql, params);
bool isFirst = true;
bool firstIsDeprecated = false;
+ bool foundExactMatch = false;
+ std::size_t hashCodeFirstMatch = 0;
for (const auto &row : sqlRes) {
const auto &name = row[3];
if (approximateMatch) {
@@ -6242,11 +6244,38 @@ AuthorityFactory::createObjectsFromNameEx(
}
throw std::runtime_error("Unsupported table_name");
};
- res.emplace_back(PairObjectName(getObject(table_name, code), name));
+ const auto obj = getObject(table_name, code);
+ if (metadata::Identifier::canonicalizeName(obj->nameStr()) ==
+ canonicalizedSearchedName) {
+ foundExactMatch = true;
+ }
+
+ const auto objPtr = obj.get();
+ if (res.empty()) {
+ hashCodeFirstMatch = typeid(*objPtr).hash_code();
+ } else if (hashCodeFirstMatch != typeid(*objPtr).hash_code()) {
+ hashCodeFirstMatch = 0;
+ }
+
+ res.emplace_back(PairObjectName(obj, name));
if (limitResultCount > 0 && res.size() == limitResultCount) {
break;
}
}
+
+ // If we found a name that is an exact match, and all objects have the
+ // same type, and we are not in approximate mode, only keep the objet(s)
+ // with the exact name match.
+ if (foundExactMatch && hashCodeFirstMatch != 0 && !approximateMatch) {
+ std::list<PairObjectName> resTmp;
+ for (const auto &pair : res) {
+ if (metadata::Identifier::canonicalizeName(
+ pair.first->nameStr()) == canonicalizedSearchedName) {
+ resTmp.emplace_back(pair);
+ }
+ }
+ res = std::move(resTmp);
+ }
}
auto sortLambda = [](const PairObjectName &a, const PairObjectName &b) {
diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp
index 8e9b7ab6..ff86c4d3 100644
--- a/test/unit/test_factory.cpp
+++ b/test/unit/test_factory.cpp
@@ -3082,6 +3082,12 @@ TEST(factory, createObjectsFromName) {
.size(),
1U);
+ // Exact name, but with other CRS that have an aliases to it ==> should
+ // match only the CRS with the given name, not those other CRS.
+ EXPECT_EQ(factory->createObjectsFromName("ETRS89 / UTM zone 32N", {}, false)
+ .size(),
+ 1U);
+
// Prime meridian
EXPECT_EQ(factoryEPSG->createObjectsFromName("Paris", {}, false, 2).size(),
1U);