maplibre/vector/
transferables.rs

1use std::fmt::{Debug, Formatter};
2
3use geozero::mvt::tile::Layer;
4
5use crate::{
6    coords::WorldTileCoords,
7    io::{
8        apc::{IntoMessage, Message, MessageTag},
9        geometry_index::TileIndex,
10    },
11    render::{
12        shaders::{ShaderSymbolVertex, ShaderSymbolVertexNew},
13        ShaderVertex,
14    },
15    sdf::{Feature, SymbolLayerData},
16    vector::{
17        tessellation::{IndexDataType, OverAlignedVertexBuffer},
18        AvailableVectorLayerBucket, MissingVectorLayerBucket,
19    },
20};
21
22#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
23pub enum VectorMessageTag {
24    TileTessellated = 1,
25    LayerMissing = 2,
26    LayerTessellated = 3,
27    SymbolLayerTessellated = 4,
28    LayerIndexed = 10,
29}
30
31impl MessageTag for VectorMessageTag {
32    fn dyn_clone(&self) -> Box<dyn MessageTag> {
33        Box::new(*self)
34    }
35}
36
37pub trait TileTessellated: IntoMessage + Debug + Send {
38    fn message_tag() -> &'static dyn MessageTag;
39
40    fn build_from(coords: WorldTileCoords) -> Self
41    where
42        Self: Sized;
43
44    fn coords(&self) -> WorldTileCoords;
45}
46
47pub trait LayerMissing: IntoMessage + Debug + Send {
48    fn message_tag() -> &'static dyn MessageTag;
49
50    fn build_from(coords: WorldTileCoords, layer_name: String) -> Self
51    where
52        Self: Sized;
53
54    fn coords(&self) -> WorldTileCoords;
55
56    fn layer_name(&self) -> &str;
57
58    fn to_bucket(self) -> MissingVectorLayerBucket;
59}
60
61pub trait LayerTessellated: IntoMessage + Debug + Send {
62    fn message_tag() -> &'static dyn MessageTag;
63
64    fn build_from(
65        coords: WorldTileCoords,
66        buffer: OverAlignedVertexBuffer<ShaderVertex, IndexDataType>,
67        feature_indices: Vec<u32>,
68        feature_colors: Vec<[f32; 4]>,
69        layer_data: Layer,
70        style_layer_id: String,
71    ) -> Self
72    where
73        Self: Sized;
74
75    fn coords(&self) -> WorldTileCoords;
76
77    fn is_empty(&self) -> bool;
78
79    fn style_layer_id(&self) -> &str;
80
81    fn to_bucket(self) -> AvailableVectorLayerBucket;
82}
83
84pub trait SymbolLayerTessellated: IntoMessage + Debug + Send {
85    fn message_tag() -> &'static dyn MessageTag;
86
87    fn build_from(
88        coords: WorldTileCoords,
89        buffer: OverAlignedVertexBuffer<ShaderSymbolVertex, IndexDataType>,
90        new_buffer: OverAlignedVertexBuffer<ShaderSymbolVertexNew, IndexDataType>,
91        features: Vec<Feature>,
92        layer_data: Layer,
93        style_layer_id: String,
94    ) -> Self
95    where
96        Self: Sized;
97
98    fn coords(&self) -> WorldTileCoords;
99
100    fn is_empty(&self) -> bool;
101
102    fn to_bucket(self) -> SymbolLayerData;
103}
104
105pub trait LayerIndexed: IntoMessage + Debug + Send {
106    fn message_tag() -> &'static dyn MessageTag;
107
108    fn build_from(coords: WorldTileCoords, index: TileIndex) -> Self
109    where
110        Self: Sized;
111
112    fn coords(&self) -> WorldTileCoords;
113
114    fn to_tile_index(self) -> TileIndex;
115}
116
117pub struct DefaultTileTessellated {
118    coords: WorldTileCoords,
119}
120
121impl Debug for DefaultTileTessellated {
122    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
123        write!(f, "DefaultTileTessellated({})", self.coords)
124    }
125}
126
127impl IntoMessage for DefaultTileTessellated {
128    fn into(self) -> Message {
129        Message::new(Self::message_tag(), Box::new(self))
130    }
131}
132
133impl TileTessellated for DefaultTileTessellated {
134    fn message_tag() -> &'static dyn MessageTag {
135        &VectorMessageTag::TileTessellated
136    }
137
138    fn build_from(coords: WorldTileCoords) -> Self {
139        Self { coords }
140    }
141
142    fn coords(&self) -> WorldTileCoords {
143        self.coords
144    }
145}
146
147pub struct DefaultLayerMissing {
148    pub coords: WorldTileCoords,
149    pub layer_name: String,
150}
151
152impl Debug for DefaultLayerMissing {
153    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
154        write!(f, "DefaultLayerMissing({})", self.coords)
155    }
156}
157
158impl IntoMessage for DefaultLayerMissing {
159    fn into(self) -> Message {
160        Message::new(Self::message_tag(), Box::new(self))
161    }
162}
163
164impl LayerMissing for DefaultLayerMissing {
165    fn message_tag() -> &'static dyn MessageTag {
166        &VectorMessageTag::LayerMissing
167    }
168
169    fn build_from(coords: WorldTileCoords, layer_name: String) -> Self {
170        Self { coords, layer_name }
171    }
172
173    fn coords(&self) -> WorldTileCoords {
174        self.coords
175    }
176
177    fn layer_name(&self) -> &str {
178        &self.layer_name
179    }
180
181    fn to_bucket(self) -> MissingVectorLayerBucket {
182        MissingVectorLayerBucket {
183            coords: self.coords,
184            source_layer: self.layer_name,
185        }
186    }
187}
188
189#[derive(Clone)]
190pub struct DefaultLayerTessellated {
191    pub coords: WorldTileCoords,
192    pub buffer: OverAlignedVertexBuffer<ShaderVertex, IndexDataType>,
193    /// Holds for each feature the count of indices.
194    pub feature_indices: Vec<u32>,
195    pub feature_colors: Vec<[f32; 4]>,
196    pub layer_data: Layer, // FIXME (perf): Introduce a better structure for this
197    pub style_layer_id: String,
198}
199
200impl Debug for DefaultLayerTessellated {
201    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
202        write!(f, "DefaultLayerTesselated({})", self.coords)
203    }
204}
205
206impl IntoMessage for DefaultLayerTessellated {
207    fn into(self) -> Message {
208        Message::new(Self::message_tag(), Box::new(self))
209    }
210}
211
212impl LayerTessellated for DefaultLayerTessellated {
213    fn message_tag() -> &'static dyn MessageTag {
214        &VectorMessageTag::LayerTessellated
215    }
216
217    fn build_from(
218        coords: WorldTileCoords,
219        buffer: OverAlignedVertexBuffer<ShaderVertex, IndexDataType>,
220        feature_indices: Vec<u32>,
221        feature_colors: Vec<[f32; 4]>,
222        layer_data: Layer,
223        style_layer_id: String,
224    ) -> Self {
225        Self {
226            coords,
227            buffer,
228            feature_indices,
229            feature_colors,
230            layer_data,
231            style_layer_id,
232        }
233    }
234
235    fn coords(&self) -> WorldTileCoords {
236        self.coords
237    }
238
239    fn is_empty(&self) -> bool {
240        self.buffer.usable_indices == 0
241    }
242
243    fn style_layer_id(&self) -> &str {
244        &self.style_layer_id
245    }
246
247    fn to_bucket(self) -> AvailableVectorLayerBucket {
248        AvailableVectorLayerBucket {
249            coords: self.coords,
250            source_layer: self.layer_data.name,
251            style_layer_id: self.style_layer_id,
252            buffer: self.buffer,
253            feature_indices: self.feature_indices,
254            feature_colors: self.feature_colors,
255        }
256    }
257}
258
259pub struct DefaultSymbolLayerTessellated {
260    pub coords: WorldTileCoords,
261    pub buffer: OverAlignedVertexBuffer<ShaderSymbolVertex, IndexDataType>,
262    pub new_buffer: OverAlignedVertexBuffer<ShaderSymbolVertexNew, IndexDataType>,
263    pub features: Vec<Feature>,
264    pub layer_data: Layer, // FIXME (perf): Introduce a better structure for this
265    pub style_layer_id: String,
266}
267
268impl Debug for crate::vector::transferables::DefaultSymbolLayerTessellated {
269    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
270        write!(f, "DefaultSymbolLayerTessellated({})", self.coords)
271    }
272}
273
274impl IntoMessage for crate::vector::transferables::DefaultSymbolLayerTessellated {
275    fn into(self) -> Message {
276        Message::new(Self::message_tag(), Box::new(self))
277    }
278}
279
280impl SymbolLayerTessellated for crate::vector::transferables::DefaultSymbolLayerTessellated {
281    fn message_tag() -> &'static dyn MessageTag {
282        &VectorMessageTag::SymbolLayerTessellated
283    }
284
285    fn build_from(
286        coords: WorldTileCoords,
287        buffer: OverAlignedVertexBuffer<ShaderSymbolVertex, IndexDataType>,
288        new_buffer: OverAlignedVertexBuffer<ShaderSymbolVertexNew, IndexDataType>,
289        features: Vec<Feature>,
290        layer_data: Layer,
291        style_layer_id: String,
292    ) -> Self {
293        Self {
294            coords,
295            buffer,
296            new_buffer,
297            features,
298            layer_data,
299            style_layer_id,
300        }
301    }
302
303    fn coords(&self) -> WorldTileCoords {
304        self.coords
305    }
306
307    fn is_empty(&self) -> bool {
308        self.new_buffer.usable_indices == 0
309    }
310
311    fn to_bucket(self) -> SymbolLayerData {
312        SymbolLayerData {
313            coords: self.coords,
314            source_layer: self.layer_data.name,
315            style_layer_id: self.style_layer_id,
316            buffer: self.buffer,
317            new_buffer: self.new_buffer,
318            features: self.features,
319        }
320    }
321}
322
323pub struct DefaultLayerIndexed {
324    coords: WorldTileCoords,
325    index: TileIndex,
326}
327
328impl Debug for DefaultLayerIndexed {
329    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
330        write!(f, "DefaultLayerIndexed({})", self.coords)
331    }
332}
333
334impl IntoMessage for DefaultLayerIndexed {
335    fn into(self) -> Message {
336        Message::new(Self::message_tag(), Box::new(self))
337    }
338}
339
340impl LayerIndexed for DefaultLayerIndexed {
341    fn message_tag() -> &'static dyn MessageTag {
342        &VectorMessageTag::LayerIndexed
343    }
344
345    fn build_from(coords: WorldTileCoords, index: TileIndex) -> Self {
346        Self { coords, index }
347    }
348
349    fn coords(&self) -> WorldTileCoords {
350        self.coords
351    }
352
353    fn to_tile_index(self) -> TileIndex {
354        self.index
355    }
356}
357
358pub trait VectorTransferables: Copy + Clone + 'static {
359    type TileTessellated: TileTessellated;
360    type LayerMissing: LayerMissing;
361    type LayerTessellated: LayerTessellated;
362    type SymbolLayerTessellated: SymbolLayerTessellated;
363    type LayerIndexed: LayerIndexed;
364}
365
366#[derive(Copy, Clone)]
367pub struct DefaultVectorTransferables;
368
369impl VectorTransferables for DefaultVectorTransferables {
370    type TileTessellated = DefaultTileTessellated;
371    type LayerMissing = DefaultLayerMissing;
372    type LayerTessellated = DefaultLayerTessellated;
373    type SymbolLayerTessellated = DefaultSymbolLayerTessellated;
374    type LayerIndexed = DefaultLayerIndexed;
375}