Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/search
diff options
context:
space:
mode:
authorvng <viktor.govako@gmail.com>2012-09-04 20:13:07 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:43:05 +0300
commit3aabb33fb24db5204d58f9325db8c481ed961669 (patch)
tree2a8cd54e54088a585eaea203c42f7358ae080a2c /search
parentfd9b04c2b8db649e2f4892f50077e8310fd951ba (diff)
[search] Skip numbers in search query and add synonyms for US streets (North, West, etc).
Diffstat (limited to 'search')
-rw-r--r--search/search_query.cpp112
-rw-r--r--search/search_query.hpp51
2 files changed, 139 insertions, 24 deletions
diff --git a/search/search_query.cpp b/search/search_query.cpp
index b29bd6a6e8..479a96b243 100644
--- a/search/search_query.cpp
+++ b/search/search_query.cpp
@@ -708,8 +708,10 @@ Query::Params::Params(Query const & q, bool isLocalities/* = false*/)
FillLanguages(q);
}
-void Query::Params::EraseTokens(vector<size_t> const & eraseInds)
+void Query::Params::EraseTokens(vector<size_t> & eraseInds)
{
+ eraseInds.erase(unique(eraseInds.begin(), eraseInds.end()), eraseInds.end());
+
// fill temporary vector
vector<TokensVectorT> newTokens;
@@ -741,6 +743,111 @@ void Query::Params::EraseTokens(vector<size_t> const & eraseInds)
}
}
+template <class ToDo> void Query::Params::ForEachToken(ToDo toDo)
+{
+ size_t const count = m_tokens.size();
+ for (size_t i = 0; i < count; ++i)
+ {
+ ASSERT ( !m_tokens[i].empty(), () );
+ ASSERT ( !m_tokens[i].front().empty(), () );
+ toDo(m_tokens[i].front(), i);
+ }
+
+ if (!m_prefixTokens.empty())
+ {
+ ASSERT ( !m_prefixTokens.front().empty(), () );
+ toDo(m_prefixTokens.front(), count);
+ }
+}
+
+namespace
+{
+ bool IsNumber(strings::UniString const & s)
+ {
+ for (size_t i = 0; i < s.size(); ++i)
+ if (!isdigit(s[i]))
+ return false;
+ return true;
+ }
+
+ class DoStoreNumbers
+ {
+ vector<size_t> & m_vec;
+ public:
+ DoStoreNumbers(vector<size_t> & vec) : m_vec(vec) {}
+ void operator() (Query::Params::StringT const & s, size_t i)
+ {
+ /// @todo Do smart filtering of house numbers and zipcodes.
+ if (IsNumber(s))
+ m_vec.push_back(i);
+ }
+ };
+
+ class DoAddStreetSynonyms
+ {
+ Query::Params & m_params;
+
+ Query::Params::TokensVectorT & GetTokens(size_t i)
+ {
+ size_t const count = m_params.m_tokens.size();
+ if (i < count)
+ return m_params.m_tokens[i];
+ else
+ {
+ ASSERT_EQUAL ( i, count, () );
+ return m_params.m_prefixTokens;
+ }
+ }
+
+ void AddSynonym(size_t i, string const & sym)
+ {
+ GetTokens(i).push_back(strings::MakeUniString(sym));
+ }
+
+ public:
+ DoAddStreetSynonyms(Query::Params & params) : m_params(params) {}
+
+ void operator() (Query::Params::StringT const & s, size_t i)
+ {
+ if (s.size() <= 2)
+ {
+ string const ss = strings::ToUtf8(strings::MakeLowerCase(s));
+
+ // All synonyms should be lowercase!
+ if (ss == "n")
+ AddSynonym(i, "north");
+ else if (ss == "w")
+ AddSynonym(i, "west");
+ else if (ss == "s")
+ AddSynonym(i, "south");
+ else if (ss == "e")
+ AddSynonym(i, "east");
+ else if (ss == "nw")
+ AddSynonym(i, "northwest");
+ else if (ss == "ne")
+ AddSynonym(i, "northeast");
+ else if (ss == "sw")
+ AddSynonym(i, "southwest");
+ else if (ss == "se")
+ AddSynonym(i, "southeast");
+ }
+ }
+ };
+}
+
+void Query::Params::ProcessAddressTokens()
+{
+ // 1. Do simple stuff - erase all number tokens.
+ // Assume that USA street name numbers endswith "st, nd, rd, th" suffixes.
+
+ vector<size_t> toErase;
+ ForEachToken(DoStoreNumbers(toErase));
+ EraseTokens(toErase);
+
+ // 2. Add synonyms for N, NE, NW, etc.
+ ForEachToken(DoAddStreetSynonyms(*this));
+}
+
void Query::Params::FillLanguages(Query const & q)
{
for (int i = 0; i < LANG_COUNT; ++i)
@@ -891,6 +998,8 @@ void Query::SearchAddress()
if (!params.IsEmpty())
{
+ params.ProcessAddressTokens();
+
SetViewportByIndex(mwmInfo, scales::GetRectForLevel(ADDRESS_SCALE, loc.m_value.m_pt, 1.0), ADDRESS_RECT_ID);
/// @todo Hack - do not search for address in World.mwm; Do it better in future.
@@ -1427,6 +1536,7 @@ m2::RectD const & Query::GetViewport(int viewportID/* = -1*/) const
return m_viewport[1];
}
}
+
m2::PointD Query::GetPosition(int viewportID/* = -1*/) const
{
if (viewportID == ADDRESS_RECT_ID)
diff --git a/search/search_query.hpp b/search/search_query.hpp
index b025238d5b..575fd66567 100644
--- a/search/search_query.hpp
+++ b/search/search_query.hpp
@@ -86,6 +86,34 @@ public:
typedef trie::ValueReader::ValueType TrieValueT;
+ struct Params
+ {
+ typedef strings::UniString StringT;
+ typedef vector<StringT> TokensVectorT;
+ typedef unordered_set<int8_t> LangsSetT;
+
+ vector<TokensVectorT> m_tokens;
+ TokensVectorT m_prefixTokens;
+ LangsSetT m_langs;
+
+ /// Initialize search params (tokens, languages).
+ /// @param[in] isLocalities Use true when search for locality in World.
+ Params(Query const & q, bool isLocalities = false);
+
+ /// @param[in] eraseInds Sorted vector of token's indexes.
+ void EraseTokens(vector<size_t> & eraseInds);
+
+ void ProcessAddressTokens();
+
+ bool IsEmpty() const { return (m_tokens.empty() && m_prefixTokens.empty()); }
+ bool IsLangExist(int8_t l) const { return (m_langs.count(l) > 0); }
+
+ private:
+ template <class ToDo> void ForEachToken(ToDo toDo);
+
+ void FillLanguages(Query const & q);
+ };
+
private:
friend class impl::FeatureLoader;
friend class impl::BestNameFinder;
@@ -108,29 +136,6 @@ private:
void FlushResults(Results & res, void (Results::*pAddFn)(Result const &));
- struct Params
- {
- typedef vector<strings::UniString> TokensVectorT;
- typedef unordered_set<int8_t> LangsSetT;
-
- vector<TokensVectorT> m_tokens;
- TokensVectorT m_prefixTokens;
- LangsSetT m_langs;
-
- /// Initialize search params (tokens, languages).
- /// @param[in] isLocalities Use true when search for locality in World.
- Params(Query const & q, bool isLocalities = false);
-
- /// @param[in] eraseInds Sorted vector of token's indexes.
- void EraseTokens(vector<size_t> const & eraseInds);
-
- bool IsEmpty() const { return (m_tokens.empty() && m_prefixTokens.empty()); }
- bool IsLangExist(int8_t l) const { return (m_langs.count(l) > 0); }
-
- private:
- void FillLanguages(Query const & q);
- };
-
void SearchAddress();
bool SearchLocality(MwmValue * pMwm, impl::Locality & res);