diff --git a/search/search_engine.cpp b/search/search_engine.cpp index 5d05f1b17a..48ccc3ccc5 100644 --- a/search/search_engine.cpp +++ b/search/search_engine.cpp @@ -160,7 +160,7 @@ void Engine::SetViewportAsync(m2::RectD const & viewport) m2::RectD r(viewport); (void)GetInflatedViewport(r); - m_pQuery->SetViewport(r); + m_pQuery->SetViewport(r, true); } void Engine::EmitResults(SearchParams const & params, Results & res) @@ -247,7 +247,7 @@ void Engine::SearchAsync() if (viewportSearch) { - m_pQuery->SetViewport(viewport); + m_pQuery->SetViewport(viewport, true); m_pQuery->SearchViewportPoints(res); if (res.GetCount() > 0) @@ -260,7 +260,7 @@ void Engine::SearchAsync() bool const isInflated = GetInflatedViewport(viewport); size_t const oldCount = res.GetCount(); - m_pQuery->SetViewport(viewport); + m_pQuery->SetViewport(viewport, oneTimeSearch); m_pQuery->Search(res, RESULTS_COUNT); size_t const newCount = res.GetCount(); diff --git a/search/search_query.cpp b/search/search_query.cpp index b91ec9b706..2791951675 100644 --- a/search/search_query.cpp +++ b/search/search_query.cpp @@ -127,32 +127,50 @@ int8_t Query::GetLanguage(int id) const return m_keywordsScorer.GetLanguage(GetLangIndex(id)); } -void Query::SetViewport(m2::RectD const & viewport) +void Query::SetViewport(m2::RectD const & viewport, bool forceUpdate) { m_cancel = false; MWMVectorT mwmsInfo; m_pIndex->GetMwmsInfo(mwmsInfo); - SetViewportByIndex(mwmsInfo, viewport, CURRENT_V); + SetViewportByIndex(mwmsInfo, viewport, CURRENT_V, forceUpdate); } -void Query::SetViewportByIndex(MWMVectorT const & mwmsInfo, m2::RectD const & viewport, size_t idx) +void Query::SetViewportByIndex(MWMVectorT const & mwmsInfo, m2::RectD const & viewport, + size_t idx, bool forceUpdate) { ASSERT(idx < COUNT_V, (idx)); if (viewport.IsValid()) { - // Check if viewports are equal (10 meters). - if (!m_viewport[idx].IsValid() || !IsEqualMercator(m_viewport[idx], viewport, 10.0)) + // Check if we can skip this cache query. + if (m_viewport[idx].IsValid()) { - m_viewport[idx] = viewport; - UpdateViewportOffsets(mwmsInfo, viewport, m_offsetsInViewport[idx]); + if (forceUpdate) + { + // skip if rects are equal with 10 meters tolerance + if (IsEqualMercator(m_viewport[idx], viewport, 10.0)) + return; + } + else + { + // skip if new viewport is inside the old one + m2::RectD r(m_viewport[idx]); + constexpr long double eps = 5.0 * MercatorBounds::degreeInMetres; + r.Inflate(eps, eps); + + if (r.IsRectInside(viewport)) + return; + } + } + + m_viewport[idx] = viewport; + UpdateViewportOffsets(mwmsInfo, viewport, m_offsetsInViewport[idx]); #ifdef FIND_LOCALITY_TEST - m_locality.SetViewportByIndex(viewport, idx); + m_locality.SetViewportByIndex(viewport, idx); #endif - } } else { @@ -1598,7 +1616,7 @@ void Query::SearchAddress(Results & res) m2::RectD const rect = MercatorBounds::RectByCenterXYAndSizeInMeters( city.m_value.m_pt, city.m_radius); - SetViewportByIndex(mwmsInfo, rect, LOCALITY_V); + SetViewportByIndex(mwmsInfo, rect, LOCALITY_V, false); /// @todo Hack - do not search for address in World.mwm; Do it better in future. bool const b = m_worldSearch; diff --git a/search/search_query.hpp b/search/search_query.hpp index e6d79bb362..939ee90b54 100644 --- a/search/search_query.hpp +++ b/search/search_query.hpp @@ -77,7 +77,9 @@ public: void Init(bool viewportSearch); - void SetViewport(m2::RectD const & viewport); + /// @param[in] forceUpdate Pass true (default) to recache feature's ids even + /// if viewport is a part of the old cached rect. + void SetViewport(m2::RectD const & viewport, bool forceUpdate); void SetRankPivot(m2::PointD const & pivot); inline string const & GetPivotRegion() const { return m_region; } @@ -158,7 +160,8 @@ private: typedef map> OffsetsVectorT; typedef feature::DataHeader FHeaderT; - void SetViewportByIndex(MWMVectorT const & mwmsInfo, m2::RectD const & viewport, size_t idx); + void SetViewportByIndex(MWMVectorT const & mwmsInfo, m2::RectD const & viewport, + size_t idx, bool forceUpdate); void UpdateViewportOffsets(MWMVectorT const & mwmsInfo, m2::RectD const & rect, OffsetsVectorT & offsets); void ClearCache(size_t ind);