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

retrieval.cpp « search - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4afdb46e2be3373631e63d6893db0e5bde93ebcd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include "retrieval.hpp"

#include "cancel_exception.hpp"
#include "feature_offset_match.hpp"
#include "interval_set.hpp"
#include "search_index_values.hpp"
#include "search_trie.hpp"

#include "v2/mwm_context.hpp"

#include "indexer/feature.hpp"
#include "indexer/feature_algo.hpp"
#include "indexer/index.hpp"
#include "indexer/osm_editor.hpp"
#include "indexer/scales.hpp"
#include "indexer/search_delimiters.hpp"
#include "indexer/search_string_utils.hpp"
#include "indexer/trie_reader.hpp"

#include "platform/mwm_traits.hpp"
#include "platform/mwm_version.hpp"

#include "coding/compressed_bit_vector.hpp"
#include "coding/reader_wrapper.hpp"

#include "std/algorithm.hpp"

using osm::Editor;

namespace search
{
namespace
{

unique_ptr<coding::CompressedBitVector> SortFeaturesAndBuildCBV(vector<uint64_t> && features)
{
  my::SortUnique(features);
  return coding::CompressedBitVectorBuilder::FromBitPositions(move(features));
}

/// Check that any from first matches any from second.
template <class TComp, class T>
bool IsFirstMatchesSecond(vector<T> const & first, vector<T> const & second, TComp const & comp)
{
  if (second.empty())
    return true;

  for (auto const & s : second)
  {
    for (auto const & f : first)
    {
      if (comp(f, s))
        return true;
    }
  }
  return false;
}

bool MatchFeatureByName(FeatureType const & ft, SearchQueryParams const & params)
{
  using namespace strings;

  bool matched = false;
  ft.ForEachName([&](int8_t lang, string const & utf8Name)
  {
    if (utf8Name.empty() || params.m_langs.count(lang) == 0)
      return true;

    vector<UniString> nameTokens;
    SplitUniString(NormalizeAndSimplifyString(utf8Name), MakeBackInsertFunctor(nameTokens), Delimiters());

    auto const matchPrefix = [](UniString const & s1, UniString const & s2)
    {
      return StartsWith(s1, s2);
    };
    if (!IsFirstMatchesSecond(nameTokens, params.m_prefixTokens, matchPrefix))
      return true;

    for (auto const & synonyms : params.m_tokens)
    {
      if (!IsFirstMatchesSecond(nameTokens, synonyms, equal_to<UniString>()))
        return true;
    }

    matched = true;
    return false;
  });

  return matched;
}

// Retrieves from the search index corresponding to |value| all
// features matching to |params|.
template <typename TValue>
unique_ptr<coding::CompressedBitVector> RetrieveAddressFeaturesImpl(
    MwmSet::MwmId const & id, MwmValue & value, my::Cancellable const & cancellable,
    SearchQueryParams const & params)
{
  // Exclude from search all deleted/modified features and match all edited/created features separately.
  Editor & editor = Editor::Instance();

  auto const deleted = editor.GetFeaturesByStatus(id, Editor::FeatureStatus::Deleted);
  auto const modified = editor.GetFeaturesByStatus(id, Editor::FeatureStatus::Modified);
  auto const filter = [&](uint32_t featureIndex) -> bool
  {
    return (!binary_search(deleted.begin(), deleted.end(), featureIndex) &&
            !binary_search(modified.begin(), modified.end(), featureIndex));
  };

  serial::CodingParams codingParams(trie::GetCodingParams(value.GetHeader().GetDefCodingParams()));
  ModelReaderPtr searchReader = value.m_cont.GetReader(SEARCH_INDEX_FILE_TAG);

  auto const trieRoot = trie::ReadTrie<SubReaderWrapper<Reader>, ValueList<TValue>>(
      SubReaderWrapper<Reader>(searchReader.GetPtr()), SingleValueSerializer<TValue>(codingParams));

  // TODO (@y, @m): This code may be optimized in the case where
  // bit vectors are sorted in the search index.
  vector<uint64_t> features;
  uint32_t counter = 0;
  auto const collector = [&](TValue const & value)
  {
    if ((++counter & 0xFF) == 0)
      BailIfCancelled(cancellable);
    features.push_back(value.m_featureId);
  };

  MatchFeaturesInTrie(params, *trieRoot, filter, collector);

  // Match all edited/created features separately.
  auto const matcher = [&](uint32_t featureIndex)
  {
    FeatureType ft;
    VERIFY(editor.GetEditedFeature(id, featureIndex, ft), ());
    // TODO(AlexZ): Should we match by some feature's metafields too?
    if (MatchFeatureByName(ft, params))
      features.push_back(featureIndex);
  };

  for_each(modified.begin(), modified.end(), matcher);
  auto const created = editor.GetFeaturesByStatus(id, Editor::FeatureStatus::Created);
  for_each(created.begin(), created.end(), matcher);

  return SortFeaturesAndBuildCBV(move(features));
}

// Retrieves from the geometry index corresponding to handle all
// features from |coverage|.
unique_ptr<coding::CompressedBitVector> RetrieveGeometryFeaturesImpl(
    v2::MwmContext const & context, my::Cancellable const & cancellable,
    covering::IntervalsT const & coverage, int scale)
{
  uint32_t counter = 0;
  vector<uint64_t> features;

  context.ForEachIndex(coverage, scale, [&](uint64_t featureId)
  {
    if ((++counter & 0xFF) == 0)
      BailIfCancelled(cancellable);
    features.push_back(featureId);
  });

  return SortFeaturesAndBuildCBV(move(features));
}

}  // namespace

namespace v2
{
unique_ptr<coding::CompressedBitVector> RetrieveAddressFeatures(
    MwmSet::MwmId const & id, MwmValue & value, my::Cancellable const & cancellable,
    SearchQueryParams const & params)
{
  version::MwmTraits mwmTraits(value.GetMwmVersion().GetFormat());

  if (mwmTraits.GetSearchIndexFormat() ==
      version::MwmTraits::SearchIndexFormat::FeaturesWithRankAndCenter)
  {
    using TValue = FeatureWithRankAndCenter;
    return RetrieveAddressFeaturesImpl<TValue>(id, value, cancellable, params);
  }
  else if (mwmTraits.GetSearchIndexFormat() ==
           version::MwmTraits::SearchIndexFormat::CompressedBitVector)
  {
    using TValue = FeatureIndexValue;
    return RetrieveAddressFeaturesImpl<TValue>(id, value, cancellable, params);
  }
  return unique_ptr<coding::CompressedBitVector>();
}

unique_ptr<coding::CompressedBitVector> RetrieveGeometryFeatures(
    MwmContext const & context, my::Cancellable const & cancellable,
    m2::RectD const & rect, int scale)
{
  covering::IntervalsT coverage;
  v2::CoverRect(rect, scale, coverage);
  return RetrieveGeometryFeaturesImpl(context, cancellable, coverage, scale);
}

} // namespace v2
} // namespace search