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:
authorAnatoly Serdtcev <serdtcev@maps.me>2019-02-01 16:42:33 +0300
committerSergey Yershov <syershov@maps.me>2019-02-04 13:55:58 +0300
commitfaeee82dd69f54b3265d14a64f9cc985467ba0a9 (patch)
tree39fabef3723bf36f9a77d21eaf594f5c2f0f5074 /geocoder
parentcf62483dc641d8d3ce59386e211b2463c7a69039 (diff)
[geocoder] Search locality buildings
Diffstat (limited to 'geocoder')
-rw-r--r--geocoder/geocoder.cpp36
-rw-r--r--geocoder/geocoder.hpp2
-rw-r--r--geocoder/geocoder_tests/geocoder_tests.cpp19
-rw-r--r--geocoder/index.cpp19
4 files changed, 54 insertions, 22 deletions
diff --git a/geocoder/geocoder.cpp b/geocoder/geocoder.cpp
index 96c6b808bf..ae008bd693 100644
--- a/geocoder/geocoder.cpp
+++ b/geocoder/geocoder.cpp
@@ -287,30 +287,32 @@ void Geocoder::FillBuildingsLayer(Context & ctx, Tokens const & subquery, Layer
{
if (ctx.GetLayers().empty())
return;
- auto const & layer = ctx.GetLayers().back();
- if (layer.m_type != Type::Street)
- return;
auto const & subqueryHN = MakeHouseNumber(subquery);
if (!search::house_numbers::LooksLikeHouseNumber(subqueryHN, false /* isPrefix */))
return;
- // We've already filled a street layer and now see something that resembles
- // a house number. While it still can be something else (a zip code, for example)
- // let's stay on the safer side and set the house number bit.
- ctx.SetHouseNumberBit();
+ for_each(ctx.GetLayers().rbegin(), ctx.GetLayers().rend(), [&, this] (auto const & layer) {
+ if (layer.m_type != Type::Street && layer.m_type != Type::Locality)
+ return;
- for (auto const & streetDocId : layer.m_entries)
- {
- m_index.ForEachBuildingOnStreet(streetDocId, [&](Index::DocId const & buildingDocId) {
- auto const & bld = m_index.GetDoc(buildingDocId);
- auto const bt = static_cast<size_t>(Type::Building);
- auto const & realHN = MakeHouseNumber(bld.m_address[bt]);
- if (search::house_numbers::HouseNumbersMatch(realHN, subqueryHN, false /* queryIsPrefix */))
- curLayer.m_entries.emplace_back(buildingDocId);
- });
- }
+ // We've already filled a street/location layer and now see something that resembles
+ // a house number. While it still can be something else (a zip code, for example)
+ // let's stay on the safer side and set the house number bit.
+ ctx.SetHouseNumberBit();
+
+ for (auto const & streetDocId : layer.m_entries)
+ {
+ m_index.ForEachBuildingOnStreet(streetDocId, [&](Index::DocId const & buildingDocId) {
+ auto const & bld = m_index.GetDoc(buildingDocId);
+ auto const bt = static_cast<size_t>(Type::Building);
+ auto const & realHN = MakeHouseNumber(bld.m_address[bt]);
+ if (search::house_numbers::HouseNumbersMatch(realHN, subqueryHN, false /* queryIsPrefix */))
+ curLayer.m_entries.emplace_back(buildingDocId);
+ });
+ }
+ });
}
void Geocoder::FillRegularLayer(Context const & ctx, Type type, Tokens const & subquery,
diff --git a/geocoder/geocoder.hpp b/geocoder/geocoder.hpp
index 42fe749050..a829fbaa0f 100644
--- a/geocoder/geocoder.hpp
+++ b/geocoder/geocoder.hpp
@@ -55,7 +55,7 @@ public:
BeamKey(base::GeoObjectId osmId, Type type, std::vector<Type> const & allTypes, bool allTokensUsed)
: m_osmId(osmId)
, m_type(type)
- , m_allTypes(std::move(allTypes))
+ , m_allTypes(allTypes)
, m_allTokensUsed(allTokensUsed)
{
base::SortUnique(m_allTypes);
diff --git a/geocoder/geocoder_tests/geocoder_tests.cpp b/geocoder/geocoder_tests/geocoder_tests.cpp
index 58c951e9fa..c583598bbe 100644
--- a/geocoder/geocoder_tests/geocoder_tests.cpp
+++ b/geocoder/geocoder_tests/geocoder_tests.cpp
@@ -151,4 +151,23 @@ UNIT_TEST(Geocoder_MismatchedLocality)
// "Street 3" looks almost like a match to "Paris-Street-3" but we should not emit it.
TestGeocoder(geocoder, "Moscow Street 3", {});
}
+
+UNIT_TEST(Geocoder_LocalityBuilding)
+{
+ string const kData = R"#(
+10 {"properties": {"address": {"locality": "Zelenograd"}}}
+
+22 {"properties": {"address": {"building": "2", "locality": "Zelenograd"}}}
+
+31 {"properties": {"address": {"street": "Street", "locality": "Zelenograd"}}}
+32 {"properties": {"address": {"building": "2", "street": "Street", "locality": "Zelenograd"}}}
+)#";
+
+ ScopedFile const regionsJsonFile("regions.jsonl", kData);
+ Geocoder geocoder(regionsJsonFile.GetFullPath());
+
+ base::GeoObjectId const building2(22);
+
+ TestGeocoder(geocoder, "Zelenograd 2", {{building2, 1.0}});
+}
} // namespace geocoder
diff --git a/geocoder/index.cpp b/geocoder/index.cpp
index 7602fd7777..e18a1ab6e1 100644
--- a/geocoder/index.cpp
+++ b/geocoder/index.cpp
@@ -99,13 +99,24 @@ void Index::AddHouses()
if (buildingDoc.m_type != Type::Building)
continue;
- size_t const t = static_cast<size_t>(Type::Street);
+ auto const & street = buildingDoc.m_address[static_cast<size_t>(Type::Street)];
+ auto const & locality = buildingDoc.m_address[static_cast<size_t>(Type::Locality)];
- ForEachDocId(buildingDoc.m_address[t], [&](DocId const & streetCandidate) {
- auto const & streetDoc = GetDoc(streetCandidate);
+ Tokens const * buildingPlace = nullptr;
+
+ if (!street.empty())
+ buildingPlace = &street;
+ else if (!locality.empty())
+ buildingPlace = &locality;
+
+ if (!buildingPlace)
+ continue;
+
+ ForEachDocId(*buildingPlace, [&](DocId const & placeCandidate) {
+ auto const & streetDoc = GetDoc(placeCandidate);
if (streetDoc.IsParentTo(buildingDoc))
{
- m_buildingsOnStreet[streetCandidate].emplace_back(docId);
+ m_buildingsOnStreet[placeCandidate].emplace_back(docId);
++numIndexed;
if (numIndexed % kLogBatch == 0)