ovtile/mapbox/
vector_tile.rs

1use pbf::{ProtoRead, Protobuf};
2
3use alloc::collections::BTreeMap;
4use alloc::rc::Rc;
5use alloc::string::String;
6use alloc::vec::Vec;
7
8use core::cell::RefCell;
9
10use crate::{
11    base::BaseVectorTile,
12    mapbox::{write_layer, MapboxVectorLayer},
13};
14
15/// The vector tile struct that covers both "open" and "mapbox" specifications
16#[derive(Debug)]
17pub struct MapboxVectorTile {
18    /// the layers in the vector tile
19    pub layers: BTreeMap<String, MapboxVectorLayer>,
20    /// the protobuf for the vector tile
21    pbf: Rc<RefCell<Protobuf>>,
22}
23impl MapboxVectorTile {
24    /// Create a new vector tile
25    pub fn new(data: Vec<u8>, end: Option<usize>) -> Self {
26        let pbf = Rc::new(RefCell::new(data.into()));
27        let mut vt = MapboxVectorTile { pbf: pbf.clone(), layers: BTreeMap::new() };
28
29        let mut tmp_pbf = pbf.borrow_mut();
30        tmp_pbf.read_fields(&mut vt, end);
31
32        vt
33    }
34
35    /// Get a layer given the name
36    pub fn layer(&mut self, name: &str) -> Option<&mut MapboxVectorLayer> {
37        self.layers.get_mut(name)
38    }
39}
40impl ProtoRead for MapboxVectorTile {
41    fn read(&mut self, tag: u64, pb: &mut Protobuf) {
42        match tag {
43            1 | 3 => {
44                let mut layer = MapboxVectorLayer::new(self.pbf.clone(), tag == 1);
45                pb.read_message(&mut layer);
46                self.layers.insert(layer.name.clone(), layer);
47            }
48            #[tarpaulin::skip]
49            _ => panic!("unknown tag: {}", tag),
50        }
51    }
52}
53
54/// writer for converting a BaseVectorTile to encoded bytes of the Open Vector Flat Tile format or Mapbox Vector Tile
55pub fn write_tile(tile: &mut BaseVectorTile, mapbox_support: bool) -> Vec<u8> {
56    let mut pbf = Protobuf::new();
57
58    // first write layers
59    for layer in tile.layers.values() {
60        pbf.write_bytes_field(
61            if mapbox_support { 3 } else { 1 },
62            &write_layer(layer, mapbox_support),
63        );
64    }
65
66    pbf.take()
67}