aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);