From 57ddd9fb195a104e6066aa3c4f1003c9eae03733 Mon Sep 17 00:00:00 2001 From: Yury Melnichek Date: Tue, 27 Sep 2011 21:46:47 +0200 Subject: [PATCH] [search] Return name that matches best. --- search/intermediate_result.cpp | 5 ++-- search/intermediate_result.hpp | 3 ++- search/search_query.cpp | 48 +++++++++++++++++++++++++++++++++- search/search_query.hpp | 10 ++++++- 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/search/intermediate_result.cpp b/search/intermediate_result.cpp index 050ee77a9f..ee662cce23 100644 --- a/search/intermediate_result.cpp +++ b/search/intermediate_result.cpp @@ -11,8 +11,9 @@ namespace impl { IntermediateResult::IntermediateResult(m2::RectD const & viewportRect, - FeatureType const & feature) - : m_str(feature.GetPreferredDrawableName()), m_rect(feature::GetFeatureViewport(feature)), + FeatureType const & feature, + string const & displayName) + : m_str(displayName), m_rect(feature::GetFeatureViewport(feature)), m_resultType(RESULT_FEATURE) { FeatureType::GetTypesFn types; diff --git a/search/intermediate_result.hpp b/search/intermediate_result.hpp index e65067022d..7cee945c5b 100644 --- a/search/intermediate_result.hpp +++ b/search/intermediate_result.hpp @@ -19,7 +19,8 @@ public: // For RESULT_FEATURE. IntermediateResult(m2::RectD const & viewportRect, - FeatureType const & feature); + FeatureType const & feature, + string const & displayName); // For RESULT_LATLON. IntermediateResult(m2::RectD const & viewportRect, double lat, double lon, double precision); diff --git a/search/search_query.cpp b/search/search_query.cpp index 283daa45fc..ee28cf25fe 100644 --- a/search/search_query.cpp +++ b/search/search_query.cpp @@ -1,6 +1,7 @@ #include "search_query.hpp" #include "categories_holder.hpp" #include "feature_offset_match.hpp" +#include "keyword_matcher.hpp" #include "latlon_match.hpp" #include "result.hpp" #include "../indexer/feature_covering.hpp" @@ -107,6 +108,8 @@ void Query::Search(string const & query, if (m_tokens.size() > 31) m_tokens.resize(31); + m_pKeywordMatcher.reset(new KeywordMatcher(m_tokens.data(), (int)m_tokens.size(), &m_prefix)); + m_results = my::limited_priority_queue(resultsNeeded); } @@ -138,6 +141,49 @@ void Query::FlushResults(function const & f) f(it->GenerateFinalResult()); } +void Query::AddFeatureResult(FeatureType const & feature) +{ + uint32_t penalty; + string name; + GetBestMatchName(feature, penalty, name); + AddResult(impl::IntermediateResult(m_viewport, feature, name)); +} + +namespace impl +{ + +class BestNameFinder +{ + uint32_t & m_penalty; + string & m_name; + KeywordMatcher & m_keywordMatcher; +public: + BestNameFinder(uint32_t & penalty, string & name, KeywordMatcher & keywordMatcher) + : m_penalty(penalty), m_name(name), m_keywordMatcher(keywordMatcher) + { + m_penalty = uint32_t(-1); + } + + bool operator()(signed char, string const & name) const + { + uint32_t penalty = m_keywordMatcher.Score(name); + if (penalty < m_penalty) + { + m_penalty = penalty; + m_name = name; + } + return true; + } +}; + +} // namespace search::impl + +void Query::GetBestMatchName(FeatureType const & feature, uint32_t & penalty, string & name) +{ + impl::BestNameFinder bestNameFinder(penalty, name, *m_pKeywordMatcher); + feature.ForEachNameRef(bestNameFinder); +} + namespace impl { @@ -157,7 +203,7 @@ struct FeatureLoader ++m_count; FeatureType feature; m_featuresVector.Get(offset, feature); - m_query.AddResult(impl::IntermediateResult(m_query.m_viewport, feature)); + m_query.AddFeatureResult(feature); } }; diff --git a/search/search_query.hpp b/search/search_query.hpp index 2452b3c58e..4ce04cce59 100644 --- a/search/search_query.hpp +++ b/search/search_query.hpp @@ -4,17 +4,20 @@ #include "../base/buffer_vector.hpp" #include "../base/limited_priority_queue.hpp" #include "../std/function.hpp" +#include "../std/scoped_ptr.hpp" #include "../std/string.hpp" #include "../std/unordered_set.hpp" #include "../std/vector.hpp" +class FeatureType; class Index; namespace search { class CategoriesHolder; -namespace impl { class IntermediateResult; class FeatureLoader; } +class KeywordMatcher; +namespace impl { class IntermediateResult; class FeatureLoader; class BestNameFinder; } class Query { @@ -30,11 +33,14 @@ public: private: friend class impl::FeatureLoader; + friend class impl::BestNameFinder; void AddResult(impl::IntermediateResult const & result); + void AddFeatureResult(FeatureType const & feature); void FlushResults(function const & f); void UpdateViewportOffsets(); void SearchFeatures(); + void GetBestMatchName(FeatureType const & feature, uint32_t & penalty, string & name); Index const * m_pIndex; CategoriesHolder const * m_pCategories; @@ -46,6 +52,8 @@ private: m2::RectD m_viewport; m2::RectD m_viewportExtended; + scoped_ptr m_pKeywordMatcher; + vector > m_offsetsInViewport; my::limited_priority_queue m_results;