Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Pimenov <m@maps.me>2018-11-29 18:57:40 +0300
committerTatiana Yan <tatiana.kondakova@gmail.com>2018-11-30 12:49:34 +0300
commit2da498b417b254a853543f68ecfc99a611cce1a0 (patch)
tree8ee4abac2cf728d09c700ae19bfe790e43941ab2 /geocoder
parentb2d1f1cd3eb58740c7205c5a9d59eb2d10ad1413 (diff)
[geocoder] A fix for the mismatched locality class of errors.
Diffstat (limited to 'geocoder')
-rw-r--r--geocoder/geocoder.cpp45
-rw-r--r--geocoder/geocoder.hpp14
-rw-r--r--geocoder/geocoder_tests/geocoder_tests.cpp24
3 files changed, 73 insertions, 10 deletions
diff --git a/geocoder/geocoder.cpp b/geocoder/geocoder.cpp
index 112f59c625..f5df358702 100644
--- a/geocoder/geocoder.cpp
+++ b/geocoder/geocoder.cpp
@@ -115,6 +115,12 @@ size_t Geocoder::Context::GetNumUsedTokens() const
return m_numUsedTokens;
}
+Type Geocoder::Context::GetTokenType(size_t id) const
+{
+ CHECK_LESS(id, m_tokenTypes.size(), ());
+ return m_tokenTypes[id];
+}
+
string const & Geocoder::Context::GetToken(size_t id) const
{
CHECK_LESS(id, m_tokens.size(), ());
@@ -143,9 +149,9 @@ bool Geocoder::Context::IsTokenUsed(size_t id) const
bool Geocoder::Context::AllTokensUsed() const { return m_numUsedTokens == m_tokens.size(); }
void Geocoder::Context::AddResult(base::GeoObjectId const & osmId, double certainty, Type type,
- bool allTokensUsed)
+ vector<Type> && allTypes, bool allTokensUsed)
{
- m_beam.Add(BeamKey(osmId, type, allTokensUsed), certainty);
+ m_beam.Add(BeamKey(osmId, type, move(allTypes), allTokensUsed), certainty);
}
void Geocoder::Context::FillResults(vector<Result> & results) const
@@ -159,7 +165,25 @@ void Geocoder::Context::FillResults(vector<Result> & results) const
if (!seen.insert(e.m_key.m_osmId).second)
continue;
- if (m_surelyGotHouseNumber && e.m_key.m_type != Type::Building && !e.m_key.m_allTokensUsed)
+ bool isGoodHouseHumber = false;
+ if (e.m_key.m_type == Type::Building)
+ {
+ bool gotLocality = false;
+ bool gotStreet = false;
+ bool gotBuilding = false;
+ for (Type t : e.m_key.m_allTypes)
+ {
+ if (t == Type::Region || t == Type::Subregion || t == Type::Locality)
+ gotLocality = true;
+ if (t == Type::Street)
+ gotStreet = true;
+ if (t == Type::Building)
+ gotBuilding = true;
+ }
+ isGoodHouseHumber = gotLocality && gotStreet && gotBuilding;
+ }
+
+ if (m_surelyGotHouseNumber && !isGoodHouseHumber && !e.m_key.m_allTokensUsed)
continue;
results.emplace_back(e.m_key.m_osmId, e.m_value /* certainty */);
@@ -244,13 +268,20 @@ void Geocoder::Go(Context & ctx, Type type) const
ScopedMarkTokens mark(ctx, type, i, j + 1);
double certainty = 0;
- for (auto const t : ctx.GetTokenTypes())
+ vector<Type> allTypes;
+ for (size_t tokId = 0; tokId < ctx.GetNumTokens(); ++tokId)
+ {
+ if (search::IsStreetSynonym(strings::MakeUniString(ctx.GetToken(tokId))))
+ continue;
+
+ auto const t = ctx.GetTokenType(tokId);
certainty += GetWeight(t);
+ if (t != Type::Count)
+ allTypes.push_back(t);
+ }
for (auto const * e : curLayer.m_entries)
- {
- ctx.AddResult(e->m_osmId, certainty, type, ctx.AllTokensUsed());
- }
+ ctx.AddResult(e->m_osmId, certainty, type, move(allTypes), ctx.AllTokensUsed());
ctx.GetLayers().emplace_back(move(curLayer));
SCOPE_GUARD(pop, [&] { ctx.GetLayers().pop_back(); });
diff --git a/geocoder/geocoder.hpp b/geocoder/geocoder.hpp
index 131569a44e..4ff93fd3af 100644
--- a/geocoder/geocoder.hpp
+++ b/geocoder/geocoder.hpp
@@ -6,6 +6,7 @@
#include "geocoder/types.hpp"
#include "base/geo_object_id.hpp"
+#include "base/stl_helpers.hpp"
#include "base/string_utils.hpp"
#include <cstddef>
@@ -50,13 +51,18 @@ public:
public:
struct BeamKey
{
- BeamKey(base::GeoObjectId osmId, Type type, bool allTokensUsed)
- : m_osmId(osmId), m_type(type), m_allTokensUsed(allTokensUsed)
+ BeamKey(base::GeoObjectId osmId, Type type, std::vector<Type> && allTypes, bool allTokensUsed)
+ : m_osmId(osmId)
+ , m_type(type)
+ , m_allTypes(std::move(allTypes))
+ , m_allTokensUsed(allTokensUsed)
{
+ base::SortUnique(m_allTypes);
}
base::GeoObjectId m_osmId;
Type m_type;
+ std::vector<Type> m_allTypes;
bool m_allTokensUsed;
};
@@ -68,6 +74,8 @@ public:
size_t GetNumTokens() const;
size_t GetNumUsedTokens() const;
+ Type GetTokenType(size_t id) const;
+
std::string const & GetToken(size_t id) const;
void MarkToken(size_t id, Type type);
@@ -79,7 +87,7 @@ public:
bool AllTokensUsed() const;
void AddResult(base::GeoObjectId const & osmId, double certainty, Type type,
- bool allTokensUsed);
+ std::vector<Type> && allTypes, bool allTokensUsed);
void FillResults(std::vector<Result> & results) const;
diff --git a/geocoder/geocoder_tests/geocoder_tests.cpp b/geocoder/geocoder_tests/geocoder_tests.cpp
index d193ed2026..504dcf9b32 100644
--- a/geocoder/geocoder_tests/geocoder_tests.cpp
+++ b/geocoder/geocoder_tests/geocoder_tests.cpp
@@ -127,4 +127,28 @@ UNIT_TEST(Geocoder_OnlyBuildings)
TestGeocoder(geocoder, "some locality maybenumbered 3",
{{numberedStreet, 1.0}, {houseOnANonNumberedStreet, 0.8875}});
}
+
+UNIT_TEST(Geocoder_MismatchedLocality)
+{
+ string const kData = R"#(
+10 {"properties": {"address": {"locality": "Moscow"}}}
+11 {"properties": {"address": {"locality": "Paris"}}}
+
+21 {"properties": {"address": {"street": "Street", "locality": "Moscow"}}}
+22 {"properties": {"address": {"building": "2", "street": "Street", "locality": "Moscow"}}}
+
+31 {"properties": {"address": {"street": "Street", "locality": "Paris"}}}
+32 {"properties": {"address": {"building": "3", "street": "Street", "locality": "Paris"}}}
+)#";
+
+ ScopedFile const regionsJsonFile("regions.jsonl", kData);
+ Geocoder geocoder(regionsJsonFile.GetFullPath());
+
+ base::GeoObjectId const building2(22);
+
+ TestGeocoder(geocoder, "Moscow Street 2", {{building2, 1.0}});
+
+ // "Street 3" looks almost like a match to "Paris-Street-3" but we should not emit it.
+ TestGeocoder(geocoder, "Moscow Street 3", {});
+}
} // namespace geocoder