From 3bf670236fd979f196ed09eb55f050bb7edb354f Mon Sep 17 00:00:00 2001 From: tatiana-yan Date: Thu, 24 Jan 2019 16:21:28 +0300 Subject: [PATCH] [search] Use squares and suburbs as streets in geocoder. --- data/categories.txt | 4 ++-- generator/search_index_builder.cpp | 2 +- indexer/ftypes_matcher.cpp | 12 +++++++++++- indexer/ftypes_matcher.hpp | 18 +++++++++++++++--- indexer/indexer_tests/checker_test.cpp | 10 +++++----- search/categories_cache.cpp | 2 +- search/intermediate_result.cpp | 5 +---- search/model.cpp | 2 +- search/reverse_geocoder.cpp | 2 +- search/search_integration_tests/smoke_test.cpp | 1 + search/search_tests/house_detector_tests.cpp | 2 +- search/street_vicinity_loader.cpp | 16 ++++++++++++++-- 12 files changed, 54 insertions(+), 22 deletions(-) diff --git a/data/categories.txt b/data/categories.txt index 4447fe59bb..dbc5d5ab56 100644 --- a/data/categories.txt +++ b/data/categories.txt @@ -4168,7 +4168,7 @@ sk:^Ostrov sw:^Kisiwa fa:جزیره -place-suburb +place-suburb|landuse-residential|place-neighbourhood en:^Suburb|district ru:^Район|микрорайон|округ|квартал ar:^حي سكني|ضاحية @@ -5966,7 +5966,7 @@ el:^Ράφτης|ράπτης sk:^Krajčírstvo fa:خیاطی -area:highway-footway|area:highway-pedestrian|area:highway-steps +area:highway-footway|area:highway-pedestrian|area:highway-steps|place-square en:^Square ru:^Площадь ar:^ساحة diff --git a/generator/search_index_builder.cpp b/generator/search_index_builder.cpp index c66b58f57b..eb2495197b 100644 --- a/generator/search_index_builder.cpp +++ b/generator/search_index_builder.cpp @@ -261,7 +261,7 @@ public: feature::TypesHolder types(f); - auto const & streetChecker = ftypes::IsStreetChecker::Instance(); + auto const & streetChecker = ftypes::IsStreetOrSuburbChecker::Instance(); bool const hasStreetType = streetChecker(types); // Init inserter with serialized value. diff --git a/indexer/ftypes_matcher.cpp b/indexer/ftypes_matcher.cpp index d34b2a73d2..b141bc6096 100644 --- a/indexer/ftypes_matcher.cpp +++ b/indexer/ftypes_matcher.cpp @@ -214,7 +214,7 @@ IsSuburbChecker::IsSuburbChecker() m_types.push_back(c.GetTypeByPath({"place", "suburb"})); } -IsStreetChecker::IsStreetChecker() +IsWayChecker::IsWayChecker() { // TODO (@y, @m, @vng): this list must be up-to-date with // data/categories.txt, so, it's worth it to generate or parse it @@ -243,6 +243,16 @@ IsStreetChecker::IsStreetChecker() m_types.push_back(c.GetTypeByPath({p[0], p[1]})); } +IsStreetOrSuburbChecker::IsStreetOrSuburbChecker() +{ + for (auto const t : IsWayChecker::Instance().m_types) + m_types.push_back(t); + for (auto const t : IsSquareChecker::Instance().m_types) + m_types.push_back(t); + for (auto const t : IsSuburbChecker::Instance().m_types) + m_types.push_back(t); +} + IsAddressObjectChecker::IsAddressObjectChecker() : BaseChecker(1 /* level */) { auto const paths = {"building", "amenity", "shop", "tourism", "historic", "office", "craft"}; diff --git a/indexer/ftypes_matcher.hpp b/indexer/ftypes_matcher.hpp index 751d6de52f..018d0ed932 100644 --- a/indexer/ftypes_matcher.hpp +++ b/indexer/ftypes_matcher.hpp @@ -107,6 +107,7 @@ public: class IsSquareChecker : public BaseChecker { IsSquareChecker(); + friend class IsStreetOrSuburbChecker; public: DECLARE_CHECKER_INSTANCE(IsSquareChecker); @@ -115,16 +116,27 @@ public: class IsSuburbChecker : public BaseChecker { IsSuburbChecker(); + friend class IsStreetOrSuburbChecker; public: DECLARE_CHECKER_INSTANCE(IsSuburbChecker); }; -class IsStreetChecker : public BaseChecker +class IsWayChecker : public BaseChecker { - IsStreetChecker(); + IsWayChecker(); + friend class IsStreetOrSuburbChecker; + public: - DECLARE_CHECKER_INSTANCE(IsStreetChecker); + DECLARE_CHECKER_INSTANCE(IsWayChecker); +}; + +class IsStreetOrSuburbChecker : public BaseChecker +{ + IsStreetOrSuburbChecker(); + +public: + DECLARE_CHECKER_INSTANCE(IsStreetOrSuburbChecker); }; class IsAddressObjectChecker : public BaseChecker diff --git a/indexer/indexer_tests/checker_test.cpp b/indexer/indexer_tests/checker_test.cpp index 9dc695893b..19f14e6a34 100644 --- a/indexer/indexer_tests/checker_test.cpp +++ b/indexer/indexer_tests/checker_test.cpp @@ -179,17 +179,17 @@ UNIT_TEST(IsTypeConformed) TEST(!ftypes::IsTypeConformed(types[1], {"*", "building", "*"}), ()); } -UNIT_TEST(IsStreetChecker) +UNIT_TEST(IsWayChecker) { classificator::Load(); - TEST(ftypes::IsStreetChecker::Instance()(GetStreetTypes()), ()); - TEST(ftypes::IsStreetChecker::Instance()(GetStreetAndNotStreetTypes()), ()); + TEST(ftypes::IsWayChecker::Instance()(GetStreetTypes()), ()); + TEST(ftypes::IsWayChecker::Instance()(GetStreetAndNotStreetTypes()), ()); // TODO (@y, @m, @vng): need to investigate - do we really need this - // TEST for absence of links, because IsStreetChecker() is used for + // TEST for absence of links, because IsWayChecker() is used for // search only. // - // TEST(!ftypes::IsStreetChecker::Instance()(GetLinkTypes()), ()); + // TEST(!ftypes::IsWayChecker::Instance()(GetLinkTypes()), ()); } UNIT_TEST(IsLinkChecker) diff --git a/search/categories_cache.cpp b/search/categories_cache.cpp index a9356e8e21..01975ddefc 100644 --- a/search/categories_cache.cpp +++ b/search/categories_cache.cpp @@ -52,7 +52,7 @@ CBV CategoriesCache::Load(MwmContext const & context) const // StreetsCache ------------------------------------------------------------------------------------ StreetsCache::StreetsCache(base::Cancellable const & cancellable) - : CategoriesCache(ftypes::IsStreetChecker::Instance(), cancellable) + : CategoriesCache(ftypes::IsStreetOrSuburbChecker::Instance(), cancellable) { } diff --git a/search/intermediate_result.cpp b/search/intermediate_result.cpp index 1458961de0..1adc00cab4 100644 --- a/search/intermediate_result.cpp +++ b/search/intermediate_result.cpp @@ -148,10 +148,7 @@ bool RankerResult::IsEqualCommon(RankerResult const & r) const return m_geomType == r.m_geomType && GetBestType() == r.GetBestType() && m_str == r.m_str; } -bool RankerResult::IsStreet() const -{ - return m_geomType == feature::GEOM_LINE && ftypes::IsStreetChecker::Instance()(m_types); -} +bool RankerResult::IsStreet() const { return ftypes::IsStreetOrSuburbChecker::Instance()(m_types); } uint32_t RankerResult::GetBestType(vector const & preferredTypes) const { diff --git a/search/model.cpp b/search/model.cpp index 6387b001d2..0f5f048130 100644 --- a/search/model.cpp +++ b/search/model.cpp @@ -82,7 +82,7 @@ private: Model::Type Model::GetType(FeatureType & feature) const { static auto const & buildingChecker = CustomIsBuildingChecker::Instance(); - static auto const & streetChecker = IsStreetChecker::Instance(); + static auto const & streetChecker = IsStreetOrSuburbChecker::Instance(); static auto const & localityChecker = IsLocalityChecker::Instance(); static auto const & poiChecker = IsPoiChecker::Instance(); diff --git a/search/reverse_geocoder.cpp b/search/reverse_geocoder.cpp index 9fdbd5d588..28f17689fe 100644 --- a/search/reverse_geocoder.cpp +++ b/search/reverse_geocoder.cpp @@ -40,7 +40,7 @@ void AddStreet(FeatureType & ft, m2::PointD const & center, bool includeSquaresA vector & streets) { bool const addAsStreet = - ft.GetFeatureType() == feature::GEOM_LINE && ftypes::IsStreetChecker::Instance()(ft); + ft.GetFeatureType() == feature::GEOM_LINE && ftypes::IsWayChecker::Instance()(ft); bool const isSquareOrSuburb = ftypes::IsSquareChecker::Instance()(ft) || ftypes::IsSuburbChecker::Instance()(ft); bool const addAsSquareOrSuburb = includeSquaresAndSuburbs && isSquareOrSuburb; diff --git a/search/search_integration_tests/smoke_test.cpp b/search/search_integration_tests/smoke_test.cpp index def4880578..5abf9a5ef8 100644 --- a/search/search_integration_tests/smoke_test.cpp +++ b/search/search_integration_tests/smoke_test.cpp @@ -149,6 +149,7 @@ UNIT_CLASS_TEST(SmokeTest, CategoriesTest) {"waterway", "riverbank"}, {"waterway", "stream"}, {"landuse", "basin"}, + {"landuse", "residential"}, {"place", "county"}, {"place", "islet"}, {"power", "pole"}, diff --git a/search/search_tests/house_detector_tests.cpp b/search/search_tests/house_detector_tests.cpp index d611f8d437..279c1e7099 100644 --- a/search/search_tests/house_detector_tests.cpp +++ b/search/search_tests/house_detector_tests.cpp @@ -77,7 +77,7 @@ public: if (f.GetFeatureType() == feature::GEOM_LINE) { string name; - if (f.GetName(0, name) && ftypes::IsStreetChecker::Instance()(f)) + if (f.GetName(0, name) && ftypes::IsWayChecker::Instance()(f)) { string key; if (GetKey(name, key)) diff --git a/search/street_vicinity_loader.cpp b/search/street_vicinity_loader.cpp index 55bf2eca98..0fd8560848 100644 --- a/search/street_vicinity_loader.cpp +++ b/search/street_vicinity_loader.cpp @@ -3,6 +3,7 @@ #include "indexer/cell_id.hpp" #include "indexer/feature_covering.hpp" #include "indexer/feature_decl.hpp" +#include "indexer/ftypes_matcher.hpp" #include "geometry/mercator.hpp" #include "geometry/point2d.hpp" @@ -46,11 +47,22 @@ void StreetVicinityLoader::LoadStreet(uint32_t featureId, Street & street) if (!m_context->GetFeature(featureId, feature)) return; - if (feature.GetFeatureType() != feature::GEOM_LINE) + bool const isStreet = feature.GetFeatureType() == feature::GEOM_LINE && + ftypes::IsWayChecker::Instance()(feature); + bool const isSquareOrSuburb = ftypes::IsSquareChecker::Instance()(feature) || + ftypes::IsSuburbChecker::Instance()(feature); + if (!isStreet && !isSquareOrSuburb) return; vector points; - feature.ForEachPoint(base::MakeBackInsertFunctor(points), FeatureType::BEST_GEOMETRY); + if (feature.GetFeatureType() == feature::GEOM_AREA) + { + points = feature.GetTriangesAsPoints(FeatureType::BEST_GEOMETRY); + } + else + { + feature.ForEachPoint(base::MakeBackInsertFunctor(points), FeatureType::BEST_GEOMETRY); + } ASSERT(!points.empty(), ()); for (auto const & point : points)