diff --git a/search/intermediate_result.cpp b/search/intermediate_result.cpp index 71c3a512cb..25461c7d98 100644 --- a/search/intermediate_result.cpp +++ b/search/intermediate_result.cpp @@ -93,17 +93,19 @@ template bool LessDistanceT(T const & r1, T const & r2) PreResult1::PreResult1(FeatureID const & fID, uint8_t rank, m2::PointD const & center, m2::PointD const & pos, m2::RectD const & viewport, int8_t viewportID) : m_id(fID), + m_center(center), m_rank(rank), m_viewportID(viewportID) { ASSERT(m_id.IsValid(), ()); - CalcParams(center, viewport, pos); + CalcParams(viewport, pos); } PreResult1::PreResult1(m2::PointD const & center, m2::PointD const & pos, m2::RectD const & viewport) + : m_center(center) { - CalcParams(center, viewport, pos); + CalcParams(viewport, pos); } namespace @@ -117,15 +119,15 @@ void AssertValid(m2::PointD const & p) } -void PreResult1::CalcParams(m2::PointD const & fCenter, m2::RectD const & viewport, m2::PointD const & pos) +void PreResult1::CalcParams(m2::RectD const & viewport, m2::PointD const & pos) { - AssertValid(fCenter); + AssertValid(m_center); // Check if point is valid (see Query::empty_pos_value). if (pos.x > -500 && pos.y > -500) { AssertValid(pos); - m_distance = ResultDistance(fCenter, pos); + m_distance = ResultDistance(m_center, pos); } else { @@ -133,8 +135,8 @@ void PreResult1::CalcParams(m2::PointD const & fCenter, m2::RectD const & viewpo m_distance = -1.0; } - m_viewportDistance = ViewportDistance(viewport, fCenter); - m_distanceFromViewportCenter = ResultDistance(fCenter, viewport.Center()); + m_viewportDistance = ViewportDistance(viewport, m_center); + m_distanceFromViewportCenter = ResultDistance(m_center, viewport.Center()); } bool PreResult1::LessRank(PreResult1 const & r1, PreResult1 const & r2) @@ -153,33 +155,42 @@ bool PreResult1::LessViewportDistance(PreResult1 const & r1, PreResult1 const & } -void PreResult2::CalcParams(m2::PointD const & fCenter, m2::RectD const & viewport, m2::PointD const & pos) +void PreResult2::CalcParams(m2::RectD const & viewport, m2::PointD const & pos) { // dummy object to avoid copy-paste - PreResult1 res(fCenter, pos, viewport); + PreResult1 res(GetCenter(), pos, viewport); m_distance = res.m_distance; m_distanceFromViewportCenter = res.m_distanceFromViewportCenter; m_viewportDistance = res.m_viewportDistance; } -PreResult2::PreResult2(FeatureType const & f, uint8_t rank, +PreResult2::PreResult2(FeatureType const & f, PreResult1 const * p, m2::RectD const & viewport, m2::PointD const & pos, string const & displayName, string const & fileName) : m_id(f.GetID()), m_types(f), m_str(displayName), - m_resultType(RESULT_FEATURE), - m_rank(rank) + m_resultType(RESULT_FEATURE) { ASSERT(m_id.IsValid(), ()); ASSERT(!m_types.Empty(), ()); m_types.SortBySpec(); - m2::PointD const fCenter = f.GetLimitRect(FeatureType::WORST_GEOMETRY).Center(); - CalcParams(fCenter, viewport, pos); + m_rank = p ? p->GetRank() : 0; + + m2::PointD fCenter; + if (p && f.GetFeatureType() != feature::GEOM_POINT) + { + // Optimization tip - use precalculated center point if possible. + fCenter = p->GetCenter(); + } + else + fCenter = f.GetLimitRect(FeatureType::WORST_GEOMETRY).Center(); + m_region.SetParams(fileName, fCenter); + CalcParams(viewport, pos); } PreResult2::PreResult2(m2::RectD const & viewport, m2::PointD const & pos, double lat, double lon) @@ -188,8 +199,8 @@ PreResult2::PreResult2(m2::RectD const & viewport, m2::PointD const & pos, doubl m_rank(255) { m2::PointD const fCenter(MercatorBounds::LonToX(lon), MercatorBounds::LatToY(lat)); - CalcParams(fCenter, viewport, pos); m_region.SetParams(string(), fCenter); + CalcParams(viewport, pos); } PreResult2::PreResult2(string const & name, int penalty) diff --git a/search/intermediate_result.hpp b/search/intermediate_result.hpp index bfac8baab6..fa0d91748e 100644 --- a/search/intermediate_result.hpp +++ b/search/intermediate_result.hpp @@ -32,12 +32,13 @@ class PreResult1 template friend bool LessDistanceT(T const & r1, T const & r2); FeatureID m_id; + m2::PointD m_center; double m_distance, m_distanceFromViewportCenter; uint8_t m_viewportDistance; uint8_t m_rank; int8_t m_viewportID; - void CalcParams(m2::PointD const & fCenter, m2::RectD const & viewport, m2::PointD const & pos); + void CalcParams(m2::RectD const & viewport, m2::PointD const & pos); public: PreResult1(FeatureID const & fID, uint8_t rank, m2::PointD const & center, @@ -49,6 +50,7 @@ public: static bool LessViewportDistance(PreResult1 const & r1, PreResult1 const & r2); inline FeatureID GetID() const { return m_id; } + inline m2::PointD GetCenter() const { return m_center; } inline uint8_t GetRank() const { return m_rank; } inline int8_t GetViewportID() const { return m_viewportID; } }; @@ -58,7 +60,7 @@ public: /// Read and fill needed info for ranking and getting final results. class PreResult2 { - void CalcParams(m2::PointD const & fCenter, m2::RectD const & viewport, m2::PointD const & pos); + void CalcParams(m2::RectD const & viewport, m2::PointD const & pos); public: enum ResultType @@ -69,7 +71,7 @@ public: }; // For RESULT_FEATURE. - PreResult2(FeatureType const & f, uint8_t rank, + PreResult2(FeatureType const & f, PreResult1 const * p, m2::RectD const & viewport, m2::PointD const & pos, string const & displayName, string const & fileName); diff --git a/search/search_query.cpp b/search/search_query.cpp index 4929b264f1..8986955c0b 100644 --- a/search/search_query.cpp +++ b/search/search_query.cpp @@ -461,7 +461,7 @@ namespace impl LoadFeature(res.GetID(), feature, name, country); int8_t const viewportID = res.GetViewportID(); - return new impl::PreResult2(feature, res.GetRank(), + return new impl::PreResult2(feature, &res, m_query.GetViewport(viewportID), m_query.GetPosition(viewportID), name, country); } @@ -474,7 +474,6 @@ namespace impl if (!name.empty() && !country.empty()) { - // this results will be with equal rank == 0 return new impl::PreResult2(feature, 0, m_query.GetViewport(), m_query.GetPosition(), name, country);