@@ -62,6 +62,39 @@ GpuVectorLayerTile preprocess(tile::Id id, const QByteArray& vector_tile_data, c
62
62
} // namespace nucleus::vector_layer
63
63
namespace nucleus ::vector_layer::details {
64
64
65
+ std::vector<std::pair<uint32_t , uint32_t >> simplify_styles (std::vector<std::pair<uint32_t , uint32_t >> style_indices, const std::vector<glm::u32vec4> style_buffer)
66
+ {
67
+ // we get multiple styles that may have full opacity and the same width
68
+ // creating render calls for both does not make sense -> we only want to draw the top layer
69
+ // this function simplifys all the styles so that only the styles which actually have a change to be rendered will remain
70
+
71
+ // order the styles so that we look at layer in descending order
72
+ std::sort (style_indices.begin (), style_indices.end (), [](std::pair<uint32_t , uint32_t > a, std::pair<uint32_t , uint32_t > b) { return a.second > b.second ; });
73
+
74
+ std::vector<std::pair<uint32_t , uint32_t >> out_styles;
75
+ int accummulative_opacity = 0 ;
76
+ float width = 0.0 ;
77
+
78
+ for (const auto & indices : style_indices) {
79
+ const auto style_data = style_buffer[indices.first ];
80
+ const float current_width = float (style_data.z ) / float (constants::style_precision);
81
+ const int current_opacity = style_data.x & 255 ;
82
+
83
+ if (width < current_width) {
84
+ // reset opacity
85
+ accummulative_opacity = 0 ;
86
+ width = current_width;
87
+ }
88
+
89
+ if (accummulative_opacity < 255 ) {
90
+ accummulative_opacity += current_opacity;
91
+ out_styles.push_back (indices);
92
+ }
93
+ }
94
+
95
+ return out_styles;
96
+ }
97
+
65
98
std::vector<GeometryData> parse_tile (tile::Id id, const QByteArray& vector_tile_data, const Style & style)
66
99
{
67
100
const auto d = vector_tile_data.toStdString ();
@@ -93,9 +126,10 @@ std::vector<GeometryData> parse_tile(tile::Id id, const QByteArray& vector_tile_
93
126
const auto feature = mapbox::vector_tile::feature (layer.getFeature (i), layer);
94
127
95
128
const auto type = (feature.getType () == mapbox::vector_tile::GeomType::LINESTRING) ? " line" : " fill" ;
96
- auto styles = style.indices (layer_name, type, id.zoom_level , feature);
129
+ auto style_indices = style.indices (layer_name, type, id.zoom_level , feature);
130
+ style_indices = simplify_styles (style_indices, style_buffer);
97
131
98
- if (styles .size () == 0 ) // no styles found -> we do not visualize it
132
+ if (style_indices .size () == 0 ) // no styles found -> we do not visualize it
99
133
continue ;
100
134
101
135
if (feature.getType () == mapbox::vector_tile::GeomType::POLYGON) {
@@ -114,7 +148,7 @@ std::vector<GeometryData> parse_tile(tile::Id id, const QByteArray& vector_tile_
114
148
115
149
// TODO performance -> might be more efficient to find out if the style is the same and the alpha is full -> only visualize the higher layer_index
116
150
117
- for (const auto & style : styles )
151
+ for (const auto & style : style_indices )
118
152
data.emplace_back (vertices, extent, style.first , style.second , true , all_edges, 0 );
119
153
// data.emplace_back(std::vector<glm::vec2>(vertices), extent, styles[0].first, styles[0].second, true, std::vector<glm::ivec2>(edges), 0);
120
154
// data.push_back({ vertices, extent, styles[0].first, styles[0].second, true, all_edges, 0 });
@@ -131,7 +165,7 @@ std::vector<GeometryData> parse_tile(tile::Id id, const QByteArray& vector_tile_
131
165
132
166
// TODO performance -> instead of duplicating the vertice data we only want to duplicate the index data
133
167
134
- for (const auto & style : styles ) {
168
+ for (const auto & style : style_indices ) {
135
169
const auto line_width = float (style_buffer[style.first ].z ) / float (constants::style_precision);
136
170
data.emplace_back (vertices, extent, style.first , style.second , false , no_edges, line_width);
137
171
}
0 commit comments