@@ -36,15 +36,51 @@ geojsonvt::Options options() {
36
36
37
37
struct ClientGeoJsonData {
38
38
std::unique_ptr<geojsonvt::GeoJSONVT> tiles;
39
- mapbox:: geometry::feature_collection<double > features;
39
+ geometry::feature_collection<double > features;
40
40
std::vector<Properties> properties;
41
41
};
42
42
43
+ struct PolylineBuilderData : mapbox::geometry::line_string<double > {};
44
+
45
+ PolylineBuilder::PolylineBuilder () {
46
+ data = std::make_unique<PolylineBuilderData>();
47
+ }
48
+
49
+ PolylineBuilder::~PolylineBuilder () = default ;
50
+
51
+ void PolylineBuilder::beginPolyline (size_t numberOfPoints) {
52
+ data->reserve (numberOfPoints);
53
+ }
54
+
55
+ void PolylineBuilder::addPoint (Tangram::LngLat point) {
56
+ data->emplace_back (point.longitude , point.latitude );
57
+ }
58
+
59
+ struct PolygonBuilderData : mapbox::geometry::polygon<double > {};
60
+
61
+ PolygonBuilder::PolygonBuilder () {
62
+ data = std::make_unique<PolygonBuilderData>();
63
+ }
64
+
65
+ PolygonBuilder::~PolygonBuilder () = default ;
66
+
67
+ void PolygonBuilder::beginPolygon (size_t numberOfRings) {
68
+ data->reserve (numberOfRings);
69
+ }
70
+
71
+ void PolygonBuilder::beginRing (size_t numberOfPoints) {
72
+ data->emplace_back ();
73
+ data->back ().reserve (numberOfPoints);
74
+ }
75
+
76
+ void PolygonBuilder::addPoint (LngLat point) {
77
+ data->back ().emplace_back (point.longitude , point.latitude );
78
+ }
79
+
43
80
std::shared_ptr<TileTask> ClientGeoJsonSource::createTask (TileID _tileId) {
44
81
return std::make_shared<TileTask>(_tileId, shared_from_this ());
45
82
}
46
83
47
-
48
84
// TODO: pass scene's resourcePath to constructor to be used with `stringFromFile`
49
85
ClientGeoJsonSource::ClientGeoJsonSource (Platform& _platform, const std::string& _name,
50
86
const std::string& _url, bool _generateCentroids,
@@ -63,6 +99,7 @@ ClientGeoJsonSource::ClientGeoJsonSource(Platform& _platform, const std::string&
63
99
LOGE (" Unable to retrieve data from '%s': %s" , _url.c_str (), response.error );
64
100
} else {
65
101
addData (std::string (response.content .begin (), response.content .end ()));
102
+ generateTiles ();
66
103
}
67
104
m_hasPendingData = false ;
68
105
};
@@ -72,7 +109,7 @@ ClientGeoJsonSource::ClientGeoJsonSource(Platform& _platform, const std::string&
72
109
73
110
}
74
111
75
- ClientGeoJsonSource::~ClientGeoJsonSource () {}
112
+ ClientGeoJsonSource::~ClientGeoJsonSource () = default ;
76
113
77
114
struct add_centroid {
78
115
@@ -81,10 +118,7 @@ struct add_centroid {
81
118
bool operator ()(const geometry::polygon<double >& geom) {
82
119
if (geom.empty ()) { return false ; }
83
120
pt = centroid (geom.front ().begin (), geom.front ().end ()-1 );
84
- if (std::isnan (pt.x ) || std::isnan (pt.y )) {
85
- return false ;
86
- }
87
- return true ;
121
+ return !(std::isnan (pt.x ) || std::isnan (pt.y ));
88
122
}
89
123
90
124
bool operator ()(const geometry::multi_polygon<double >& geom) {
@@ -115,7 +149,7 @@ struct prop_visitor {
115
149
Properties& props;
116
150
std::string& key;
117
151
void operator ()(std::string v) {
118
- props.set (key, v );
152
+ props.set (key, std::move (v) );
119
153
}
120
154
void operator ()(bool v) {
121
155
props.set (key, double (v));
@@ -136,47 +170,22 @@ struct prop_visitor {
136
170
}
137
171
};
138
172
139
- void ClientGeoJsonSource::generateLabelCentroidFeature () {
140
- for (const auto &feat : m_store->features ) {
141
- geometry::point<double > centroid;
142
- const auto & properties = m_store->properties [feat.id .get <uint64_t >()];
143
- if (geometry::geometry<double >::visit (feat.geometry , add_centroid{ centroid })) {
144
- uint64_t id = m_store->features .size ();
145
- m_store->features .emplace_back (centroid, id);
146
- m_store->properties .push_back (properties);
147
- auto & props = m_store->properties .back ();
148
- props.set (" label_placement" , 1.0 );
149
- }
150
- }
151
- }
152
-
153
- void ClientGeoJsonSource::addData (const std::string& _data) {
173
+ void ClientGeoJsonSource::generateTiles () {
154
174
155
175
std::lock_guard<std::mutex> lock (m_mutexStore);
156
176
157
- const auto json = geojson::parse (_data);
158
- auto features = geojsonvt::geojson::visit (json, geojsonvt::ToFeatureCollection{});
159
-
160
- for (auto & feature : features) {
161
-
162
- feature.id = uint64_t (m_store->properties .size ());
163
- m_store->properties .emplace_back ();
164
- Properties& props = m_store->properties .back ();
165
-
166
- for (const auto & prop : feature.properties ) {
167
- auto key = prop.first ;
168
- prop_visitor visitor = {props, key};
169
- mapbox::util::apply_visitor (visitor, prop.second );
170
- }
171
- feature.properties .clear ();
172
- }
173
-
174
- m_store->features .insert (m_store->features .end (),
175
- std::make_move_iterator (features.begin ()),
176
- std::make_move_iterator (features.end ()));
177
-
178
177
if (m_generateCentroids) {
179
- generateLabelCentroidFeature ();
178
+ for (const auto &feat : m_store->features ) {
179
+ geometry::point<double > centroid;
180
+ const auto & properties = m_store->properties [feat.id .get <uint64_t >()];
181
+ if (geometry::geometry<double >::visit (feat.geometry , add_centroid{ centroid })) {
182
+ uint64_t id = m_store->features .size ();
183
+ m_store->features .emplace_back (centroid, id);
184
+ m_store->properties .push_back (properties);
185
+ auto & props = m_store->properties .back ();
186
+ props.set (" label_placement" , 1.0 );
187
+ }
188
+ }
180
189
}
181
190
182
191
m_store->tiles = std::make_unique<geojsonvt::GeoJSONVT>(m_store->features , options ());
@@ -210,65 +219,61 @@ void ClientGeoJsonSource::clearData() {
210
219
m_generation++;
211
220
}
212
221
213
- void ClientGeoJsonSource::addPoint (const Properties& _tags, LngLat _point ) {
222
+ void ClientGeoJsonSource::addData (const std::string& _data ) {
214
223
215
224
std::lock_guard<std::mutex> lock (m_mutexStore);
216
225
217
- geometry::point<double > geom { _point.longitude , _point.latitude };
226
+ const auto json = geojson::parse (_data);
227
+ auto features = geojsonvt::geojson::visit (json, geojsonvt::ToFeatureCollection{});
218
228
219
- uint64_t id = m_store-> features . size ();
229
+ for ( auto & feature : features) {
220
230
221
- m_store->features .emplace_back (geom, id);
222
- m_store->properties .emplace_back (_tags);
231
+ feature.id = uint64_t (m_store->properties .size ());
232
+ m_store->properties .emplace_back ();
233
+ Properties& props = m_store->properties .back ();
223
234
224
- m_store->tiles = std::make_unique<geojsonvt::GeoJSONVT>(m_store->features , options ());
225
- m_generation++;
226
- }
235
+ for (const auto & prop : feature.properties ) {
236
+ auto key = prop.first ;
237
+ prop_visitor visitor = {props, key};
238
+ mapbox::util::apply_visitor (visitor, prop.second );
239
+ }
240
+ feature.properties .clear ();
241
+ }
227
242
228
- void ClientGeoJsonSource::addLine (const Properties& _tags, const Coordinates& _line) {
243
+ m_store->features .insert (m_store->features .end (),
244
+ std::make_move_iterator (features.begin ()),
245
+ std::make_move_iterator (features.end ()));
246
+ }
229
247
248
+ void ClientGeoJsonSource::addPointFeature (Properties&& properties, LngLat coordinates) {
230
249
231
250
std::lock_guard<std::mutex> lock (m_mutexStore);
232
251
233
- geometry::line_string<double > geom;
234
- for (auto & p : _line) {
235
- geom.emplace_back (p.longitude , p.latitude );
236
- }
252
+ geometry::point<double > geom {coordinates.longitude , coordinates.latitude };
237
253
238
254
uint64_t id = m_store->features .size ();
239
-
240
255
m_store->features .emplace_back (geom, id);
241
- m_store->properties .emplace_back (_tags);
242
-
243
- m_store->tiles = std::make_unique<geojsonvt::GeoJSONVT>(m_store->features , options ());
244
- m_generation++;
256
+ m_store->properties .emplace_back (properties);
245
257
}
246
258
247
- void ClientGeoJsonSource::addPoly (const Properties& _tags, const std::vector<Coordinates>& _poly) {
248
-
259
+ void ClientGeoJsonSource::addPolylineFeature (Properties&& properties, PolylineBuilder&& polyline) {
249
260
250
261
std::lock_guard<std::mutex> lock (m_mutexStore);
251
262
252
- geometry::polygon<double > geom;
253
- for (auto & ring : _poly) {
254
- geom.emplace_back ();
255
- auto &line = geom.back ();
256
- for (auto & p : ring) {
257
- line.emplace_back (p.longitude , p.latitude );
258
- }
259
- }
260
-
261
263
uint64_t id = m_store->features .size ();
264
+ auto geom = std::move (polyline.data );
265
+ m_store->features .emplace_back (*geom, id);
266
+ m_store->properties .emplace_back (properties);
267
+ }
262
268
263
- m_store->features .emplace_back (geom, id);
264
- m_store->properties .emplace_back (_tags);
269
+ void ClientGeoJsonSource::addPolygonFeature (Properties&& properties, PolygonBuilder&& polygon) {
265
270
266
- if (m_generateCentroids) {
267
- generateLabelCentroidFeature ();
268
- }
271
+ std::lock_guard<std::mutex> lock (m_mutexStore);
269
272
270
- m_store->tiles = std::make_unique<geojsonvt::GeoJSONVT>(m_store->features , options ());
271
- m_generation++;
273
+ uint64_t id = m_store->features .size ();
274
+ auto geom = std::move (polygon.data );
275
+ m_store->features .emplace_back (*geom, id);
276
+ m_store->properties .emplace_back (properties);
272
277
}
273
278
274
279
struct add_geometry {
@@ -356,7 +361,6 @@ std::shared_ptr<TileData> ClientGeoJsonSource::parse(const TileTask& _task) cons
356
361
}
357
362
}
358
363
359
-
360
364
return data;
361
365
}
362
366
0 commit comments