88#include < mlt/decoder.hpp>
99#include < mlt/layer.hpp>
1010
11+ #include < algorithm>
12+ #include < cmath>
13+ #include < cstdint>
14+ #include < exception>
15+ #include < iterator>
16+ #include < memory>
17+ #include < numeric>
18+ #include < optional>
19+ #include < string>
20+ #include < string_view>
21+ #include < utility>
22+ #include < variant>
23+ #include < vector>
24+
1125namespace mbgl {
26+ namespace {
1227
28+ using MapLibreTile = mlt::MapLibreTile;
1329using GeometryType = mlt::metadata::tileset::GeometryType;
1430
15- VectorMLTTileFeature::VectorMLTTileFeature (std::shared_ptr<const MapLibreTile> tile_,
16- const mlt::Layer& layer_,
17- const mlt::Feature& feature_,
18- std::uint32_t extent_)
19- : tile(std::move(tile_)),
20- layer (layer_),
21- feature(feature_),
22- extent(extent_) {}
23-
24- FeatureType VectorMLTTileFeature::getType () const {
25- switch (feature.getGeometry ().type ) {
26- case GeometryType::POINT :
27- return FeatureType::Point;
28- case GeometryType::MULTIPOINT :
29- case GeometryType::MULTILINESTRING :
30- case GeometryType::LINESTRING :
31- return FeatureType::LineString;
32- case GeometryType::POLYGON :
33- case GeometryType::MULTIPOLYGON :
34- return FeatureType::Polygon;
35- default :
36- return FeatureType::Unknown;
31+ class VectorMLTTileFeature final : public GeometryTileFeature {
32+ public:
33+ VectorMLTTileFeature (std::shared_ptr<const MapLibreTile> tile_,
34+ const mlt::Layer& layer_,
35+ const mlt::Feature& feature_,
36+ std::uint32_t extent_)
37+ : tile(std::move(tile_)),
38+ layer (layer_),
39+ feature(feature_),
40+ extent(extent_) {}
41+
42+ VectorMLTTileFeature (const VectorMLTTileFeature&) = delete;
43+ VectorMLTTileFeature (VectorMLTTileFeature&& other)
44+ : tile(std::move(other.tile)),
45+ layer(other.layer),
46+ feature(other.feature),
47+ extent(other.extent),
48+ lines(std::move(other.lines)),
49+ properties(std::move(other.properties)) {}
50+
51+ VectorMLTTileFeature& operator =(VectorMLTTileFeature&&) = delete ;
52+ VectorMLTTileFeature& operator =(const VectorMLTTileFeature&) = delete ;
53+
54+ FeatureType getType () const override {
55+ switch (feature.getGeometry ().type ) {
56+ case GeometryType::POINT :
57+ return FeatureType::Point;
58+ case GeometryType::MULTIPOINT :
59+ case GeometryType::MULTILINESTRING :
60+ case GeometryType::LINESTRING :
61+ return FeatureType::LineString;
62+ case GeometryType::POLYGON :
63+ case GeometryType::MULTIPOLYGON :
64+ return FeatureType::Polygon;
65+ default :
66+ return FeatureType::Unknown;
67+ }
3768 }
38- }
3969
40- namespace {
70+ std::optional<Value> getValue (const std::string& key) const override ;
71+ const PropertyMap& getProperties () const override ;
72+ FeatureIdentifier getID () const override ;
73+ const GeometryCollection& getGeometries () const override ;
74+
75+ private:
76+ std::shared_ptr<const MapLibreTile> tile;
77+ const mlt::Layer& layer;
78+ const mlt::Feature& feature;
79+ std::uint32_t extent;
80+
81+ mutable std::optional<GeometryCollection> lines;
82+ mutable std::optional<PropertyMap> properties;
83+ };
84+
4185struct PropertyVisitor {
4286 Value operator ()(std::nullptr_t ) const { return mapbox::feature::null_value; }
4387 Value operator ()(bool value) const { return value; }
@@ -54,7 +98,6 @@ struct PropertyVisitor {
5498 return value ? operator ()(*value) : NullValue ();
5599 }
56100};
57- } // namespace
58101
59102std::optional<Value> VectorMLTTileFeature::getValue (const std::string& key) const {
60103 if (auto prop = feature.getProperty (key, layer)) {
@@ -81,21 +124,22 @@ FeatureIdentifier VectorMLTTileFeature::getID() const {
81124 return feature.getID ().has_value () ? mapbox::feature::identifier (*feature.getID ()) : mapbox::feature::null_value;
82125}
83126
84- namespace {
85127struct PointConverter {
86128 double scale;
129+
87130 inline constexpr static GeometryCoordinate convert (double scale, const mlt::Coordinate& coord) {
88131 return {static_cast <std::int16_t >(std::round (coord.x * scale)),
89132 static_cast <std::int16_t >(std::round (coord.y * scale))};
90133 }
134+
91135 GeometryCoordinate operator ()(const mlt::Coordinate& coord) const { return convert (scale, coord); }
136+
92137 GeometryCoordinates operator ()(const mlt::CoordVec& coords) const {
93138 GeometryCoordinates result (coords.size ());
94139 std::ranges::transform (coords, result.begin (), *this );
95140 return result;
96141 }
97142};
98- } // namespace
99143
100144const GeometryCollection& VectorMLTTileFeature::getGeometries () const {
101145 MLN_TRACE_FUNC ();
@@ -155,70 +199,94 @@ const GeometryCollection& VectorMLTTileFeature::getGeometries() const {
155199 return *lines;
156200}
157201
158- VectorMLTTileLayer::VectorMLTTileLayer (std::shared_ptr<const MapLibreTile> tile_, const mlt::Layer& layer_)
159- : tile(std::move(tile_)),
160- layer(layer_) {}
202+ class VectorMLTTileLayer final : public GeometryTileLayer {
203+ public:
204+ VectorMLTTileLayer (std::shared_ptr<const MapLibreTile> tile_, const mlt::Layer& layer_)
205+ : tile(std::move(tile_)),
206+ layer (layer_) {}
161207
162- std::size_t VectorMLTTileLayer::featureCount () const {
163- return layer.getFeatures ().size ();
164- }
208+ std::size_t featureCount () const override { return layer.getFeatures ().size (); }
165209
166- std::unique_ptr<GeometryTileFeature> VectorMLTTileLayer::getFeature (std::size_t index) const {
167- const auto & features = layer.getFeatures ();
168- const mlt::Feature* targetFeature = nullptr ;
169- targetFeature = &features[index];
170- return std::make_unique<VectorMLTTileFeature>(tile, layer, *targetFeature, layer.getExtent ());
171- }
210+ std::unique_ptr<GeometryTileFeature> getFeature (std::size_t index) const override {
211+ const auto & features = layer.getFeatures ();
212+ return std::make_unique<VectorMLTTileFeature>(tile, layer, features[index], layer.getExtent ());
213+ }
172214
173- std::string VectorMLTTileLayer::getName () const {
174- return layer.getName ();
175- }
215+ std::string getName () const override { return layer.getName (); }
176216
177- VectorMLTTileData::VectorMLTTileData (std::shared_ptr<const std::string> data_, bool fastPFOREnabled_)
178- : data(std::move(data_)),
179- fastPFOREnabled(fastPFOREnabled_) {}
217+ private:
218+ const std::shared_ptr<const MapLibreTile> tile;
219+ const mlt::Layer& layer;
220+ };
180221
181- VectorMLTTileData::VectorMLTTileData (const VectorMLTTileData& other)
182- : data(other.data),
183- tile(other.tile),
184- fastPFOREnabled(other.fastPFOREnabled) {}
222+ } // namespace
185223
186- std::unique_ptr<GeometryTileData> VectorMLTTileData::clone () const {
187- return std::make_unique<VectorMLTTileData>(*this );
188- }
224+ class VectorMLTTileData ::Impl {
225+ public:
226+ Impl (std::shared_ptr<const std::string> data_, bool fastPFOREnabled_)
227+ : data(std::move(data_)),
228+ fastPFOREnabled (fastPFOREnabled_) {}
189229
190- std::unique_ptr<GeometryTileLayer> VectorMLTTileData::getLayer (const std::string& name) const {
191- MLN_TRACE_FUNC ();
230+ Impl (const Impl&) = default;
231+
232+ std::unique_ptr<GeometryTileLayer> getLayer (const std::string& name) const {
233+ MLN_TRACE_FUNC ();
192234
193- if (data && !tile) {
194- try {
195- mlt::DataView tileData{data->data (), data->size ()};
196- tile = std::make_shared<MapLibreTile>(mlt::Decoder (fastPFOREnabled).decode (tileData));
197- } catch (const std::exception& ex) {
198- Log::Warning (Event::ParseTile, " MLT parse failed: " + std::string (ex.what ()));
235+ if (data && !tile) {
236+ try {
237+ mlt::DataView tileData{data->data (), data->size ()};
238+ tile = std::make_shared<MapLibreTile>(mlt::Decoder (fastPFOREnabled).decode (tileData));
239+ } catch (const std::exception& ex) {
240+ Log::Warning (Event::ParseTile, " MLT parse failed: " + std::string (ex.what ()));
241+ }
242+ data.reset ();
199243 }
200- // We don't need the raw data anymore
201- data.reset ();
244+
245+ if (tile) {
246+ if (const auto * layer = tile->getLayer (name)) {
247+ return std::make_unique<VectorMLTTileLayer>(tile, *layer);
248+ }
249+ }
250+ return nullptr ;
202251 }
203252
204- if (tile) {
205- if (const auto * layer = tile-> getLayer (name) ) {
206- return std::make_unique<VectorMLTTileLayer>(tile, *layer );
253+ std::vector<std::string> layerNames () const {
254+ if (data && !data-> empty () && !tile ) {
255+ getLayer ({} );
207256 }
257+ if (tile) {
258+ std::vector<std::string> result (tile->getLayers ().size ());
259+ std::ranges::transform (tile->getLayers (), result.begin (), [](const auto & layer) { return layer.getName (); });
260+ return result;
261+ }
262+ return {};
208263 }
209- return nullptr ;
264+
265+ private:
266+ mutable std::shared_ptr<const std::string> data;
267+ mutable std::shared_ptr<const MapLibreTile> tile;
268+ bool fastPFOREnabled;
269+ };
270+
271+ VectorMLTTileData::VectorMLTTileData (std::shared_ptr<const std::string> data, bool fastPFOREnabled)
272+ : impl(std::make_unique<Impl>(std::move(data), fastPFOREnabled)) {}
273+
274+ VectorMLTTileData::VectorMLTTileData (const VectorMLTTileData& other)
275+ : impl(std::make_unique<Impl>(*other.impl)) {}
276+
277+ VectorMLTTileData::VectorMLTTileData (VectorMLTTileData&&) noexcept = default;
278+ VectorMLTTileData::~VectorMLTTileData () = default ;
279+
280+ std::unique_ptr<GeometryTileData> VectorMLTTileData::clone () const {
281+ return std::make_unique<VectorMLTTileData>(*this );
282+ }
283+
284+ std::unique_ptr<GeometryTileLayer> VectorMLTTileData::getLayer (const std::string& name) const {
285+ return impl->getLayer (name);
210286}
211287
212288std::vector<std::string> VectorMLTTileData::layerNames () const {
213- if (data && !data->empty () && !tile) {
214- getLayer ({});
215- }
216- if (tile) {
217- std::vector<std::string> result (tile->getLayers ().size ());
218- std::ranges::transform (tile->getLayers (), result.begin (), [](const auto & layer) { return layer.getName (); });
219- return result;
220- }
221- return {};
289+ return impl->layerNames ();
222290}
223291
224292} // namespace mbgl
0 commit comments