From 41013614768eddbccf24c4c7f788add6db3a95ec Mon Sep 17 00:00:00 2001 From: vng Date: Fri, 11 Jan 2013 19:24:35 +0300 Subject: [search] Temporary solution: sort results by it's real distance for AROUND_POSITION search mode. --- search/intermediate_result.cpp | 43 ++++++++++++++++++++++-------------------- search/intermediate_result.hpp | 6 +++++- search/params.hpp | 2 +- search/result.hpp | 5 +++++ search/search_engine.cpp | 33 ++++++++++++++++++++++++++++++-- search/search_query.cpp | 12 +++++++----- 6 files changed, 72 insertions(+), 29 deletions(-) (limited to 'search') diff --git a/search/intermediate_result.cpp b/search/intermediate_result.cpp index 0b067a8348..ed6ac77ee9 100644 --- a/search/intermediate_result.cpp +++ b/search/intermediate_result.cpp @@ -133,25 +133,31 @@ bool PreResult1::LessViewportDistance(PreResult1 const & r1, PreResult1 const & } +void PreResult2::CalcParams(m2::RectD const & viewport, m2::PointD const & pos) +{ + // dummy object to avoid copy-paste + PreResult1 res(0, 0, m_center, 0, pos, viewport); + + m_distance = res.m_distance; + m_distanceFromViewportCenter = res.m_distanceFromViewportCenter; + m_viewportDistance = res.m_viewportDistance; +} -PreResult2::PreResult2(FeatureType const & f, PreResult1 const & res, +PreResult2::PreResult2(FeatureType const & f, uint8_t rank, + m2::RectD const & viewport, m2::PointD const & pos, string const & displayName, string const & fileName) : m_types(f), m_str(displayName), - m_featureRect(f.GetLimitRect(FeatureType::WORST_GEOMETRY)), - m_center(res.m_center), - m_distance(res.m_distance), - m_distanceFromViewportCenter(res.m_distanceFromViewportCenter), m_resultType(RESULT_FEATURE), - m_rank(res.m_rank), - m_viewportDistance(res.m_viewportDistance) + m_rank(rank) { ASSERT ( !m_types.Empty(), () ); m_types.SortBySpec(); - // It's better to get exact center for point feature. - if (f.GetFeatureType() == feature::GEOM_POINT) - m_center = m_featureRect.Center(); + m_featureRect = f.GetLimitRect(FeatureType::WORST_GEOMETRY); + m_center = m_featureRect.Center(); + + CalcParams(viewport, pos); // get region info if (!fileName.empty()) @@ -160,19 +166,16 @@ PreResult2::PreResult2(FeatureType const & f, PreResult1 const & res, m_region.SetPoint(m_center); } -PreResult2::PreResult2(m2::RectD const & viewport, m2::PointD const & pos, - double lat, double lon) +PreResult2::PreResult2(m2::RectD const & viewport, m2::PointD const & pos, double lat, double lon) : m_str("(" + strings::to_string(lat) + ", " + strings::to_string(lon) + ")"), - m_resultType(RESULT_LATLON), m_rank(255) + m_resultType(RESULT_LATLON), + m_rank(255) { - // dummy object to avoid copy-paste - PreResult1 res(0, 0, m2::PointD(MercatorBounds::LonToX(lon), MercatorBounds::LatToY(lat)), - 0, pos, viewport); + m_center.x = MercatorBounds::LonToX(lon); + m_center.y = MercatorBounds::LatToY(lat); + m_featureRect.Add(m_center); - m_center = res.m_center; - m_distance = res.m_distance; - m_distanceFromViewportCenter = res.m_distanceFromViewportCenter; - m_viewportDistance = res.m_viewportDistance; + CalcParams(viewport, pos); // get region info m_region.SetPoint(m_center); diff --git a/search/intermediate_result.hpp b/search/intermediate_result.hpp index ea87a2a7f8..0bd2e42945 100644 --- a/search/intermediate_result.hpp +++ b/search/intermediate_result.hpp @@ -53,12 +53,15 @@ public: static bool LessViewportDistance(PreResult1 const & r1, PreResult1 const & r2); inline pair GetID() const { return make_pair(m_mwmID, m_featureID); } + uint8_t GetRank() const { return m_rank; } }; /// Second result class. Objects are creating during reading of features. class PreResult2 { + void CalcParams(m2::RectD const & viewport, m2::PointD const & pos); + public: enum ResultType { @@ -68,7 +71,8 @@ public: }; // For RESULT_FEATURE. - PreResult2(FeatureType const & f, PreResult1 const & res, + PreResult2(FeatureType const & f, uint8_t rank, + m2::RectD const & viewport, m2::PointD const & pos, string const & displayName, string const & fileName); // For RESULT_LATLON. diff --git a/search/params.hpp b/search/params.hpp index 71bcd7c4c9..c1e57648f5 100644 --- a/search/params.hpp +++ b/search/params.hpp @@ -34,7 +34,7 @@ namespace search }; void SetSearchMode(int mode) { m_searchMode = mode; } - bool NeedSearch(SearchModeT mode) const { return ((m_searchMode & mode) != 0);} + bool NeedSearch(SearchModeT mode) const { return ((m_searchMode & mode) != 0); } //@} void SetPosition(double lat, double lon); diff --git a/search/result.hpp b/search/result.hpp index 6a1326b804..88c3221dbe 100644 --- a/search/result.hpp +++ b/search/result.hpp @@ -100,6 +100,11 @@ public: { m_vec.swap(rhs.m_vec); } + + template void Sort(LessT lessFn) + { + sort(m_vec.begin(), m_vec.end(), lessFn); + } }; } diff --git a/search/search_engine.cpp b/search/search_engine.cpp index 3807311c7a..b0e78991cb 100644 --- a/search/search_engine.cpp +++ b/search/search_engine.cpp @@ -185,6 +185,35 @@ void Engine::SetViewportAsync(m2::RectD const & viewport, m2::RectD const & near m_pQuery->SetViewport(arrRects, ARRAY_SIZE(arrRects)); } +namespace +{ + bool LessByDistance(Result const & r1, Result const & r2) + { + Result::ResultType const t1 = r1.GetResultType(); + + if (t1 == r2.GetResultType() && t1 == Result::RESULT_FEATURE) + return (r1.GetDistanceFromCenter() < r2.GetDistanceFromCenter()); + else if (t1 == Result::RESULT_SUGGESTION) + return true; + else + return false; + } + + /// @todo Temporary solution to ensure that results are sorted by distance only for AROUND_POSITION mode. + void EmitResults(SearchParams const & params, Results & res) + { + if (params.IsValidPosition() && + params.NeedSearch(SearchParams::AROUND_POSITION) && + !params.NeedSearch(SearchParams::IN_VIEWPORT) && + !params.NeedSearch(SearchParams::SEARCH_WORLD)) + { + res.Sort(&LessByDistance); + } + + params.m_callback(res); + } +} + void Engine::SearchAsync() { { @@ -287,7 +316,7 @@ void Engine::SearchAsync() // Emit results even if search was canceled and we have something. size_t const count = res.GetCount(); if (!m_pQuery->IsCanceled() || count > 0) - params.m_callback(res); + 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) @@ -304,7 +333,7 @@ void Engine::SearchAsync() // Emit if we have more results. if (res.GetCount() > count) - params.m_callback(res); + EmitResults(params, res); } // Emit finish marker to client. diff --git a/search/search_query.cpp b/search/search_query.cpp index 5eb8088943..ec7d210070 100644 --- a/search/search_query.cpp +++ b/search/search_query.cpp @@ -462,7 +462,9 @@ namespace impl string name, country; LoadFeature(res.GetID(), feature, name, country); - return new impl::PreResult2(feature, res, name, country); + return new impl::PreResult2(feature, res.GetRank(), + m_query.GetViewport(), m_query.GetPosition(), + name, country); } impl::PreResult2 * operator() (pair const & id) @@ -473,10 +475,10 @@ namespace impl if (!name.empty() && !country.empty()) { - // this results will be with equal rank - impl::PreResult1 res(0, 0, feature.GetLimitRect(FeatureType::WORST_GEOMETRY).Center(), - 0, m_query.m_position, m_query.GetViewport()); - return new impl::PreResult2(feature, res, name, country); + // this results will be with equal rank == 0 + return new impl::PreResult2(feature, 0, + m_query.GetViewport(), m_query.GetPosition(), + name, country); } else return 0; -- cgit v1.2.3