ovtile/open/
vector_layer.rs

1use pbf::{ProtoRead, Protobuf};
2
3use crate::{
4    base::BaseVectorLayer,
5    open::{
6        decode_shape, encode_shape, read_feature, write_feature, ColumnCacheReader,
7        ColumnCacheWriter, Extent, OpenVectorFeature, Shape,
8    },
9    VectorLayerMethods,
10};
11
12use core::cell::RefCell;
13
14use alloc::rc::Rc;
15use alloc::string::String;
16use alloc::vec::Vec;
17
18/// The Open Vector Layer class represents a layer in an Open Vector Tile.
19/// Contains an extent, name, version, and features.
20/// The features will utilize the layer extent to decode geometry.
21#[derive(Debug)]
22pub struct OpenVectorLayer {
23    /// the version of the vector tile
24    pub version: u16,
25    /// the name of the layer
26    pub name: String,
27    /// the extent of the vector layer
28    pub extent: Extent,
29    /// the features in the layer
30    pub features: Vec<OpenVectorFeature>,
31    shape: Option<Shape>,
32    m_shape: Option<Shape>,
33    cache: Rc<RefCell<ColumnCacheReader>>,
34}
35impl OpenVectorLayer {
36    /// Create a new OpenVectorLayer
37    pub fn new(cache: Rc<RefCell<ColumnCacheReader>>) -> OpenVectorLayer {
38        OpenVectorLayer {
39            version: 1,
40            name: String::new(),
41            extent: Extent::default(),
42            shape: None,
43            m_shape: None,
44            features: Vec::new(),
45            cache,
46        }
47    }
48}
49impl VectorLayerMethods for OpenVectorLayer {
50    fn version(&self) -> u16 {
51        self.version
52    }
53    fn name(&self) -> String {
54        self.name.clone()
55    }
56    fn extent(&self) -> usize {
57        self.extent.into()
58    }
59    fn len(&self) -> usize {
60        self.features.len()
61    }
62    fn is_empty(&self) -> bool {
63        self.features.is_empty()
64    }
65    fn feature(&mut self, i: usize) -> Option<&mut dyn crate::VectorFeatureMethods> {
66        self.features.get_mut(i).map(|f| f as &mut dyn crate::VectorFeatureMethods)
67    }
68}
69impl ProtoRead for OpenVectorLayer {
70    fn read(&mut self, tag: u64, pb: &mut Protobuf) {
71        match tag {
72            1 => self.version = pb.read_varint::<u16>(),
73            2 => {
74                self.name = {
75                    let mut cache = self.cache.borrow_mut();
76                    cache.get_string(pb.read_varint())
77                }
78            }
79            3 => self.extent = pb.read_varint::<Extent>(),
80            4 => self.features.push(read_feature(
81                pb.read_bytes(),
82                self.extent,
83                self.cache.clone(),
84                &self.shape.clone().unwrap_or_default(),
85                self.m_shape.clone().unwrap_or_default(),
86            )),
87            5 => {
88                self.shape = {
89                    let mut cache = self.cache.borrow_mut();
90                    Some(decode_shape(pb.read_varint(), &mut cache))
91                }
92            }
93            6 => {
94                self.m_shape = {
95                    let mut cache: core::cell::RefMut<ColumnCacheReader> = self.cache.borrow_mut();
96                    Some(decode_shape(pb.read_varint(), &mut cache))
97                }
98            }
99            #[tarpaulin::skip]
100            _ => panic!("unknown tag: {}", tag),
101        }
102    }
103}
104
105/// Write the layer to a protobuf
106pub fn write_layer(layer: &mut BaseVectorLayer, cache: &mut ColumnCacheWriter) -> Vec<u8> {
107    let mut pbf = Protobuf::new();
108
109    pbf.write_varint_field(1, layer.version);
110    pbf.write_varint_field(2, cache.add_string(layer.name.clone()));
111    pbf.write_varint_field(3, layer.extent);
112    pbf.write_varint_field(5, encode_shape(&layer.shape, cache));
113    if let Some(ref m_shape) = layer.m_shape {
114        pbf.write_varint_field(6, encode_shape(m_shape, cache));
115    }
116
117    // sort by feature type
118    layer.features.sort_by_key(|a| a.get_type());
119
120    for feature in &layer.features {
121        pbf.write_bytes_field(
122            4,
123            &write_feature(feature, &layer.shape, layer.m_shape.as_ref(), cache),
124        );
125    }
126
127    pbf.take()
128}