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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
|
#pragma once
#include "generator/osm_id.hpp"
#include "indexer/feature.hpp"
#include "coding/file_reader.hpp"
#include "coding/read_write_utils.hpp"
#include "std/bind.hpp"
namespace serial { class CodingParams; }
/// Used for serialization\deserialization of features during --generate_features.
class FeatureBuilder1
{
/// For debugging
friend string DebugPrint(FeatureBuilder1 const & f);
public:
using TPointSeq = vector<m2::PointD>;
using TGeometry = list<TPointSeq>;
using TBuffer = vector<char>;
FeatureBuilder1();
/// @name Geometry manipulating functions.
//@{
/// Set center (origin) point of feature and set that feature is point.
void SetCenter(m2::PointD const & p);
/// Add point to geometry.
void AddPoint(m2::PointD const & p);
/// Set that feature is linear type.
void SetLinear(bool reverseGeometry = false);
/// Set that feature is area and get ownership of holes.
void SetAreaAddHoles(TGeometry const & holes);
inline void SetArea() { m_params.SetGeomType(feature::GEOM_AREA); }
inline bool IsLine() const { return (GetGeomType() == feature::GEOM_LINE); }
inline bool IsArea() const { return (GetGeomType() == feature::GEOM_AREA); }
void AddPolygon(vector<m2::PointD> & poly);
//@}
inline feature::Metadata const & GetMetadata() const { return m_params.GetMetadata(); }
inline TGeometry const & GetGeometry() const { return m_polygons; }
inline TPointSeq const & GetOuterGeometry() const { return m_polygons.front(); }
inline feature::EGeomType GetGeomType() const { return m_params.GetGeomType(); }
inline void AddType(uint32_t type) { m_params.AddType(type); }
inline bool HasType(uint32_t t) const { return m_params.IsTypeExist(t); }
inline bool PopExactType(uint32_t type) { return m_params.PopExactType(type); }
inline void SetType(uint32_t type) { m_params.SetType(type); }
inline uint32_t FindType(uint32_t comp, uint8_t level) const { return m_params.FindType(comp, level); }
inline FeatureParams::TTypes const & GetTypes() const { return m_params.m_Types; }
/// Check classificator types for their compatibility with feature geometry type.
/// Need to call when using any classificator types manipulating.
/// @return false If no any valid types.
bool RemoveInvalidTypes();
/// Clear name if it's not visible in scale range [minS, maxS].
void RemoveNameIfInvisible(int minS = 0, int maxS = 1000);
void RemoveUselessNames();
template <class FnT> bool RemoveTypesIf(FnT fn)
{
m_params.m_Types.erase(remove_if(m_params.m_Types.begin(), m_params.m_Types.end(), fn),
m_params.m_Types.end());
return m_params.m_Types.empty();
}
/// @name Serialization.
//@{
void Serialize(TBuffer & data) const;
void SerializeBase(TBuffer & data, serial::CodingParams const & params, bool needSearializeAdditionalInfo = true) const;
void Deserialize(TBuffer & data);
//@}
/// @name Selectors.
//@{
inline m2::RectD GetLimitRect() const { return m_limitRect; }
bool FormatFullAddress(string & res) const;
/// Get common parameters of feature.
FeatureBase GetFeatureBase() const;
bool IsGeometryClosed() const;
m2::PointD GetGeometryCenter() const;
m2::PointD GetKeyPoint() const;
size_t GetPointsCount() const;
inline size_t GetPolygonsCount() const { return m_polygons.size(); }
inline size_t GetTypesCount() const { return m_params.m_Types.size(); }
//@}
/// @name Iterate through polygons points.
/// Stops processing when functor returns false.
//@{
private:
template <class ToDo> class ToDoWrapper
{
ToDo & m_toDo;
public:
ToDoWrapper(ToDo & toDo) : m_toDo(toDo) {}
bool operator() (m2::PointD const & p) { return m_toDo(p); }
void EndRegion() {}
};
public:
template <class ToDo>
void ForEachGeometryPointEx(ToDo & toDo) const
{
if (m_params.GetGeomType() == feature::GEOM_POINT)
toDo(m_center);
else
{
for (TPointSeq const & points : m_polygons)
{
for (auto const & pt : points)
if (!toDo(pt))
return;
toDo.EndRegion();
}
}
}
template <class ToDo>
void ForEachGeometryPoint(ToDo & toDo) const
{
ToDoWrapper<ToDo> wrapper(toDo);
ForEachGeometryPointEx(wrapper);
}
//@}
bool PreSerialize();
/// @note This function overrides all previous assigned types.
/// Set all the parameters, except geometry type (it's set by other functions).
inline void SetParams(FeatureParams const & params) { m_params.SetParams(params); }
inline FeatureParams const & GetParams() const { return m_params; }
/// @name For OSM debugging, store original OSM id
//@{
void AddOsmId(osm::Id id);
void SetOsmId(osm::Id id);
osm::Id GetLastOsmId() const;
string GetOsmIdsString() const;
//@}
uint64_t GetWayIDForRouting() const;
bool AddName(string const & lang, string const & name);
int GetMinFeatureDrawScale() const;
bool IsDrawableInRange(int lowScale, int highScale) const;
void SetCoastCell(int64_t iCell, string const & strCell);
inline bool IsCoastCell() const { return (m_coastCell != -1); }
inline bool GetCoastCell(int64_t & cell) const
{
if (m_coastCell != -1)
{
cell = m_coastCell;
return true;
}
else return false;
}
string GetName(int8_t lang = StringUtf8Multilang::DEFAULT_CODE) const;
uint8_t GetRank() const { return m_params.rank; }
/// @name For diagnostic use only.
//@{
bool operator== (FeatureBuilder1 const &) const;
bool CheckValid() const;
//@}
bool IsRoad() const;
protected:
/// Used for features debugging
vector<osm::Id> m_osmIds;
FeatureParams m_params;
m2::RectD m_limitRect;
/// Can be one of the following:
/// - point in point-feature
/// - origin point of text [future] in line-feature
/// - origin point of text or symbol in area-feature
m2::PointD m_center; // Check HEADER_HAS_POINT
/// List of geometry polygons.
TGeometry m_polygons; // Check HEADER_IS_AREA
/// Not used in GEOM_POINTs
int64_t m_coastCell;
};
/// Used for serialization of features during final pass.
class FeatureBuilder2 : public FeatureBuilder1
{
using TBase = FeatureBuilder1;
using TOffsets = vector<uint32_t>;
static void SerializeOffsets(uint32_t mask, TOffsets const & offsets, TBuffer & buffer);
public:
struct SupportingData
{
/// @name input
//@{
TOffsets m_ptsOffset;
TOffsets m_trgOffset;
uint8_t m_ptsMask;
uint8_t m_trgMask;
uint32_t m_ptsSimpMask;
TPointSeq m_innerPts;
TPointSeq m_innerTrg;
//@}
/// @name output
TBase::TBuffer m_buffer;
SupportingData() : m_ptsMask(0), m_trgMask(0), m_ptsSimpMask(0) {}
};
/// @name Overwrite from base_type.
//@{
bool PreSerialize(SupportingData const & data);
void Serialize(SupportingData & data, serial::CodingParams const & params);
//@}
};
namespace feature
{
/// Read feature from feature source.
template <class TSource>
void ReadFromSourceRowFormat(TSource & src, FeatureBuilder1 & fb)
{
uint32_t const sz = ReadVarUint<uint32_t>(src);
typename FeatureBuilder1::TBuffer buffer(sz);
src.Read(&buffer[0], sz);
fb.Deserialize(buffer);
}
/// Process features in .dat file.
template <class ToDo>
void ForEachFromDatRawFormat(string const & fName, ToDo && toDo)
{
FileReader reader(fName);
ReaderSource<FileReader> src(reader);
uint64_t currPos = 0;
uint64_t const fSize = reader.Size();
// read features one by one
while (currPos < fSize)
{
FeatureBuilder1 fb;
ReadFromSourceRowFormat(src, fb);
toDo(fb, currPos);
currPos = src.Pos();
}
}
}
|