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: 2db65bb8221c960e04fa349e5807c7f677a638a8 (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
#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 "std/bitset.hpp"
#include "std/initializer_list.hpp"
#include "std/iostream.hpp"
#include "std/noncopyable.hpp"
#include "std/string.hpp"
#include "std/vector.hpp"

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(string const & s) : m_name(s) {}

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

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

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

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

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

  void ConcatChildNames(string & s) const;

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

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

  pair<int, int> GetDrawScaleRange() const;

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

  template <class 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);
    }
  }

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

  /// @name Policies for classificator tree serialization.
  //@{
  class BasePolicy
  {
  protected:
    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(string const & name) { Current()->m_name = name; }
    void Start(size_t i);
    void EndChilds();
  };
  //@}

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

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

class Classificator : private noncopyable
{
  ClassifObject m_root;

  IndexAndTypeMapping m_mapping;

  uint32_t m_coastType;

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

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

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

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

  void SortClassificator();
  //@}

  void Clear();

  /// Return type by path in classificator tree, for example
  /// path = ["natural", "caostline"].
  //@{
private:
  template <class IterT> uint32_t GetTypeByPathImpl(IterT beg, IterT end) const;
public:
  /// @return 0 in case of nonexisting type
  uint32_t GetTypeByPathSafe(vector<string> const & path) const;
  /// Invokes ASSERT in case of nonexisting type
  uint32_t GetTypeByPath(vector<string> const & path) const;
  uint32_t GetTypeByPath(initializer_list<char const *> const & lst) const;
  /// @see GetReadableObjectName().
  /// @returns 0 in case of nonexisting type.
  uint32_t GetTypeByReadableObjectName(string const & name) const;
  //@}

  uint32_t GetIndexForType(uint32_t t) const { return m_mapping.GetIndex(t); }
  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 <class ToDo> void ForEachTree(ToDo & toDo) const
  {
    GetRoot()->ForEachObjectInTree(toDo, ftype::GetEmptyValue());
  }

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

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

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

Classificator & classif();