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

classificator.hpp « indexer - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f798becd5cf4894a08c55a39130b87e4f6c4fdd2 (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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#pragma once

#include "indexer/drawing_rule_def.hpp"
#include "indexer/feature_decl.hpp"
#include "indexer/map_style.hpp"
#include "indexer/scales.hpp"
#include "indexer/types_mapping.hpp"

#include "base/macros.hpp"

#include <bitset>
#include <initializer_list>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

class ClassifObject;

namespace ftype
{
  inline uint32_t GetEmptyValue() { return 1; }

  void PushValue(uint32_t & type, uint8_t value);
  bool GetValue(uint32_t type, uint8_t level, uint8_t & value);
  void PopValue(uint32_t & type);
  void TruncValue(uint32_t & type, uint8_t level);
  uint8_t GetLevel(uint32_t type);
}

class ClassifObjectPtr
{
  ClassifObject const * m_p;
  size_t m_ind;

public:
  ClassifObjectPtr() : m_p(0), m_ind(0) {}
  ClassifObjectPtr(ClassifObject const * p, size_t i): m_p(p), m_ind(i) {}

  ClassifObject const * get() const { return m_p; }
  ClassifObject const * operator->() const { return m_p; }
  operator bool() const { return (m_p != 0); }

  size_t GetIndex() const { return m_ind; }
};

class ClassifObject
{
  struct less_name_t
  {
    bool operator() (ClassifObject const & r1, ClassifObject const & r2) const
    {
      return (r1.m_name < r2.m_name);
    }
  };

public:
  ClassifObject() {}  // for serialization only
  ClassifObject(std::string const & s) : m_name(s) {}

  /// @name Fill from osm draw rule files.
  //@{
private:
  ClassifObject * AddImpl(std::string const & s);
public:
  ClassifObject * Add(std::string const & s);
  ClassifObject * Find(std::string const & s);

  void AddDrawRule(drule::Key const & k);
  //@}

  /// @name Find substitution when reading osm features.
  //@{
  ClassifObjectPtr BinaryFind(std::string const & s) const;
  //@}

  void Sort();
  void Swap(ClassifObject & r);

  std::string const & GetName() const { return m_name; }
  ClassifObject const * GetObject(size_t i) const;

  void ConcatChildNames(std::string & s) const;

  void GetSuitable(int scale, feature::GeomType gt, drule::KeysT & keys) const;
  inline std::vector<drule::Key> const & GetDrawingRules() const { return m_drawRule; }

  bool IsDrawable(int scale) const;
  bool IsDrawableAny() const;
  bool IsDrawableLike(feature::GeomType gt, bool emptyName = false) const;

  std::pair<int, int> GetDrawScaleRange() const;

  template <typename ToDo>
  void ForEachObject(ToDo && toDo)
  {
    for (size_t i = 0; i < m_objs.size(); ++i)
      toDo(&m_objs[i]);
  }

  template <typename ToDo>
  void ForEachObjectInTree(ToDo && toDo, uint32_t const start) const
  {
    for (size_t i = 0; i < m_objs.size(); ++i)
    {
      uint32_t type = start;

      ftype::PushValue(type, static_cast<uint8_t>(i));

      toDo(&m_objs[i], type);

      m_objs[i].ForEachObjectInTree(toDo, type);
    }
  }

  using VisibleMask = std::bitset<scales::UPPER_STYLE_SCALE+1>;
  void SetVisibilityOnScale(bool isVisible, int scale) { m_visibility[scale] = isVisible; }

  /// @name Policies for classificator tree serialization.
  //@{
  class BasePolicy
  {
  protected:
    std::vector<ClassifObject *> m_stack;
    ClassifObject * Current() const { return m_stack.back(); }

  public:
    BasePolicy(ClassifObject * pRoot) { m_stack.push_back(pRoot); }

    void Start(size_t i) { m_stack.push_back(&(Current()->m_objs[i])); }
    void End() { m_stack.pop_back(); }
  };

  class LoadPolicy : public BasePolicy
  {
    typedef BasePolicy base_type;
  public:
    LoadPolicy(ClassifObject * pRoot) : base_type(pRoot) {}

    void Name(std::string const & name) { Current()->m_name = name; }
    void Start(size_t i);
    void EndChilds();
  };
  //@}

private:
  std::string m_name;
  std::vector<drule::Key> m_drawRule;
  std::vector<ClassifObject> m_objs;
  VisibleMask m_visibility;
};

inline void swap(ClassifObject & r1, ClassifObject & r2)
{
  r1.Swap(r2);
}

class Classificator
{
public:
  Classificator() : m_root("world") {}

  ClassifObject * Add(ClassifObject * parent, std::string const & key, std::string const & value);

  /// @name Serialization-like functions.
  //@{
  void ReadClassificator(std::istream & s);
  void ReadTypesMapping(std::istream & s);
  //@}

  void Clear();

  bool HasTypesMapping() const { return m_mapping.IsLoaded(); }

  /// @return 0 in case of nonexisting type
  uint32_t GetTypeByPathSafe(std::vector<std::string> const & path) const;
  /// Invokes ASSERT in case of nonexisting type
  uint32_t GetTypeByPath(std::vector<std::string> const & path) const;
  uint32_t GetTypeByPath(std::initializer_list<char const *> const & lst) const;
  /// @see GetReadableObjectName().
  /// @returns 0 in case of nonexisting type.
  uint32_t GetTypeByReadableObjectName(std::string const & name) const;
  //@}

  uint32_t GetIndexForType(uint32_t t) const { return m_mapping.GetIndex(t); }
  // Throws std::out_of_range exception.
  uint32_t GetTypeForIndex(uint32_t i) const { return m_mapping.GetType(i); }
  bool IsTypeValid(uint32_t t) const { return m_mapping.HasIndex(t); }

  inline uint32_t GetCoastType() const { return m_coastType; }

  /// @name used in osm2type.cpp, not for public use.
  //@{
  ClassifObject const * GetRoot() const { return &m_root; }
  ClassifObject * GetMutableRoot() { return &m_root; }
  //@}

  /// Iterate through all classificator tree.
  /// Functor receives pointer to object and uint32 type.
  template <typename ToDo>
  void ForEachTree(ToDo && toDo) const
  {
    GetRoot()->ForEachObjectInTree(std::forward<ToDo>(toDo), ftype::GetEmptyValue());
  }

  template <typename ToDo>
  void ForEachInSubtree(ToDo && toDo, uint32_t root) const
  {
    toDo(root);
    GetObject(root)->ForEachObjectInTree([&toDo](ClassifObject const *, uint32_t c) { toDo(c); },
                                         root);
  }

  /// @name Used only in feature_visibility.cpp, not for public use.
  //@{
  template <typename ToDo>
  typename ToDo::ResultType ProcessObjects(uint32_t type, ToDo & toDo) const;

  ClassifObject const * GetObject(uint32_t type) const;
  std::string GetFullObjectName(uint32_t type) const;
  //@}

  /// @return Object name to show in UI (not for debug purposes).
  std::string GetReadableObjectName(uint32_t type) const;

private:
  static ClassifObject * AddV(ClassifObject * parent, std::string const & key,
                              std::string const & value);

  /// Return type by path in classificator tree, for example
  /// path = ["natural", "caostline"].
  //@{
  template <typename Iter>
  uint32_t GetTypeByPathImpl(Iter beg, Iter end) const;

  ClassifObject m_root;
  IndexAndTypeMapping m_mapping;
  uint32_t m_coastType;

  DISALLOW_COPY_AND_MOVE(Classificator);
};

Classificator & classif();