open_vector_tile/open/
vector_layer.rs

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