From e8a77fb0fbf27ba468a8b3f952efd0fb3743cabd Mon Sep 17 00:00:00 2001 From: Yuri Gorshenin Date: Wed, 7 Sep 2016 12:04:07 +0300 Subject: [PATCH] [search][android][ios] Exposed categories synonyms. --- .../mapswithme/maps/DisplayedCategories.cpp | 4 +-- .../maps/search/CategoriesAdapter.java | 24 +++++++------- .../maps/search/DisplayedCategories.java | 4 +-- indexer/categories_holder.cpp | 29 +++++++++++++---- indexer/categories_holder.hpp | 13 +++++++- .../MWMSearchCategoriesManager.mm | 2 +- map/framework.cpp | 1 + map/framework.hpp | 14 ++++++-- search/displayed_categories.cpp | 11 ++++--- search/displayed_categories.hpp | 32 ++++++++++++++++--- 10 files changed, 97 insertions(+), 37 deletions(-) diff --git a/android/jni/com/mapswithme/maps/DisplayedCategories.cpp b/android/jni/com/mapswithme/maps/DisplayedCategories.cpp index 1239fd9e1d..bdddf6e29f 100644 --- a/android/jni/com/mapswithme/maps/DisplayedCategories.cpp +++ b/android/jni/com/mapswithme/maps/DisplayedCategories.cpp @@ -5,8 +5,8 @@ extern "C" { JNIEXPORT jobjectArray JNICALL -Java_com_mapswithme_maps_search_DisplayedCategories_nativeGet(JNIEnv * env, jclass clazz) +Java_com_mapswithme_maps_search_DisplayedCategories_nativeGetKeys(JNIEnv * env, jclass clazz) { - return jni::ToJavaStringArray(env, search::GetDisplayedCategories()); + return jni::ToJavaStringArray(env, search::DisplayedCategories::GetKeys()); } } // extern "C" diff --git a/android/src/com/mapswithme/maps/search/CategoriesAdapter.java b/android/src/com/mapswithme/maps/search/CategoriesAdapter.java index 669becf2a4..779834502f 100644 --- a/android/src/com/mapswithme/maps/search/CategoriesAdapter.java +++ b/android/src/com/mapswithme/maps/search/CategoriesAdapter.java @@ -36,22 +36,20 @@ class CategoriesAdapter extends RecyclerView.Adapter const CategoriesHolder::kLocaleMapping = {{"en", 1}, {"ru", 2}, {"uk", 3}, @@ -111,6 +115,7 @@ void CategoriesHolder::LoadFromStream(istream & s) { m_type2cat.clear(); m_name2type.clear(); + m_groupTranslations.clear(); State state = EParseTypes; string line; @@ -118,7 +123,6 @@ void CategoriesHolder::LoadFromStream(istream & s) Category cat; vector types; vector currentGroups; - multimap groupTranslations; Classificator const & c = classif(); @@ -184,9 +188,11 @@ void CategoriesHolder::LoadFromStream(istream & s) { for (string const & group : currentGroups) { - auto trans = groupTranslations.equal_range(group); - for (auto it = trans.first; it != trans.second; ++it) - cat.m_synonyms.push_back(it->second); + auto it = m_groupTranslations.find(group); + if (it == m_groupTranslations.end()) + continue; + for (auto const & synonym : it->second) + cat.m_synonyms.push_back(synonym); } } @@ -242,7 +248,7 @@ void CategoriesHolder::LoadFromStream(istream & s) if (currentGroups.size() == 1 && types.empty()) { // Not a translation, but a category group definition - groupTranslations.emplace(currentGroups[0], name); + m_groupTranslations[currentGroups[0]].push_back(name); } else cat.m_synonyms.push_back(name); @@ -308,6 +314,7 @@ bool CategoriesHolder::IsTypeExist(uint32_t type) const return range.first != range.second; } +// static int8_t CategoriesHolder::MapLocaleToInteger(string const & locale) { ASSERT(!kLocaleMapping.empty(), ()); @@ -338,3 +345,11 @@ int8_t CategoriesHolder::MapLocaleToInteger(string const & locale) return kUnsupportedLocaleCode; } + +// static +string CategoriesHolder::MapIntegerToLocale(int8_t code) +{ + if (code <= 0 || code > kLocaleMapping.size()) + return string(); + return kLocaleMapping[code - 1].m_name; +} diff --git a/indexer/categories_holder.hpp b/indexer/categories_holder.hpp index b488e4ab5d..3719fd7fbc 100644 --- a/indexer/categories_holder.hpp +++ b/indexer/categories_holder.hpp @@ -41,6 +41,8 @@ public: int8_t m_code; }; + using GroupTranslations = unordered_map>; + private: typedef strings::UniString StringT; typedef multimap > Type2CategoryContT; @@ -49,6 +51,7 @@ private: Type2CategoryContT m_type2cat; Name2CatContT m_name2type; + GroupTranslations m_groupTranslations; public: static int8_t const kEnglishCode; @@ -107,6 +110,8 @@ public: } } + inline GroupTranslations const & GetGroupTranslations() const { return m_groupTranslations; } + /// Search name for type with preffered locale language. /// If no name for this language, return first (en) name. /// @return false if no categories for type. @@ -123,9 +128,15 @@ public: m_name2type.swap(r.m_name2type); } - /// Converts any language locale from UI to internal integer code + // Converts any language |locale| from UI to the corresponding + // internal integer code static int8_t MapLocaleToInteger(string const & locale); + // Returns corresponding string representation for an internal + // integer |code|. Returns an empty string in case of invalid + // |code|. + static string MapIntegerToLocale(int8_t code); + private: void AddCategory(Category & cat, vector & types); static bool ValidKeyToken(StringT const & s); diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.mm index efa6c4b523..498e10a39b 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/Search/TabbedView/CategoriesTab/MWMSearchCategoriesManager.mm @@ -18,7 +18,7 @@ static NSString * const kCellIdentifier = @"MWMSearchCategoryCell"; { self = [super init]; if (self) - m_categories = search::GetDisplayedCategories(); + m_categories = search::DisplayedCategories::GetKeys(); return self; } diff --git a/map/framework.cpp b/map/framework.cpp index 4356bb8bf7..fef2c26140 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -351,6 +351,7 @@ Framework::Framework() m_model.SetOnMapDeregisteredCallback(bind(&Framework::OnMapDeregistered, this, _1)); LOG(LDEBUG, ("Classificator initialized")); + m_displayedCategories = make_unique(GetDefaultCategories()); // To avoid possible races - init country info getter once in constructor. InitCountryInfoGetter(); diff --git a/map/framework.hpp b/map/framework.hpp index 5bb11fdd33..50982d0f32 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -24,6 +24,7 @@ #include "editor/user_stats.hpp" +#include "search/displayed_categories.hpp" #include "search/downloader_search_callback.hpp" #include "search/engine.hpp" #include "search/mode.hpp" @@ -117,12 +118,15 @@ protected: StringsBundle m_stringsBundle; + model::FeaturesFetcher m_model; + + // The order matters here: DisplayedCategories may be used only when + // classificator is loaded (by |m_model|). + unique_ptr m_displayedCategories; + // The order matters here: storage::CountryInfoGetter and // m_model::FeaturesFetcher must be initialized before // search::Engine and, therefore, destroyed after search::Engine. - - model::FeaturesFetcher m_model; - unique_ptr m_infoGetter; unique_ptr m_searchEngine; @@ -241,6 +245,10 @@ public: storage::Storage & GetStorage() { return m_storage; } storage::Storage const & GetStorage() const { return m_storage; } + search::DisplayedCategories const & GetDisplayedCategories() const + { + return *m_displayedCategories; + } storage::CountryInfoGetter & GetCountryInfoGetter() { return *m_infoGetter; } StorageDownloadingPolicy & GetDownloadingPolicy() { return m_storageDownloadingPolicy; } diff --git a/search/displayed_categories.cpp b/search/displayed_categories.cpp index 227b8f3944..775dd25804 100644 --- a/search/displayed_categories.cpp +++ b/search/displayed_categories.cpp @@ -2,12 +2,15 @@ namespace { -vector const kDisplayedCategories = { - "food", "hotel", "tourism", "wifi", "transport", "fuel", "parking", "shop", - "atm", "bank", "entertainment", "hospital", "pharmacy", "police", "toilet", "post"}; +vector const kKeys = {"food", "hotel", "tourism", "wifi", "transport", "fuel", + "parking", "shop", "atm", "bank", "entertainment", "hospital", + "pharmacy", "police", "toilet", "post"}; } // namespace namespace search { -vector const & GetDisplayedCategories() { return kDisplayedCategories; } +DisplayedCategories::DisplayedCategories(CategoriesHolder const & holder) : m_holder(holder) {} + +// static +vector const & DisplayedCategories::GetKeys() { return kKeys; } } // namespace search diff --git a/search/displayed_categories.hpp b/search/displayed_categories.hpp index 1e572abf35..781cb2a4d9 100644 --- a/search/displayed_categories.hpp +++ b/search/displayed_categories.hpp @@ -1,12 +1,36 @@ #pragma once +#include "indexer/categories_holder.hpp" + #include "std/string.hpp" #include "std/vector.hpp" namespace search { -// Returns a list of English names of displayed categories for the -// categories search tab. It's guaranteed that the list remains the -// same during the application lifetime. -vector const & GetDisplayedCategories(); +class DisplayedCategories +{ +public: + DisplayedCategories(CategoriesHolder const & holder); + + // Returns a list of English names of displayed categories for the + // categories search tab. It's guaranteed that the list remains the + // same during the application lifetime, keys may be used as parts + // of resources ids. + static vector const & GetKeys(); + + template + void ForEachSynonym(string const & key, Fn && fn) const + { + auto const & translations = m_holder.GetGroupTranslations(); + auto const it = translations.find("@" + key); + if (it == translations.end()) + return; + + for (auto const & name : it->second) + fn(name.m_name, CategoriesHolder::MapIntegerToLocale(name.m_locale)); + } + + private: + CategoriesHolder const & m_holder; +}; } // namespace search