1 #pragma once
2 
3 #include <mbgl/util/geometry.hpp>
4 #include <mbgl/util/feature.hpp>
5 #include <mbgl/util/optional.hpp>
6 
7 #include <cstdint>
8 #include <string>
9 #include <vector>
10 #include <memory>
11 
12 namespace mbgl {
13 
14 class CanonicalTileID;
15 
16 // Normalized vector tile coordinates.
17 // Each geometry coordinate represents a point in a bidimensional space,
18 // varying from -V...0...+V, where V is the maximum extent applicable.
19 using GeometryCoordinate = Point<int16_t>;
20 
21 class GeometryCoordinates : public std::vector<GeometryCoordinate> {
22 public:
23     using coordinate_type = int16_t;
24 
25     template <class... Args>
GeometryCoordinates(Args &&...args)26     GeometryCoordinates(Args&&... args) : std::vector<GeometryCoordinate>(std::forward<Args>(args)...) {}
GeometryCoordinates(std::initializer_list<GeometryCoordinate> args)27     GeometryCoordinates(std::initializer_list<GeometryCoordinate> args)
28       : std::vector<GeometryCoordinate>(std::move(args)) {}
29 };
30 
31 class GeometryCollection : public std::vector<GeometryCoordinates> {
32 public:
33     using coordinate_type = int16_t;
34     template <class... Args>
GeometryCollection(Args &&...args)35     GeometryCollection(Args&&... args) : std::vector<GeometryCoordinates>(std::forward<Args>(args)...) {}
GeometryCollection(std::initializer_list<GeometryCoordinates> args)36     GeometryCollection(std::initializer_list<GeometryCoordinates> args)
37       : std::vector<GeometryCoordinates>(std::move(args)) {}
38 };
39 
40 class GeometryTileFeature {
41 public:
42     virtual ~GeometryTileFeature() = default;
43     virtual FeatureType getType() const = 0;
44     virtual optional<Value> getValue(const std::string& key) const = 0;
getProperties() const45     virtual PropertyMap getProperties() const { return PropertyMap(); }
getID() const46     virtual optional<FeatureIdentifier> getID() const { return {}; }
47     virtual GeometryCollection getGeometries() const = 0;
48 };
49 
50 class GeometryTileLayer {
51 public:
52     virtual ~GeometryTileLayer() = default;
53     virtual std::size_t featureCount() const = 0;
54 
55     // Returns the feature object at the given position within the layer. The returned feature
56     // object may *not* outlive the layer object.
57     virtual std::unique_ptr<GeometryTileFeature> getFeature(std::size_t) const = 0;
58 
59     virtual std::string getName() const = 0;
60 };
61 
62 class GeometryTileData {
63 public:
64     virtual ~GeometryTileData() = default;
65     virtual std::unique_ptr<GeometryTileData> clone() const = 0;
66 
67     // Returns the layer with the given name. The returned layer object *may* outlive the data
68     // object.
69     virtual std::unique_ptr<GeometryTileLayer> getLayer(const std::string&) const = 0;
70 };
71 
72 // classifies an array of rings into polygons with outer rings and holes
73 std::vector<GeometryCollection> classifyRings(const GeometryCollection&);
74 
75 // Truncate polygon to the largest `maxHoles` inner rings by area.
76 void limitHoles(GeometryCollection&, uint32_t maxHoles);
77 
78 // convert from GeometryTileFeature to Feature (eventually we should eliminate GeometryTileFeature)
79 Feature convertFeature(const GeometryTileFeature&, const CanonicalTileID&);
80 
81 // Fix up possibly-non-V2-compliant polygon geometry using angus clipper.
82 // The result is guaranteed to have correctly wound, strictly simple rings.
83 GeometryCollection fixupPolygons(const GeometryCollection&);
84 
85 struct ToGeometryCollection {
operator ()mbgl::ToGeometryCollection86     GeometryCollection operator()(const mapbox::geometry::point<int16_t>& geom) const {
87         return { { geom } };
88     }
operator ()mbgl::ToGeometryCollection89     GeometryCollection operator()(const mapbox::geometry::multi_point<int16_t>& geom) const {
90         GeometryCoordinates coordinates;
91         coordinates.reserve(geom.size());
92         for (const auto& point : geom) {
93             coordinates.emplace_back(point);
94         }
95         return { coordinates };
96     }
operator ()mbgl::ToGeometryCollection97     GeometryCollection operator()(const mapbox::geometry::line_string<int16_t>& geom) const {
98         GeometryCoordinates coordinates;
99         coordinates.reserve(geom.size());
100         for (const auto& point : geom) {
101             coordinates.emplace_back(point);
102         }
103         return { coordinates };
104     }
operator ()mbgl::ToGeometryCollection105     GeometryCollection operator()(const mapbox::geometry::multi_line_string<int16_t>& geom) const {
106         GeometryCollection collection;
107         collection.reserve(geom.size());
108         for (const auto& ring : geom) {
109             GeometryCoordinates coordinates;
110             coordinates.reserve(ring.size());
111             for (const auto& point : ring) {
112                 coordinates.emplace_back(point);
113             }
114             collection.push_back(std::move(coordinates));
115         }
116         return collection;
117     }
operator ()mbgl::ToGeometryCollection118     GeometryCollection operator()(const mapbox::geometry::polygon<int16_t>& geom) const {
119         GeometryCollection collection;
120         collection.reserve(geom.size());
121         for (const auto& ring : geom) {
122             GeometryCoordinates coordinates;
123             coordinates.reserve(ring.size());
124             for (const auto& point : ring) {
125                 coordinates.emplace_back(point);
126             }
127             collection.push_back(std::move(coordinates));
128         }
129         return collection;
130     }
operator ()mbgl::ToGeometryCollection131     GeometryCollection operator()(const mapbox::geometry::multi_polygon<int16_t>& geom) const {
132         GeometryCollection collection;
133         for (auto& polygon : geom) {
134             for (auto& ring : polygon) {
135                 GeometryCoordinates coordinates;
136                 coordinates.reserve(ring.size());
137                 for (auto& point : ring) {
138                     coordinates.emplace_back(point);
139                 }
140                 collection.push_back(std::move(coordinates));
141             }
142         }
143         return collection;
144     }
operator ()mbgl::ToGeometryCollection145     GeometryCollection operator()(const mapbox::geometry::geometry_collection<int16_t>&) const {
146         GeometryCollection collection;
147         return collection;
148     }
149 };
150 
151 } // namespace mbgl
152