29
29
#include < rapidjson/writer.h>
30
30
31
31
namespace {
32
- void WriteSubquadsToJson (rapidjson::Document& doc,
33
- const olp::geo::TileKey& root_tile,
34
- const std::vector<std::uint16_t >& sub_quads,
35
- rapidjson::Document::AllocatorType& allocator) {
32
+
33
+ void WriteSubquadsToJson (
34
+ rapidjson::Document& doc, const olp::geo::TileKey& root_tile,
35
+ const std::map<std::uint64_t , mockserver::TileMetadata>& sub_quads,
36
+ rapidjson::Document::AllocatorType& allocator) {
36
37
rapidjson::Value sub_quads_value;
37
38
sub_quads_value.SetArray ();
38
39
for (auto quad : sub_quads) {
39
- const auto partition = root_tile.AddedSubkey64 (quad).ToHereTile ();
40
- const auto data_handle =
41
- mockserver::ReadDefaultResponses::GenerateDataHandle (partition) ;
40
+ const auto partition = root_tile.AddedSubkey64 (quad. first ).ToHereTile ();
41
+ const auto & data_handle = quad. second . data_handle ;
42
+ const auto version = quad. second . version ;
42
43
43
44
rapidjson::Value item_value;
44
45
item_value.SetObject ();
45
- olp::serializer::serialize (" subQuadKey" , std::to_string (quad), item_value ,
46
- allocator);
47
- olp::serializer::serialize (" version" , 0 , item_value, allocator);
46
+ olp::serializer::serialize (" subQuadKey" , std::to_string (quad. first ) ,
47
+ item_value, allocator);
48
+ olp::serializer::serialize (" version" , version , item_value, allocator);
48
49
olp::serializer::serialize (" dataHandle" , data_handle, item_value,
49
50
allocator);
50
- olp::serializer::serialize (" dataSize" , 100 , item_value, allocator);
51
51
sub_quads_value.PushBack (std::move (item_value), allocator);
52
52
}
53
53
doc.AddMember (" subQuads" , std::move (sub_quads_value), allocator);
54
54
}
55
55
56
- void WriteParentquadsToJson (rapidjson::Document& doc,
57
- const std::vector<std::uint64_t >& parent_quads,
58
- rapidjson::Document::AllocatorType& allocator) {
56
+ void WriteParentquadsToJson (
57
+ rapidjson::Document& doc,
58
+ const std::map<std::uint64_t , mockserver::TileMetadata>& parent_quads,
59
+ rapidjson::Document::AllocatorType& allocator) {
59
60
rapidjson::Value parent_quads_value;
60
61
parent_quads_value.SetArray ();
61
62
for (auto parent : parent_quads) {
62
- const auto partition = std::to_string (parent);
63
- const auto data_handle =
64
- mockserver::ReadDefaultResponses::GenerateDataHandle (partition) ;
63
+ const auto partition = std::to_string (parent. first );
64
+ const auto version = parent. second . version ;
65
+ const auto & data_handle = parent. second . data_handle ;
65
66
66
67
rapidjson::Value item_value;
67
68
item_value.SetObject ();
68
- olp::serializer::serialize (" partition" , std::to_string (parent), item_value,
69
- allocator);
70
- olp::serializer::serialize (" version" , 0 , item_value, allocator);
69
+ olp::serializer::serialize (" partition" , partition, item_value, allocator);
70
+ olp::serializer::serialize (" version" , version, item_value, allocator);
71
71
olp::serializer::serialize (" dataHandle" , data_handle, item_value,
72
72
allocator);
73
73
olp::serializer::serialize (" dataSize" , 100 , item_value, allocator);
74
74
parent_quads_value.PushBack (std::move (item_value), allocator);
75
75
}
76
76
doc.AddMember (" parentQuads" , std::move (parent_quads_value), allocator);
77
77
}
78
+
79
+ std::string GenerateRandomString (size_t length) {
80
+ std::string letters =
81
+ " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ;
82
+ std::random_device device;
83
+ std::mt19937 generator (device ());
84
+ std::uniform_int_distribution<unsigned int > dis (0u , letters.length () - 1 );
85
+
86
+ std::string result;
87
+ result.resize (length);
88
+ for (auto i = 0u ; i < length; ++i) {
89
+ result[i] += letters[dis (generator)];
90
+ }
91
+
92
+ return result;
93
+ }
94
+
95
+ void FillSubQuads (std::int32_t depth, std::vector<std::uint16_t >& sub_quads_) {
96
+ const auto sub_tile = olp::geo::TileKey::FromRowColumnLevel (0 , 0 , depth);
97
+ const auto start_level_id = sub_tile.ToQuadKey64 ();
98
+ const auto tiles_count = olp::geo::QuadKey64Helper::ChildrenAtLevel (depth);
99
+
100
+ std::vector<std::uint64_t > layer_ids (tiles_count);
101
+ std::iota (layer_ids.begin (), layer_ids.end (), start_level_id);
102
+ sub_quads_.insert (sub_quads_.end (), layer_ids.begin (), layer_ids.end ());
103
+ }
104
+
78
105
} // namespace
79
106
80
107
namespace mockserver {
81
108
109
+ std::string ReadDefaultResponses::GenerateData (size_t length) {
110
+ return GenerateRandomString (length);
111
+ }
112
+
82
113
std::string ReadDefaultResponses::GenerateQuadTreeResponse (
83
114
olp::geo::TileKey root_tile, std::uint32_t depth,
84
115
const std::vector<std::uint32_t >& available_levels) {
85
- std::vector <std::uint16_t > sub_quads;
86
- std::vector <std::uint64_t > parent_quads;
116
+ std::map <std::uint64_t , TileMetadata > sub_quads;
117
+ std::map <std::uint64_t , TileMetadata > parent_quads;
87
118
88
119
// generate data
89
120
for (auto level : available_levels) {
90
121
if (level < root_tile.Level ()) {
91
- auto key = root_tile.ChangedLevelTo (level);
92
- parent_quads. push_back ( key. ToQuadKey64 ()) ;
122
+ auto key = root_tile.ChangedLevelTo (level). ToQuadKey64 () ;
123
+ parent_quads[ key] = { GenerateDataHandle ( std::to_string (key)), 0 } ;
93
124
} else {
94
125
const auto level_depth = level - root_tile.Level ();
95
126
if (level_depth > depth) {
96
127
continue ;
97
128
}
98
129
99
- const auto sub_tile =
100
- olp::geo::TileKey::FromRowColumnLevel (0 , 0 , level_depth);
101
- const auto start_level_id = sub_tile.ToQuadKey64 ();
102
- const auto tiles_count =
103
- olp::geo::QuadKey64Helper::ChildrenAtLevel (level_depth);
130
+ std::vector<std::uint16_t > sub_quads_vector;
131
+ FillSubQuads (level_depth, sub_quads_vector);
104
132
105
- std::vector<std:: uint64_t > layer_ids (tiles_count);
106
- std::iota (layer_ids. begin (), layer_ids. end ( ), start_level_id) ;
107
- sub_quads. insert (sub_quads. end (), layer_ids. begin (), layer_ids. end ());
133
+ for ( const auto & sub_quad : sub_quads_vector) {
134
+ sub_quads[sub_quad] = { GenerateDataHandle ( std::to_string (sub_quad) ), 0 } ;
135
+ }
108
136
}
109
137
}
110
138
@@ -120,4 +148,89 @@ std::string ReadDefaultResponses::GenerateQuadTreeResponse(
120
148
return buffer.GetString ();
121
149
}
122
150
151
+ QuadTreeBuilder::QuadTreeBuilder (olp::geo::TileKey root_tile,
152
+ boost::optional<int32_t > version)
153
+ : root_tile_(root_tile), base_version_(version) {}
154
+
155
+ QuadTreeBuilder& QuadTreeBuilder::WithParent (olp::geo::TileKey parent,
156
+ std::string datahandle,
157
+ boost::optional<int32_t > version) {
158
+ assert (root_tile_.IsChildOf (parent));
159
+
160
+ // Make sure to set version when the base_version is set
161
+ if (version != boost::none) {
162
+ assert (base_version_ != boost::none);
163
+ } else if (base_version_) {
164
+ version = base_version_;
165
+ }
166
+
167
+ parent_quads_[parent.ToQuadKey64 ()] = {datahandle, version};
168
+
169
+ return *this ;
170
+ }
171
+
172
+ QuadTreeBuilder& QuadTreeBuilder::FillParents () {
173
+ auto key = root_tile_.Parent ();
174
+ while (key.IsValid ()) {
175
+ auto quad_key = key.ToQuadKey64 ();
176
+ if (parent_quads_.find (quad_key) == parent_quads_.end ()) {
177
+ parent_quads_[quad_key] = {GenerateRandomString (32 ), base_version_};
178
+ }
179
+ }
180
+ return *this ;
181
+ }
182
+
183
+ QuadTreeBuilder& QuadTreeBuilder::WithSubQuad (
184
+ olp::geo::TileKey tile, std::string datahandle,
185
+ boost::optional<int32_t > version) {
186
+ assert (tile.IsChildOf (root_tile_) || tile == root_tile_);
187
+ assert ((tile.Level () - root_tile_.Level ()) <= 4 );
188
+ if (version != boost::none) {
189
+ assert (base_version_ != boost::none);
190
+ }
191
+
192
+ auto origin = root_tile_.ChangedLevelTo (tile.Level ());
193
+ auto sub_quad =
194
+ olp::geo::TileKey::FromRowColumnLevel (tile.Row () - origin.Row (),
195
+ tile.Column () - origin.Column (),
196
+ tile.Level () - root_tile_.Level ())
197
+ .ToQuadKey64 ();
198
+
199
+ sub_quads_[sub_quad] = {datahandle, version};
200
+
201
+ return *this ;
202
+ }
203
+
204
+ QuadTreeBuilder& QuadTreeBuilder::FillSubquads (uint32_t depth) {
205
+ assert (depth <= 4 );
206
+
207
+ std::vector<std::uint16_t > sub_quads;
208
+ for (uint32_t i = 0 ; i <= depth; i++) {
209
+ FillSubQuads (i, sub_quads);
210
+ }
211
+
212
+ for (const auto & sub_quad : sub_quads) {
213
+ if (sub_quads_.find (sub_quad) == sub_quads_.end ()) {
214
+ sub_quads_[sub_quad] = {GenerateRandomString (32 ), base_version_};
215
+ }
216
+ }
217
+
218
+ return *this ;
219
+ }
220
+
221
+ std::string QuadTreeBuilder::BuildJson () const {
222
+ rapidjson::Document doc;
223
+ auto & allocator = doc.GetAllocator ();
224
+ doc.SetObject ();
225
+ WriteSubquadsToJson (doc, root_tile_, sub_quads_, allocator);
226
+ WriteParentquadsToJson (doc, parent_quads_, allocator);
227
+
228
+ rapidjson::StringBuffer buffer;
229
+ rapidjson::Writer<rapidjson::StringBuffer> writer (buffer);
230
+ doc.Accept (writer);
231
+ return buffer.GetString ();
232
+ }
233
+
234
+ olp::geo::TileKey QuadTreeBuilder::Root () const { return root_tile_; }
235
+
123
236
} // namespace mockserver
0 commit comments