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
|
#pragma once
#include "generator/feature_emitter_iface.hpp"
#include "generator/feature_builder.hpp"
#include <map>
#include <set>
#include <utility>
#include <vector>
/// Feature builder class that used while feature type processing and merging.
class MergedFeatureBuilder1 : public feature::FeatureBuilder
{
bool m_isRound;
PointSeq m_roundBounds[2];
public:
MergedFeatureBuilder1() : m_isRound(false) {}
MergedFeatureBuilder1(feature::FeatureBuilder const & fb);
void SetRound();
bool IsRound() const { return m_isRound; }
void ZeroParams() { m_params.MakeZero(); }
void AppendFeature(MergedFeatureBuilder1 const & fb, bool fromBegin, bool toBack);
bool EqualGeometry(MergedFeatureBuilder1 const & fb) const;
inline bool NotEmpty() const { return !GetOuterGeometry().empty(); }
inline m2::PointD FirstPoint() const { return GetOuterGeometry().front(); }
inline m2::PointD LastPoint() const { return GetOuterGeometry().back(); }
inline bool PopAnyType(uint32_t & type) { return m_params.PopAnyType(type); }
template <class ToDo> void ForEachChangeTypes(ToDo toDo)
{
for_each(m_params.m_types.begin(), m_params.m_types.end(), toDo);
m_params.FinishAddingTypes();
}
template <class ToDo> void ForEachMiddlePoints(ToDo toDo) const
{
PointSeq const & poly = GetOuterGeometry();
for (size_t i = 1; i < poly.size()-1; ++i)
toDo(poly[i]);
}
std::pair<m2::PointD, bool> GetKeyPoint(size_t i) const;
size_t GetKeyPointsCount() const;
double GetPriority() const;
};
/// Feature merger.
class FeatureMergeProcessor
{
typedef int64_t key_t;
key_t get_key(m2::PointD const & p);
MergedFeatureBuilder1 m_last;
typedef std::vector<MergedFeatureBuilder1 *> vector_t;
typedef std::map<key_t, vector_t> map_t;
map_t m_map;
void Insert(m2::PointD const & pt, MergedFeatureBuilder1 * p);
void Remove(key_t key, MergedFeatureBuilder1 const * p);
inline void Remove1(m2::PointD const & pt, MergedFeatureBuilder1 const * p)
{
Remove(get_key(pt), p);
}
void Remove(MergedFeatureBuilder1 const * p);
uint8_t m_coordBits;
public:
FeatureMergeProcessor(uint32_t coordBits);
void operator() (feature::FeatureBuilder const & fb);
void operator() (MergedFeatureBuilder1 * p);
void DoMerge(FeatureEmitterIFace & emitter);
};
/// Feature types corrector.
class FeatureTypesProcessor
{
std::set<uint32_t> m_dontNormalize;
std::map<uint32_t, uint32_t> m_mapping;
static uint32_t GetType(char const * arr[], size_t n);
void CorrectType(uint32_t & t) const;
class do_change_types
{
FeatureTypesProcessor const & m_pr;
public:
do_change_types(FeatureTypesProcessor const & pr) : m_pr(pr) {}
void operator() (uint32_t & t) { m_pr.CorrectType(t); }
};
public:
/// For example: highway-motorway_link-* => highway-motorway.
void SetMappingTypes(char const * arr1[2], char const * arr2[2]);
/// Leave original types, for example: boundary-administrative-2.
template <size_t N> void SetDontNormalizeType(char const * (&arr)[N])
{
m_dontNormalize.insert(GetType(arr, N));
}
MergedFeatureBuilder1 * operator() (feature::FeatureBuilder const & fb);
};
namespace feature
{
/// @return false If fb became invalid (no any suitable types).
//@{
bool PreprocessForWorldMap(FeatureBuilder & fb);
bool PreprocessForCountryMap(FeatureBuilder & fb);
//@}
}
|