diff --git a/search/CMakeLists.txt b/search/CMakeLists.txt index 1637ec4893..f8646c9d05 100644 --- a/search/CMakeLists.txt +++ b/search/CMakeLists.txt @@ -13,6 +13,7 @@ set( cbv.hpp cities_boundaries_table.cpp cities_boundaries_table.hpp + city_finder.cpp city_finder.hpp common.hpp displayed_categories.cpp diff --git a/search/city_finder.cpp b/search/city_finder.cpp new file mode 100644 index 0000000000..6601ea631c --- /dev/null +++ b/search/city_finder.cpp @@ -0,0 +1,30 @@ +#include "search/city_finder.hpp" + +#include "indexer/feature_decl.hpp" + +using namespace std; + +namespace search +{ +CityFinder::CityFinder(Index const & index) + : m_unusedBoundaries(index) + , m_unusedCache(m_cancellable) + , m_finder(index, m_unusedBoundaries, m_unusedCache) +{ +} + +string CityFinder::GetCityName(m2::PointD const & p, int8_t lang) +{ + string city; + m_finder.GetLocality( + p, [&](LocalityItem const & item) { item.GetSpecifiedOrDefaultName(lang, city); }); + return city; +} + +FeatureID CityFinder::GetCityFeatureID(m2::PointD const & p) +{ + FeatureID id; + m_finder.GetLocality(p, [&id](LocalityItem const & item) { id = item.m_id; }); + return id; +} +} // namespace search diff --git a/search/city_finder.hpp b/search/city_finder.hpp index 6656c276f1..53243706bb 100644 --- a/search/city_finder.hpp +++ b/search/city_finder.hpp @@ -8,6 +8,9 @@ #include "base/cancellable.hpp" #include +#include + +struct FeatureID; namespace search { @@ -17,20 +20,10 @@ public: // TODO (@milchakov): consider to reuse locality finder from search // engine. Otherwise, CityFinder won't benefit from approximated // cities boundaries. - explicit CityFinder(Index const & index) - : m_unusedBoundaries(index) - , m_unusedCache(m_cancellable) - , m_finder(index, m_unusedBoundaries, m_unusedCache) - { - } + explicit CityFinder(Index const & index); - string GetCityName(m2::PointD const & p, int8_t lang) - { - string city; - m_finder.GetLocality( - p, [&](LocalityItem const & item) { item.GetSpecifiedOrDefaultName(lang, city); }); - return city; - } + std::string GetCityName(m2::PointD const & p, int8_t lang); + FeatureID GetCityFeatureID(m2::PointD const & p); private: my::Cancellable m_cancellable; diff --git a/search/locality_finder.cpp b/search/locality_finder.cpp index f9a53b0cdb..279d937559 100644 --- a/search/locality_finder.cpp +++ b/search/locality_finder.cpp @@ -102,9 +102,10 @@ public: auto const center = ft.GetCenter(); CitiesBoundariesTable::Boundaries boundaries; - m_boundaries.Get(FeatureID(m_ctx.GetId(), id), boundaries); + auto const fid = ft.GetID(); + m_boundaries.Get(fid, boundaries); - m_holder.Add(LocalityItem(names, center, boundaries, population)); + m_holder.Add(LocalityItem(names, center, boundaries, population, fid)); m_loadedIds.insert(id); } @@ -120,8 +121,8 @@ private: // LocalityItem ------------------------------------------------------------------------------------ LocalityItem::LocalityItem(StringUtf8Multilang const & names, m2::PointD const & center, - Boundaries const & boundaries, uint64_t population) - : m_names(names), m_center(center), m_boundaries(boundaries), m_population(population) + Boundaries const & boundaries, uint64_t population, FeatureID const & id) + : m_names(names), m_center(center), m_boundaries(boundaries), m_population(population), m_id(id) { } diff --git a/search/locality_finder.hpp b/search/locality_finder.hpp index 7177986309..d0bb5b0821 100644 --- a/search/locality_finder.hpp +++ b/search/locality_finder.hpp @@ -31,7 +31,7 @@ struct LocalityItem using Boundaries = CitiesBoundariesTable::Boundaries; LocalityItem(StringUtf8Multilang const & names, m2::PointD const & center, - Boundaries const & boundaries, uint64_t population); + Boundaries const & boundaries, uint64_t population, FeatureID const & id); bool GetName(int8_t lang, string & name) const { return m_names.GetString(lang, name); } @@ -44,6 +44,7 @@ struct LocalityItem m2::PointD m_center; Boundaries m_boundaries; uint64_t m_population; + FeatureID m_id; }; string DebugPrint(LocalityItem const & item); diff --git a/search/search.pro b/search/search.pro index aa8d3ea62d..e21c2395d8 100644 --- a/search/search.pro +++ b/search/search.pro @@ -90,6 +90,7 @@ SOURCES += \ categories_cache.cpp \ cbv.cpp \ cities_boundaries_table.cpp \ + city_finder.cpp \ displayed_categories.cpp \ downloader_search_callback.cpp \ dummy_rank_table.cpp \ diff --git a/search/search_tests/locality_selector_test.cpp b/search/search_tests/locality_selector_test.cpp index 76a93fa550..d2d00b8b10 100644 --- a/search/search_tests/locality_selector_test.cpp +++ b/search/search_tests/locality_selector_test.cpp @@ -17,51 +17,69 @@ StringUtf8Multilang ToMultilang(string const & name) struct City { - City(string const & name, m2::PointD const & center, uint64_t population) - : m_item(ToMultilang(name), center, {} /* boundaries */, population) + City(string const & name, m2::PointD const & center, uint64_t population, FeatureID const & id) + : m_item(ToMultilang(name), center, {} /* boundaries */, population, id) { } LocalityItem m_item; }; -string GetMatchedCity(m2::PointD const & point, vector const & cities) +struct MatchedCity +{ + MatchedCity(string const & name, FeatureID const & id) : m_name(name), m_id(id) {} + + string const m_name; + FeatureID const m_id; +}; + +MatchedCity GetMatchedCity(m2::PointD const & point, vector const & cities) { LocalitySelector selector(point); for (auto const & city : cities) selector(city.m_item); string name; - selector.WithBestLocality( - [&](LocalityItem const & item) { item.GetName(StringUtf8Multilang::kEnglishCode, name); }); - return name; + FeatureID id; + selector.WithBestLocality([&](LocalityItem const & item) { + item.GetName(StringUtf8Multilang::kEnglishCode, name); + id = item.m_id; + }); + + return {name, id}; } UNIT_TEST(LocalitySelector_Test1) { - auto const name = GetMatchedCity(m2::PointD(-97.56345, 26.79672), - {{"Matamoros", m2::PointD(-97.50665, 26.79718), 918536}, + MwmSet::MwmId mwmId; + auto const city = + GetMatchedCity(m2::PointD(-97.56345, 26.79672), + {{"Matamoros", m2::PointD(-97.50665, 26.79718), 918536, {mwmId, 0}}, - {"Brownsville", m2::PointD(-97.48910, 26.84558), 180663}}); - TEST_EQUAL(name, "Matamoros", ()); + {"Brownsville", m2::PointD(-97.48910, 26.84558), 180663, {mwmId, 1}}}); + TEST_EQUAL(city.m_name, "Matamoros", ()); + TEST_EQUAL(city.m_id.m_index, 0, ()); } UNIT_TEST(LocalitySelector_Test2) { - vector const cities = {{"Moscow", m2::PointD(37.61751, 67.45398), 11971516}, - {"Krasnogorsk", m2::PointD(37.34040, 67.58036), 135735}, - {"Khimki", m2::PointD(37.44499, 67.70070), 240463}, - {"Mytishchi", m2::PointD(37.73394, 67.73675), 180663}, - {"Dolgoprudny", m2::PointD(37.51425, 67.78073), 101979}}; + MwmSet::MwmId mwmId; + vector const cities = {{"Moscow", m2::PointD(37.61751, 67.45398), 11971516, {mwmId, 0}}, + {"Krasnogorsk", m2::PointD(37.34040, 67.58036), 135735, {mwmId, 1}}, + {"Khimki", m2::PointD(37.44499, 67.70070), 240463, {mwmId, 2}}, + {"Mytishchi", m2::PointD(37.73394, 67.73675), 180663, {mwmId, 3}}, + {"Dolgoprudny", m2::PointD(37.51425, 67.78073), 101979, {mwmId, 4}}}; { - auto const name = GetMatchedCity(m2::PointD(37.53826, 67.53554), cities); - TEST_EQUAL(name, "Moscow", ()); + auto const city = GetMatchedCity(m2::PointD(37.53826, 67.53554), cities); + TEST_EQUAL(city.m_name, "Moscow", ()); + TEST_EQUAL(city.m_id.m_index, 0, ()); } { - auto const name = GetMatchedCity(m2::PointD(37.46980, 67.66650), cities); - TEST_EQUAL(name, "Khimki", ()); + auto const city = GetMatchedCity(m2::PointD(37.46980, 67.66650), cities); + TEST_EQUAL(city.m_name, "Khimki", ()); + TEST_EQUAL(city.m_id.m_index, 2, ()); } } } // namespace diff --git a/xcode/search/search.xcodeproj/project.pbxproj b/xcode/search/search.xcodeproj/project.pbxproj index d7ac99ccf3..8420577b0c 100644 --- a/xcode/search/search.xcodeproj/project.pbxproj +++ b/xcode/search/search.xcodeproj/project.pbxproj @@ -200,6 +200,7 @@ A1347D511B8758C3009050FF /* query_saver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1347D4F1B8758C3009050FF /* query_saver.cpp */; }; A1347D521B8758C3009050FF /* query_saver.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A1347D501B8758C3009050FF /* query_saver.hpp */; }; A1347D551B8758E9009050FF /* query_saver_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1347D541B8758E9009050FF /* query_saver_tests.cpp */; }; + F63CE2BB1FBB206800716AD3 /* city_finder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F63CE2BA1FBB206800716AD3 /* city_finder.cpp */; }; F652D8BE1CFDE1E800FC29A0 /* common.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F652D8BA1CFDE1E800FC29A0 /* common.hpp */; }; F652D8BF1CFDE1E800FC29A0 /* engine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F652D8BB1CFDE1E800FC29A0 /* engine.cpp */; }; F652D8C01CFDE1E800FC29A0 /* engine.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F652D8BC1CFDE1E800FC29A0 /* engine.hpp */; }; @@ -433,6 +434,7 @@ A1347D4F1B8758C3009050FF /* query_saver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = query_saver.cpp; sourceTree = ""; }; A1347D501B8758C3009050FF /* query_saver.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = query_saver.hpp; sourceTree = ""; }; A1347D541B8758E9009050FF /* query_saver_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = query_saver_tests.cpp; sourceTree = ""; }; + F63CE2BA1FBB206800716AD3 /* city_finder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = city_finder.cpp; sourceTree = ""; }; F652D8BA1CFDE1E800FC29A0 /* common.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = common.hpp; sourceTree = ""; }; F652D8BB1CFDE1E800FC29A0 /* engine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = engine.cpp; sourceTree = ""; }; F652D8BC1CFDE1E800FC29A0 /* engine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = engine.hpp; sourceTree = ""; }; @@ -697,6 +699,7 @@ 3461C99E1D79949600E6E6F5 /* categories_set.hpp */, 345C8DA91D2D15A50037E3A6 /* cbv.cpp */, 345C8DAA1D2D15A50037E3A6 /* cbv.hpp */, + F63CE2BA1FBB206800716AD3 /* city_finder.cpp */, 3DFEBF751EF2D55800317D5C /* city_finder.hpp */, F652D8BA1CFDE1E800FC29A0 /* common.hpp */, 0810EC341D6D9D2E00ABFEE7 /* displayed_categories.cpp */, @@ -1126,6 +1129,7 @@ 39B2B94A1FB4620200AB85A1 /* processor_test.cpp in Sources */, F652D8F81CFDE21900FC29A0 /* intersection_result.cpp in Sources */, 34586B891DCB1E8300CF7FC9 /* hotels_filter_test.cpp in Sources */, + F63CE2BB1FBB206800716AD3 /* city_finder.cpp in Sources */, F652D9061CFDE21900FC29A0 /* ranking_info.cpp in Sources */, 39B2B94B1FB4620200AB85A1 /* ranker_test.cpp in Sources */, F652D9001CFDE21900FC29A0 /* nested_rects_cache.cpp in Sources */, @@ -1308,6 +1312,13 @@ }; name = "Production Full"; }; + F63CE2B91FB9AFCB00716AD3 /* Production Full */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = search_tests; + }; + name = "Production Full"; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */