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