summaryrefslogtreecommitdiff
path: root/src/mbgl/annotation/shape_annotation_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/annotation/shape_annotation_impl.cpp')
-rw-r--r--src/mbgl/annotation/shape_annotation_impl.cpp101
1 files changed, 81 insertions, 20 deletions
diff --git a/src/mbgl/annotation/shape_annotation_impl.cpp b/src/mbgl/annotation/shape_annotation_impl.cpp
index 76a237bfc2..a96c4eae72 100644
--- a/src/mbgl/annotation/shape_annotation_impl.cpp
+++ b/src/mbgl/annotation/shape_annotation_impl.cpp
@@ -80,33 +80,94 @@ void ShapeAnnotationImpl::updateStyle(Style& style) {
}
}
-void ShapeAnnotationImpl::updateTile(const CanonicalTileID& tileID, AnnotationTile& tile) {
- static const double baseTolerance = 4;
+struct ToGeoJSONVT {
+ const double tolerance;
- if (!shapeTiler) {
- const uint64_t maxAmountOfTiles = 1 << maxZoom;
- const double tolerance = baseTolerance / (maxAmountOfTiles * util::EXTENT);
+ ToGeoJSONVT(const double tolerance_)
+ : tolerance(tolerance_) {
+ }
- geojsonvt::ProjectedRings rings;
- for (auto& segment : shape.segments) {
- std::vector<geojsonvt::LonLat> points;
- for (auto& latLng : segment) {
- const double wrappedLongitude = util::wrap(latLng.longitude, -util::LONGITUDE_MAX, util::LONGITUDE_MAX);
- const double clampedLatitude = util::clamp(latLng.latitude, -util::LATITUDE_MAX, util::LATITUDE_MAX);
- points.push_back(geojsonvt::LonLat(wrappedLongitude, clampedLatitude));
- }
+ geojsonvt::ProjectedFeature operator()(const LineString<double>& line) const {
+ geojsonvt::ProjectedRings converted;
+ converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::Polygon, line));
+ return convertFeature(geojsonvt::ProjectedFeatureType::LineString, converted);
+ }
- if (type == geojsonvt::ProjectedFeatureType::Polygon &&
- (points.front().lon != points.back().lon || points.front().lat != points.back().lat)) {
- points.push_back(geojsonvt::LonLat(points.front().lon, points.front().lat));
+ geojsonvt::ProjectedFeature operator()(const Polygon<double>& polygon) const {
+ geojsonvt::ProjectedRings converted;
+ for (const auto& ring : polygon) {
+ converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::Polygon, ring));
+ }
+ return convertFeature(geojsonvt::ProjectedFeatureType::Polygon, converted);
+ }
+
+ geojsonvt::ProjectedFeature operator()(const MultiLineString<double>& lines) const {
+ geojsonvt::ProjectedRings converted;
+ for (const auto& line : lines) {
+ converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::LineString, line));
+ }
+ return convertFeature(geojsonvt::ProjectedFeatureType::LineString, converted);
+ }
+
+ geojsonvt::ProjectedFeature operator()(const MultiPolygon<double>& polygons) const {
+ geojsonvt::ProjectedRings converted;
+ for (const auto& polygon : polygons) {
+ for (const auto& ring : polygon) {
+ converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::Polygon, ring));
}
+ }
+ return convertFeature(geojsonvt::ProjectedFeatureType::Polygon, converted);
+ }
+
+ geojsonvt::ProjectedFeature operator()(const Point<double>&) {
+ throw std::runtime_error("unsupported shape annotation geometry type");
+ }
+
+ geojsonvt::ProjectedFeature operator()(const MultiPoint<double>&) {
+ throw std::runtime_error("unsupported shape annotation geometry type");
+ }
+
+ geojsonvt::ProjectedFeature operator()(const mapbox::geometry::geometry_collection<double>&) {
+ throw std::runtime_error("unsupported shape annotation geometry type");
+ }
+
+private:
+ geojsonvt::LonLat convertPoint(const Point<double>& p) const {
+ return {
+ util::wrap(p.x, -util::LONGITUDE_MAX, util::LONGITUDE_MAX),
+ util::clamp(p.y, -util::LATITUDE_MAX, util::LATITUDE_MAX)
+ };
+ }
- auto ring = geojsonvt::Convert::projectRing(points, tolerance);
- rings.push_back(ring);
+ geojsonvt::ProjectedRing convertPoints(geojsonvt::ProjectedFeatureType type, const std::vector<Point<double>>& points) const {
+ std::vector<geojsonvt::LonLat> converted;
+
+ for (const auto& p : points) {
+ converted.push_back(convertPoint(p));
+ }
+
+ if (type == geojsonvt::ProjectedFeatureType::Polygon && points.front() != points.back()) {
+ converted.push_back(converted.front());
}
- std::vector<geojsonvt::ProjectedFeature> features;
- features.push_back(geojsonvt::Convert::create(geojsonvt::Tags(), type, rings));
+ return geojsonvt::Convert::projectRing(converted, tolerance);
+ }
+
+ geojsonvt::ProjectedFeature convertFeature(geojsonvt::ProjectedFeatureType type, const geojsonvt::ProjectedRings& rings) const {
+ return geojsonvt::Convert::create(geojsonvt::Tags(), type, rings);
+ }
+};
+
+void ShapeAnnotationImpl::updateTile(const CanonicalTileID& tileID, AnnotationTile& tile) {
+ static const double baseTolerance = 4;
+
+ if (!shapeTiler) {
+ const uint64_t maxAmountOfTiles = 1 << maxZoom;
+ const double tolerance = baseTolerance / (maxAmountOfTiles * util::EXTENT);
+
+ std::vector<geojsonvt::ProjectedFeature> features = {
+ Geometry<double>::visit(shape.geometry, ToGeoJSONVT(tolerance))
+ };
mapbox::geojsonvt::Options options;
options.maxZoom = maxZoom;