1 #include <mbgl/renderer/buckets/heatmap_bucket.hpp>
2 #include <mbgl/renderer/bucket_parameters.hpp>
3 #include <mbgl/programs/heatmap_program.hpp>
4 #include <mbgl/style/layers/heatmap_layer_impl.hpp>
5 #include <mbgl/renderer/layers/render_heatmap_layer.hpp>
6 #include <mbgl/util/constants.hpp>
7 #include <mbgl/util/math.hpp>
8 
9 namespace mbgl {
10 
11 using namespace style;
12 
HeatmapBucket(const BucketParameters & parameters,const std::vector<const RenderLayer * > & layers)13 HeatmapBucket::HeatmapBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers)
14     : Bucket(LayerType::Heatmap),
15       mode(parameters.mode) {
16     for (const auto& layer : layers) {
17         paintPropertyBinders.emplace(
18             std::piecewise_construct,
19             std::forward_as_tuple(layer->getID()),
20             std::forward_as_tuple(
21                 layer->as<RenderHeatmapLayer>()->evaluated,
22                 parameters.tileID.overscaledZ));
23     }
24 }
25 
upload(gl::Context & context)26 void HeatmapBucket::upload(gl::Context& context) {
27     vertexBuffer = context.createVertexBuffer(std::move(vertices));
28     indexBuffer = context.createIndexBuffer(std::move(triangles));
29 
30     for (auto& pair : paintPropertyBinders) {
31         pair.second.upload(context);
32     }
33 
34     uploaded = true;
35 }
36 
hasData() const37 bool HeatmapBucket::hasData() const {
38     return !segments.empty();
39 }
40 
addFeature(const GeometryTileFeature & feature,const GeometryCollection & geometry)41 void HeatmapBucket::addFeature(const GeometryTileFeature& feature,
42                               const GeometryCollection& geometry) {
43     constexpr const uint16_t vertexLength = 4;
44 
45     for (auto& points : geometry) {
46         for(auto& point : points) {
47             auto x = point.x;
48             auto y = point.y;
49 
50             // Do not include points that are outside the tile boundaries.
51             // Include all points in Still mode. You need to include points from
52             // neighbouring tiles so that they are not clipped at tile boundaries.
53             if ((mode == MapMode::Continuous) &&
54                 (x < 0 || x >= util::EXTENT || y < 0 || y >= util::EXTENT)) continue;
55 
56             if (segments.empty() || segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
57                 // Move to a new segments because the old one can't hold the geometry.
58                 segments.emplace_back(vertices.vertexSize(), triangles.indexSize());
59             }
60 
61             // this geometry will be of the Point type, and we'll derive
62             // two triangles from it.
63             //
64             // ┌─────────┐
65             // │ 4     3 │
66             // │         │
67             // │ 1     2 │
68             // └─────────┘
69             //
70             vertices.emplace_back(HeatmapProgram::vertex(point, -1, -1)); // 1
71             vertices.emplace_back(HeatmapProgram::vertex(point,  1, -1)); // 2
72             vertices.emplace_back(HeatmapProgram::vertex(point,  1,  1)); // 3
73             vertices.emplace_back(HeatmapProgram::vertex(point, -1,  1)); // 4
74 
75             auto& segment = segments.back();
76             assert(segment.vertexLength <= std::numeric_limits<uint16_t>::max());
77             uint16_t index = segment.vertexLength;
78 
79             // 1, 2, 3
80             // 1, 4, 3
81             triangles.emplace_back(index, index + 1, index + 2);
82             triangles.emplace_back(index, index + 3, index + 2);
83 
84             segment.vertexLength += vertexLength;
85             segment.indexLength += 6;
86         }
87     }
88 
89     for (auto& pair : paintPropertyBinders) {
90         pair.second.populateVertexVectors(feature, vertices.vertexSize());
91     }
92 }
93 
getQueryRadius(const RenderLayer & layer) const94 float HeatmapBucket::getQueryRadius(const RenderLayer& layer) const {
95     (void)layer;
96     return 0;
97 }
98 
99 } // namespace mbgl
100