diff --git a/map/framework.cpp b/map/framework.cpp index deb541ee8e..971735c195 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -653,9 +653,13 @@ search::Engine * Framework::GetSearchEngine() threads::MutexGuard lock(m_modelSyn); if (!m_pSearchEngine) { - scoped_ptr pReader(GetPlatform().GetReader(SEARCH_CATEGORIES_FILE_NAME)); + Platform & pl = GetPlatform(); + + scoped_ptr pReader(pl.GetReader(SEARCH_CATEGORIES_FILE_NAME)); m_pSearchEngine.reset( - new search::Engine(&m_model.GetIndex(), new CategoriesHolder(*pReader))); + new search::Engine(&m_model.GetIndex(), new CategoriesHolder(*pReader), + pl.GetReader(PACKED_POLYGONS_FILE), + pl.GetReader(COUNTRIES_FILE))); } } return m_pSearchEngine.get(); diff --git a/search/search_engine.cpp b/search/search_engine.cpp index 45d56b9480..3f0039796e 100644 --- a/search/search_engine.cpp +++ b/search/search_engine.cpp @@ -17,8 +17,10 @@ namespace search { -Engine::Engine(IndexType const * pIndex, CategoriesHolder * pCategories) - : m_pIndex(pIndex), m_pCategories(new map()) +Engine::Engine(IndexType const * pIndex, CategoriesHolder * pCategories, + ModelReaderPtr polyR, ModelReaderPtr countryR) +: m_pIndex(pIndex), m_pCategories(new map()), + m_infoGetter(polyR, countryR) { for (CategoriesHolder::const_iterator it = pCategories->begin(); it != pCategories->end(); ++it) { @@ -32,7 +34,7 @@ Engine::Engine(IndexType const * pIndex, CategoriesHolder * pCategories) } delete pCategories; - m_pQuery.reset(new Query(pIndex, m_pCategories.get())); + m_pQuery.reset(new Query(pIndex, m_pCategories.get(), &m_infoGetter)); } Engine::~Engine() diff --git a/search/search_engine.hpp b/search/search_engine.hpp index 6094868c06..fdd13cee12 100644 --- a/search/search_engine.hpp +++ b/search/search_engine.hpp @@ -1,5 +1,7 @@ #pragma once +#include "../storage/country_info.hpp" + #include "../indexer/index.hpp" #include "../geometry/rect2d.hpp" @@ -19,7 +21,7 @@ class Index; namespace search { -class CategoryInfo; +struct CategoryInfo; class Query; class Result; @@ -29,7 +31,8 @@ public: typedef Index IndexType; // Doesn't take ownership of @pIndex. Takes ownership of pCategories - Engine(IndexType const * pIndex, CategoriesHolder * pCategories); + Engine(IndexType const * pIndex, CategoriesHolder * pCategories, + ModelReaderPtr polyR, ModelReaderPtr countryR); ~Engine(); void SetViewport(m2::RectD const & viewport); @@ -39,6 +42,7 @@ private: Index const * m_pIndex; scoped_ptr > m_pCategories; scoped_ptr m_pQuery; + storage::CountryInfoGetter m_infoGetter; }; } // namespace search diff --git a/search/search_query.cpp b/search/search_query.cpp index 6cd6de0e6b..a22e5af260 100644 --- a/search/search_query.cpp +++ b/search/search_query.cpp @@ -5,24 +5,32 @@ #include "latlon_match.hpp" #include "result.hpp" #include "search_common.hpp" + +#include "../storage/country_info.hpp" + #include "../indexer/feature_covering.hpp" #include "../indexer/features_vector.hpp" #include "../indexer/index.hpp" #include "../indexer/scales.hpp" #include "../indexer/search_delimiters.hpp" #include "../indexer/search_string_utils.hpp" + #include "../base/logging.hpp" #include "../base/string_utils.hpp" #include "../base/stl_add.hpp" + #include "../std/algorithm.hpp" #include "../std/vector.hpp" + namespace search { -Query::Query(Index const * pIndex, CategoriesMapT const * pCategories) - : m_pIndex(pIndex), m_pCategories(pCategories), m_viewport(m2::RectD::GetEmptyRect()), - m_viewportExtended(m2::RectD::GetEmptyRect()), m_bOffsetsCacheIsValid(false) +Query::Query(Index const * pIndex, CategoriesMapT const * pCategories, + storage::CountryInfoGetter const * pInfoGetter) + : m_pIndex(pIndex), m_pCategories(pCategories), m_pInfoGetter(pInfoGetter), + m_viewport(m2::RectD::GetEmptyRect()), m_viewportExtended(m2::RectD::GetEmptyRect()), + m_bOffsetsCacheIsValid(false) { } @@ -158,12 +166,13 @@ void Query::FlushResults(function const & f) f(it->GenerateFinalResult()); } -void Query::AddFeatureResult(FeatureType const & feature) +void Query::AddFeatureResult(FeatureType const & f, string const & fName) { uint32_t penalty; string name; - GetBestMatchName(feature, penalty, name); - AddResult(impl::IntermediateResult(m_viewport, feature, name)); + GetBestMatchName(f, penalty, name); + + AddResult(impl::IntermediateResult(m_viewport, f, name + ", " + GetRegionName(f, fName))); } namespace impl @@ -195,10 +204,25 @@ public: } // namespace search::impl -void Query::GetBestMatchName(FeatureType const & feature, uint32_t & penalty, string & name) +void Query::GetBestMatchName(FeatureType const & f, uint32_t & penalty, string & name) { impl::BestNameFinder bestNameFinder(penalty, name, *m_pKeywordMatcher); - feature.ForEachNameRef(bestNameFinder); + f.ForEachNameRef(bestNameFinder); +} + +string Query::GetRegionName(FeatureType const & f, string const & fName) +{ + if (!fName.empty()) + { + return m_pInfoGetter->GetRegionName(fName); + } + else + { + if (f.GetFeatureType() == feature::GEOM_POINT) + return m_pInfoGetter->GetRegionName(f.GetCenter()); + } + + return string(); } namespace impl @@ -209,9 +233,10 @@ struct FeatureLoader uint32_t m_count; FeaturesVector & m_featuresVector; Query & m_query; + string m_fName; - FeatureLoader(FeaturesVector & featuresVector, Query & query) - : m_count(0), m_featuresVector(featuresVector), m_query(query) + FeatureLoader(FeaturesVector & featuresVector, Query & query, string const & fName) + : m_count(0), m_featuresVector(featuresVector), m_query(query), m_fName(fName) { } @@ -220,7 +245,7 @@ struct FeatureLoader ++m_count; FeatureType feature; m_featuresVector.Get(offset, feature); - m_query.AddFeatureResult(feature); + m_query.AddFeatureResult(feature, m_fName); } }; @@ -250,8 +275,10 @@ void Query::SearchFeatures() ::search::trie::EdgeValueReader())); if (pTrieRoot) { - FeaturesVector featuresVector(pMwm->m_cont, pMwm->GetHeader()); - impl::FeatureLoader f(featuresVector, *this); + feature::DataHeader const & h = pMwm->GetHeader(); + FeaturesVector featuresVector(pMwm->m_cont, h); + impl::FeatureLoader f(featuresVector, *this, + (h.GetType() == feature::DataHeader::world) ? "" : pMwm->GetFileName()); vector > tokens(m_tokens.size()); diff --git a/search/search_query.hpp b/search/search_query.hpp index dadbb83e7b..6694dd98ef 100644 --- a/search/search_query.hpp +++ b/search/search_query.hpp @@ -11,13 +11,16 @@ #include "../std/unordered_set.hpp" #include "../std/vector.hpp" + class FeatureType; class Index; +namespace storage { class CountryInfoGetter; } + namespace search { -class CategoryInfo; +struct CategoryInfo; class KeywordMatcher; namespace impl { class IntermediateResult; struct FeatureLoader; class BestNameFinder; } @@ -26,7 +29,8 @@ class Query public: typedef map CategoriesMapT; - Query(Index const * pIndex, CategoriesMapT const * pCategories); + Query(Index const * pIndex, CategoriesMapT const * pCategories, + storage::CountryInfoGetter const * pInfoGetter); ~Query(); void SetViewport(m2::RectD const & viewport); @@ -42,15 +46,18 @@ private: friend class impl::BestNameFinder; void AddResult(impl::IntermediateResult const & result); - void AddFeatureResult(FeatureType const & feature); + void AddFeatureResult(FeatureType const & f, string const & fName); void FlushResults(function const & f); void UpdateViewportOffsets(); void SearchFeatures(); void SuggestCategories(); - void GetBestMatchName(FeatureType const & feature, uint32_t & penalty, string & name); + + void GetBestMatchName(FeatureType const & f, uint32_t & penalty, string & name); + string GetRegionName(FeatureType const & f, string const & fName); Index const * m_pIndex; CategoriesMapT const * m_pCategories; + storage::CountryInfoGetter const * m_pInfoGetter; string m_rawQuery; strings::UniString m_uniQuery;