diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-10-22 13:11:25 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-10-22 15:27:53 -0700 |
commit | c46a8254c46acb0da3719e20e99c87b11e998da2 (patch) | |
tree | 635f8c3e3d878ff3e025a8175a3509a1ec4d6df7 /src/mbgl/annotation | |
parent | 4f509288b7c671db96555a24a4f490311adfc13a (diff) | |
download | qtlocation-mapboxgl-c46a8254c46acb0da3719e20e99c87b11e998da2.tar.gz |
[core] Style-sourced shape annotation properties
This introduces the possibility to source the type and style properties
of a shape annotation from a designated layer in the style.
Diffstat (limited to 'src/mbgl/annotation')
-rw-r--r-- | src/mbgl/annotation/shape_annotation_impl.cpp | 139 | ||||
-rw-r--r-- | src/mbgl/annotation/shape_annotation_impl.hpp | 8 |
2 files changed, 88 insertions, 59 deletions
diff --git a/src/mbgl/annotation/shape_annotation_impl.cpp b/src/mbgl/annotation/shape_annotation_impl.cpp index 5b3c07fbc9..4ab9958fdf 100644 --- a/src/mbgl/annotation/shape_annotation_impl.cpp +++ b/src/mbgl/annotation/shape_annotation_impl.cpp @@ -15,92 +15,115 @@ using namespace mapbox::util::geojsonvt; ShapeAnnotationImpl::ShapeAnnotationImpl(const AnnotationID id_, const ShapeAnnotation& shape_, - const uint8_t maxZoom) + const uint8_t maxZoom_) : id(id_), layerID("com.mapbox.annotations.shape." + util::toString(id)), shape(shape_), - shapeTiler(([&] { - const double baseTolerance = 3; - const uint16_t extent = 4096; - const double tolerance = baseTolerance / ((1 << maxZoom) * extent); - - ProjectedGeometryContainer rings; - std::vector<LonLat> points; - - for (size_t i = 0; i < shape.segments[0].size(); ++i) { // first segment for now (no holes) - const double constraintedLatitude = ::fmin(::fmax(shape.segments[0][i].latitude, -util::LATITUDE_MAX), util::LATITUDE_MAX); - points.push_back(LonLat(shape.segments[0][i].longitude, constraintedLatitude)); - } - - ProjectedFeatureType featureType; - - if (shape.styleProperties.is<FillPaintProperties>()) { - featureType = ProjectedFeatureType::Polygon; - - if (points.front().lon != points.back().lon || points.front().lat != points.back().lat) { - points.push_back(LonLat(points.front().lon, points.front().lat)); - } - } else { - featureType = ProjectedFeatureType::LineString; - } - - ProjectedGeometryContainer ring = Convert::project(points, tolerance); - rings.members.push_back(ring); - - std::vector<ProjectedFeature> features; - features.push_back(Convert::create(Tags(), featureType, rings)); - return features; - })(), maxZoom, 4, 100, 10) {} + maxZoom(maxZoom_) { +} void ShapeAnnotationImpl::updateStyle(Style& style) { if (style.getLayer(layerID)) return; - if (shape.styleProperties.is<LinePaintProperties>()) { - const LinePaintProperties& properties = shape.styleProperties.get<LinePaintProperties>(); + std::unique_ptr<StyleLayer> layer; - std::unique_ptr<LineLayer> layer = std::make_unique<LineLayer>(); - layer->id = layerID; - layer->type = StyleLayerType::Line; + if (shape.properties.is<LinePaintProperties>()) { + layer = createLineLayer(); + const LinePaintProperties& properties = shape.properties.get<LinePaintProperties>(); ClassProperties paintProperties; paintProperties.set(PropertyKey::LineOpacity, ConstantFunction<float>(properties.opacity)); paintProperties.set(PropertyKey::LineWidth, ConstantFunction<float>(properties.width)); paintProperties.set(PropertyKey::LineColor, ConstantFunction<Color>(properties.color)); layer->styles.emplace(ClassID::Default, std::move(paintProperties)); - layer->bucket = std::make_shared<StyleBucket>(layer->type); - layer->bucket->name = layer->id; - layer->bucket->source = AnnotationManager::SourceID; - layer->bucket->source_layer = layer->id; - layer->bucket->layout.set(PropertyKey::LineJoin, ConstantFunction<JoinType>(JoinType::Round)); - - style.addLayer(std::move(layer), AnnotationManager::PointLayerID); - - } else if (shape.styleProperties.is<FillPaintProperties>()) { - const FillPaintProperties& properties = shape.styleProperties.get<FillPaintProperties>(); - - std::unique_ptr<FillLayer> layer = std::make_unique<FillLayer>(); - layer->id = layerID; - layer->type = StyleLayerType::Fill; + } else if (shape.properties.is<FillPaintProperties>()) { + layer = createFillLayer(); + const FillPaintProperties& properties = shape.properties.get<FillPaintProperties>(); ClassProperties paintProperties; paintProperties.set(PropertyKey::FillOpacity, ConstantFunction<float>(properties.opacity)); paintProperties.set(PropertyKey::FillColor, ConstantFunction<Color>(properties.fill_color)); paintProperties.set(PropertyKey::FillOutlineColor, ConstantFunction<Color>(properties.stroke_color)); layer->styles.emplace(ClassID::Default, std::move(paintProperties)); - layer->bucket = std::make_shared<StyleBucket>(layer->type); - layer->bucket->name = layer->id; - layer->bucket->source = AnnotationManager::SourceID; - layer->bucket->source_layer = layer->id; + } else { + const StyleLayer* sourceLayer = style.getLayer(shape.properties.get<std::string>()); + if (!sourceLayer) return; + + switch (sourceLayer->type) { + case StyleLayerType::Line: + layer = createLineLayer(); + break; + + case StyleLayerType::Fill: + layer = createFillLayer(); + break; - style.addLayer(std::move(layer), AnnotationManager::PointLayerID); + default: + return; + } + + layer->styles = sourceLayer->styles; + layer->bucket->layout = sourceLayer->bucket->layout; } + + layer->bucket->name = layer->id; + layer->bucket->source = AnnotationManager::SourceID; + layer->bucket->source_layer = layer->id; + + style.addLayer(std::move(layer), AnnotationManager::PointLayerID); +} + +std::unique_ptr<StyleLayer> ShapeAnnotationImpl::createLineLayer() { + type = ProjectedFeatureType::LineString; + std::unique_ptr<LineLayer> layer = std::make_unique<LineLayer>(); + layer->id = layerID; + layer->type = StyleLayerType::Line; + layer->bucket = std::make_shared<StyleBucket>(layer->type); + layer->bucket->layout.set(PropertyKey::LineJoin, ConstantFunction<JoinType>(JoinType::Round)); + return std::move(layer); +} + +std::unique_ptr<StyleLayer> ShapeAnnotationImpl::createFillLayer() { + type = ProjectedFeatureType::Polygon; + std::unique_ptr<FillLayer> layer = std::make_unique<FillLayer>(); + layer->id = layerID; + layer->type = StyleLayerType::Fill; + layer->bucket = std::make_shared<StyleBucket>(layer->type); + return std::move(layer); } void ShapeAnnotationImpl::updateTile(const TileID& tileID, AnnotationTile& tile) { - const auto& shapeTile = shapeTiler.getTile(tileID.z, tileID.x, tileID.y); + if (!shapeTiler) { + const double baseTolerance = 3; + const uint16_t extent = 4096; + const double tolerance = baseTolerance / ((1 << maxZoom) * extent); + + ProjectedGeometryContainer rings; + std::vector<LonLat> points; + + for (size_t i = 0; i < shape.segments[0].size(); ++i) { // first segment for now (no holes) + const double constraintedLatitude = ::fmin(::fmax(shape.segments[0][i].latitude, -util::LATITUDE_MAX), util::LATITUDE_MAX); + points.push_back(LonLat(shape.segments[0][i].longitude, constraintedLatitude)); + } + + if (type == ProjectedFeatureType::Polygon && + (points.front().lon != points.back().lon || points.front().lat != points.back().lat)) { + points.push_back(LonLat(points.front().lon, points.front().lat)); + } + + ProjectedGeometryContainer ring = Convert::project(points, tolerance); + rings.members.push_back(ring); + + std::vector<ProjectedFeature> features; + features.push_back(Convert::create(Tags(), type, rings)); + + shapeTiler = std::make_unique<mapbox::util::geojsonvt::GeoJSONVT>(features, maxZoom, 4, 100, 10); + } + + const auto& shapeTile = shapeTiler->getTile(tileID.z, tileID.x, tileID.y); if (!shapeTile) return; diff --git a/src/mbgl/annotation/shape_annotation_impl.hpp b/src/mbgl/annotation/shape_annotation_impl.hpp index 4cf6c23f61..1b1dacf370 100644 --- a/src/mbgl/annotation/shape_annotation_impl.hpp +++ b/src/mbgl/annotation/shape_annotation_impl.hpp @@ -13,6 +13,7 @@ namespace mbgl { class Style; +class StyleLayer; class AnnotationTile; class ShapeAnnotationImpl { @@ -30,7 +31,12 @@ public: const ShapeAnnotation shape; private: - mapbox::util::geojsonvt::GeoJSONVT shapeTiler; + std::unique_ptr<StyleLayer> createLineLayer(); + std::unique_ptr<StyleLayer> createFillLayer(); + + const uint8_t maxZoom; + mapbox::util::geojsonvt::ProjectedFeatureType type; + std::unique_ptr<mapbox::util::geojsonvt::GeoJSONVT> shapeTiler; }; } |