diff --git a/map/framework.cpp b/map/framework.cpp index f049dc786f..993885db5c 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -811,7 +811,7 @@ void Framework::UpdateUserViewportChanged() m_lastSearch.SetSearchMode(search::SearchParams::IN_VIEWPORT); m_lastSearch.SetForceSearch(false); - (void)GetSearchEngine()->Search(m_lastSearch, GetCurrentViewport()); + (void)GetSearchEngine()->Search(m_lastSearch, GetCurrentViewport(), true); } } diff --git a/search/intermediate_result.cpp b/search/intermediate_result.cpp index 6145b41377..9534f09450 100644 --- a/search/intermediate_result.cpp +++ b/search/intermediate_result.cpp @@ -238,6 +238,14 @@ Result PreResult2::GenerateFinalResult( } } +Result PreResult2::GeneratePointResult( + CategoriesHolder const * pCat, + set const * pTypes, + int8_t lang) const +{ + return Result(GetCenter(), m_str, GetFeatureType(pCat, pTypes, lang)); +} + bool PreResult2::LessRank(PreResult2 const & r1, PreResult2 const & r2) { return LessRankT(r1, r2); diff --git a/search/intermediate_result.hpp b/search/intermediate_result.hpp index 1651fc27ee..09aeff1674 100644 --- a/search/intermediate_result.hpp +++ b/search/intermediate_result.hpp @@ -87,6 +87,10 @@ public: set const * pTypes, int8_t lang) const; + Result GeneratePointResult(CategoriesHolder const * pCat, + set const * pTypes, + int8_t lang) const; + static bool LessRank(PreResult2 const & r1, PreResult2 const & r2); static bool LessDistance(PreResult2 const & r1, PreResult2 const & r2); static bool LessViewportDistance(PreResult2 const & r1, PreResult2 const & r2); diff --git a/search/result.cpp b/search/result.cpp index 4547e12cd1..5ec642fbb9 100644 --- a/search/result.cpp +++ b/search/result.cpp @@ -20,6 +20,11 @@ Result::Result(FeatureID const & id, m2::PointD const & fCenter, } } +Result::Result(m2::PointD const & pt, string const & str, string const & type) + : m_center(pt), m_str(str), m_type(type) +{ +} + Result::Result(m2::PointD const & fCenter, string const & str, string const & region, string const & flag, double distance) diff --git a/search/result.hpp b/search/result.hpp index e1a663be7f..05902daee7 100644 --- a/search/result.hpp +++ b/search/result.hpp @@ -30,6 +30,9 @@ public: string const & flag, string const & type, uint32_t featureType, double distance); + /// Used for point-like results on the map. + Result(m2::PointD const & pt, string const & str, string const & type); + /// For RESULT_LATLON. Result(m2::PointD const & fCenter, string const & str, string const & region, diff --git a/search/search_engine.cpp b/search/search_engine.cpp index 6c4e127847..b1421e6c9e 100644 --- a/search/search_engine.cpp +++ b/search/search_engine.cpp @@ -141,7 +141,7 @@ void Engine::PrepareSearch(m2::RectD const & viewport, GetPlatform().RunAsync(bind(&Engine::SetViewportAsync, this, viewport, nearby)); } -bool Engine::Search(SearchParams const & params, m2::RectD const & viewport) +bool Engine::Search(SearchParams const & params, m2::RectD const & viewport, bool viewportPoints/* = false*/) { // Check for equal query. // There is no need to put synch here for reading m_params, @@ -168,7 +168,7 @@ bool Engine::Search(SearchParams const & params, m2::RectD const & viewport) } // Run task. - GetPlatform().RunAsync(bind(&Engine::SearchAsync, this)); + GetPlatform().RunAsync(bind(&Engine::SearchAsync, this, viewportPoints)); return true; } @@ -231,7 +231,7 @@ void Engine::EmitResults(SearchParams const & params, Results & res) params.m_callback(res); } -void Engine::SearchAsync() +void Engine::SearchAsync(bool viewportPoints) { { // Avoid many threads waiting in search mutex. One is enough. @@ -326,7 +326,10 @@ void Engine::SearchAsync() { // Do search for address in all modes. // params.NeedSearch(SearchParams::SEARCH_ADDRESS) - m_pQuery->Search(res, RESULTS_COUNT); + if (viewportPoints) + m_pQuery->SearchViewportPoints(res); + else + m_pQuery->Search(res, RESULTS_COUNT); } } catch (Query::CancelException const &) @@ -339,7 +342,7 @@ void Engine::SearchAsync() EmitResults(params, res); // Make additional search in whole mwm when not enough results (only for non-empty query). - if (!emptyQuery && !m_pQuery->IsCanceled() && count < RESULTS_COUNT) + if (!viewportPoints && !emptyQuery && !m_pQuery->IsCanceled() && count < RESULTS_COUNT) { try { diff --git a/search/search_engine.hpp b/search/search_engine.hpp index a604801272..f096dcb81a 100644 --- a/search/search_engine.hpp +++ b/search/search_engine.hpp @@ -41,7 +41,7 @@ public: void PrepareSearch(m2::RectD const & viewport, bool hasPt, double lat, double lon); - bool Search(SearchParams const & params, m2::RectD const & viewport); + bool Search(SearchParams const & params, m2::RectD const & viewport, bool viewportPoints = false); void GetResults(Results & res); @@ -67,7 +67,7 @@ private: static const int RESULTS_COUNT = 30; void SetViewportAsync(m2::RectD const & viewport, m2::RectD const & nearby); - void SearchAsync(); + void SearchAsync(bool viewportPoints); void EmitResults(SearchParams const & params, Results & res); diff --git a/search/search_query.cpp b/search/search_query.cpp index 6e25236f6d..f8ea91596d 100644 --- a/search/search_query.cpp +++ b/search/search_query.cpp @@ -581,56 +581,39 @@ namespace impl }; } -void Query::FlushResults(Results & res, bool allMWMs, size_t resCount) +template void Query::MakePreResult2(vector & cont, vector & streets, int ind/* = -1*/) { - vector indV; - vector streets; + // make unique set of PreResult1 + typedef set PreResultSetT; + PreResultSetT theSet; - { - // make unique set of PreResult1 - typedef set PreResultSetT; - PreResultSetT theSet; - - for (size_t i = 0; i < m_qCount; ++i) + for (size_t i = 0; i < m_qCount; ++i) + if (ind == -1 || i == ind) { theSet.insert(m_results[i].begin(), m_results[i].end()); m_results[i].clear(); } - // make PreResult2 vector - impl::PreResult2Maker maker(*this); - for (PreResultSetT::const_iterator i = theSet.begin(); i != theSet.end(); ++i) - { - impl::PreResult2 * p = maker(*i); - if (p == 0) - continue; + // make PreResult2 vector + impl::PreResult2Maker maker(*this); + for (PreResultSetT::const_iterator i = theSet.begin(); i != theSet.end(); ++i) + { + impl::PreResult2 * p = maker(*i); + if (p == 0) + continue; - if (p->IsStreet()) - streets.push_back(p->GetID()); + if (p->IsStreet()) + streets.push_back(p->GetID()); - if (IsResultExists(p, indV)) - delete p; - else - indV.push_back(IndexedValue(p)); - } + if (IsResultExists(p, cont)) + delete p; + else + cont.push_back(IndexedValue(p)); } +} - if (indV.empty()) - return; - - RemoveDuplicatingLinear(indV); - - SortByIndexedValue(indV, CompFactory2()); - - // Do not process suggestions in additional search. - if (!allMWMs) - ProcessSuggestions(indV, res); - - bool (Results::*addFn)(Result const &) = allMWMs ? - &Results::AddResultCheckExisting : - &Results::AddResult; - -#ifdef HOUSE_SEARCH_TEST +void Query::FlushHouses(Results & res, bool allMWMs, vector const & streets) +{ if (!m_house.empty() && !streets.empty()) { if (m_houseDetector.LoadStreets(streets) > 0) @@ -648,6 +631,10 @@ void Query::FlushResults(Results & res, bool allMWMs, size_t resCount) if (!allMWMs) count = min(count, size_t(5)); + bool (Results::*addFn)(Result const &) = allMWMs ? + &Results::AddResultCheckExisting : + &Results::AddResult; + for (size_t i = 0; i < count; ++i) { House const * h = houses[i].m_house; @@ -657,6 +644,32 @@ void Query::FlushResults(Results & res, bool allMWMs, size_t resCount) (res.*addFn)(r); } } +} + +void Query::FlushResults(Results & res, bool allMWMs, size_t resCount) +{ + vector indV; + vector streets; + + MakePreResult2(indV, streets); + + if (indV.empty()) + return; + + RemoveDuplicatingLinear(indV); + + SortByIndexedValue(indV, CompFactory2()); + + // Do not process suggestions in additional search. + if (!allMWMs) + ProcessSuggestions(indV, res); + + bool (Results::*addFn)(Result const &) = allMWMs ? + &Results::AddResultCheckExisting : + &Results::AddResult; + +#ifdef HOUSE_SEARCH_TEST + FlushHouses(res, allMWMs, streets); #endif // emit feature results @@ -672,6 +685,38 @@ void Query::FlushResults(Results & res, bool allMWMs, size_t resCount) } } +void Query::SearchViewportPoints(Results & res) +{ + ClearQueues(); + + if (m_cancel) return; + SearchAddress(res); + + if (m_cancel) return; + SearchFeatures(); + + vector indV; + vector streets; + + MakePreResult2(indV, streets, 1); + + if (indV.empty()) + return; + + RemoveDuplicatingLinear(indV); + +#ifdef HOUSE_SEARCH_TEST + FlushHouses(res, false, streets); +#endif + + for (size_t i = 0; i < indV.size(); ++i) + { + if (m_cancel) break; + + res.AddResult((*(indV[i])).GeneratePointResult(m_pCategories, &m_prefferedTypes, GetLanguage(LANG_CURRENT))); + } +} + ftypes::Type Query::GetLocalityIndex(feature::TypesHolder const & types) const { static ftypes::IsLocalityChecker checker; diff --git a/search/search_query.hpp b/search/search_query.hpp index cad482a5c8..d78d12fa59 100644 --- a/search/search_query.hpp +++ b/search/search_query.hpp @@ -98,6 +98,8 @@ public: void Search(Results & res, size_t resCount); void SearchAllInViewport(m2::RectD const & viewport, Results & res, unsigned int resultsNeeded = 30); void SearchAdditional(Results & res, bool nearMe, bool inViewport, size_t resCount); + + void SearchViewportPoints(Results & res); //@} void ClearCaches(); @@ -169,6 +171,8 @@ private: void AddResultFromTrie(TrieValueT const & val, size_t mwmID, ViewportID vID = DEFAULT_V); + template void MakePreResult2(vector & cont, vector & streets, int ind = -1); + void FlushHouses(Results & res, bool allMWMs, vector const & streets); void FlushResults(Results & res, bool allMWMs, size_t resCount); ftypes::Type GetLocalityIndex(feature::TypesHolder const & types) const; @@ -176,7 +180,6 @@ private: void GetSuggestion(string const & name, string & suggest) const; template void ProcessSuggestions(vector & vec, Results & res) const; - void SearchAddress(Results & res); /// Search for best localities by input tokens. @@ -269,6 +272,9 @@ public: static const size_t m_qCount = 3; private: + // 0 - LessRank + // 1 - LessViewportDistance + // 2 - LessDistance QueueT m_results[m_qCount]; };