summaryrefslogtreecommitdiff
path: root/src/mbgl/tile/geometry_tile_data.hpp
blob: 5677db2b167df0e7ff9ae14649cc4c3c400223dd (plain)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#pragma once

#include <mbgl/util/geometry.hpp>
#include <mbgl/util/feature.hpp>
#include <mbgl/util/optional.hpp>

#include <cstdint>
#include <string>
#include <vector>
#include <memory>

namespace mbgl {

class CanonicalTileID;

// Normalized vector tile coordinates.
// Each geometry coordinate represents a point in a bidimensional space,
// varying from -V...0...+V, where V is the maximum extent applicable.
using GeometryCoordinate = Point<int16_t>;

class GeometryCoordinates : public std::vector<GeometryCoordinate> {
public:
    using coordinate_type = int16_t;

    GeometryCoordinates() = default;
    GeometryCoordinates(const std::vector<GeometryCoordinate>& v)
        : std::vector<GeometryCoordinate>(v) {}
    GeometryCoordinates(std::vector<GeometryCoordinate>&& v)
        : std::vector<GeometryCoordinate>(std::move(v)) {}

    using std::vector<GeometryCoordinate>::vector;
};

class GeometryCollection : public std::vector<GeometryCoordinates> {
public:
    using coordinate_type = int16_t;
    using std::vector<GeometryCoordinates>::vector;
};

class GeometryTileFeature {
public:
    virtual ~GeometryTileFeature() = default;
    virtual FeatureType getType() const = 0;
    virtual optional<Value> getValue(const std::string& key) const = 0;
    virtual PropertyMap getProperties() const { return PropertyMap(); }
    virtual optional<FeatureIdentifier> getID() const { return {}; }
    virtual GeometryCollection getGeometries() const = 0;
};

class GeometryTileLayer {
public:
    virtual ~GeometryTileLayer() = default;
    virtual std::size_t featureCount() const = 0;

    // Returns the feature object at the given position within the layer. The returned feature
    // object may *not* outlive the layer object.
    virtual std::unique_ptr<GeometryTileFeature> getFeature(std::size_t) const = 0;

    virtual std::string getName() const = 0;
};

class GeometryTileData {
public:
    virtual ~GeometryTileData() = default;
    virtual std::unique_ptr<GeometryTileData> clone() const = 0;

    // Returns the layer with the given name. The returned layer object *may* outlive the data
    // object.
    virtual std::unique_ptr<GeometryTileLayer> getLayer(const std::string&) const = 0;
};

// classifies an array of rings into polygons with outer rings and holes
std::vector<GeometryCollection> classifyRings(const GeometryCollection&);

// Truncate polygon to the largest `maxHoles` inner rings by area.
void limitHoles(GeometryCollection&, uint32_t maxHoles);

// convert from GeometryTileFeature to Feature (eventually we should eliminate GeometryTileFeature)
Feature convertFeature(const GeometryTileFeature&, const CanonicalTileID&);

// convert from GeometryTileFeature to Feature without geometry (eventually we should eliminate GeometryTileFeature)
Feature convertFeatureProperties(const GeometryTileFeature&);

// Fix up possibly-non-V2-compliant polygon geometry using angus clipper.
// The result is guaranteed to have correctly wound, strictly simple rings.
GeometryCollection fixupPolygons(const GeometryCollection&);

struct ToGeometryCollection {
    GeometryCollection operator()(const mapbox::geometry::point<int16_t>& geom) const {
        return { { geom } };
    }
    GeometryCollection operator()(const mapbox::geometry::multi_point<int16_t>& geom) const {
        GeometryCoordinates coordinates;
        coordinates.reserve(geom.size());
        for (const auto& point : geom) {
            coordinates.emplace_back(point);
        }
        return { coordinates };
    }
    GeometryCollection operator()(const mapbox::geometry::line_string<int16_t>& geom) const {
        GeometryCoordinates coordinates;
        coordinates.reserve(geom.size());
        for (const auto& point : geom) {
            coordinates.emplace_back(point);
        }
        return { coordinates };
    }
    GeometryCollection operator()(const mapbox::geometry::multi_line_string<int16_t>& geom) const {
        GeometryCollection collection;
        collection.reserve(geom.size());
        for (const auto& ring : geom) {
            GeometryCoordinates coordinates;
            coordinates.reserve(ring.size());
            for (const auto& point : ring) {
                coordinates.emplace_back(point);
            }
            collection.push_back(std::move(coordinates));
        }
        return collection;
    }
    GeometryCollection operator()(const mapbox::geometry::polygon<int16_t>& geom) const {
        GeometryCollection collection;
        collection.reserve(geom.size());
        for (const auto& ring : geom) {
            GeometryCoordinates coordinates;
            coordinates.reserve(ring.size());
            for (const auto& point : ring) {
                coordinates.emplace_back(point);
            }
            collection.push_back(std::move(coordinates));
        }
        return collection;
    }
    GeometryCollection operator()(const mapbox::geometry::multi_polygon<int16_t>& geom) const {
        GeometryCollection collection;
        for (auto& polygon : geom) {
            for (auto& ring : polygon) {
                GeometryCoordinates coordinates;
                coordinates.reserve(ring.size());
                for (auto& point : ring) {
                    coordinates.emplace_back(point);
                }
                collection.push_back(std::move(coordinates));
            }
        }
        return collection;
    }
    GeometryCollection operator()(const mapbox::geometry::geometry_collection<int16_t>&) const {
        GeometryCollection collection;
        return collection;
    }
};

} // namespace mbgl