• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Open-S2 / open-vector-tile / #19

15 Aug 2024 12:44AM UTC coverage: 43.923% (+9.0%) from 34.908%
#19

push

Mr Martian
fix coveralls

2349 of 5348 relevant lines covered (43.92%)

46.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/rust/vector_tile.rs
1
use crate::{VectorLines3DWithOffset, VectorPoints3D};
2

3
use pbf::{ProtoRead, Protobuf};
4

5
use alloc::collections::BTreeMap;
6
use alloc::rc::Rc;
7
use alloc::string::String;
8
use alloc::vec::Vec;
9

10
use core::cell::RefCell;
11

12
use crate::{
13
    base::BaseVectorTile,
14
    mapbox::MapboxVectorLayer,
15
    open::{
16
        write_layer, ColumnCacheReader, ColumnCacheWriter, FeatureType, OpenVectorLayer, Properties,
17
    },
18
    VectorGeometry, VectorLinesWithOffset, VectorPoints, BBOX,
19
};
20

21
/// Methods that all vector features should have
22
pub trait VectorFeatureMethods {
23
    /// the id of the feature
24
    fn id(&self) -> Option<u64>;
25
    /// the version of the vector tile
26
    fn version(&self) -> u16;
27
    /// the properties
28
    fn properties(&self) -> Properties;
29
    /// the extent
30
    fn extent(&self) -> usize;
31
    /// the feature type
32
    fn get_type(&self) -> FeatureType;
33
    /// the bounding box
34
    fn bbox(&self) -> Option<BBOX>;
35
    /// whether the feature has m values
36
    fn has_m_values(&self) -> bool;
37
    /// regardless of the type, we return a flattend point array
38
    fn load_points(&mut self) -> VectorPoints;
39
    /// regardless of the type, we return a flattend point3D array
40
    fn load_points_3d(&mut self) -> VectorPoints3D;
41
    /// an array of lines. The offsets will be set to 0
42
    fn load_lines(&mut self) -> VectorLinesWithOffset;
43
    /// an array of 3D lines. The offsets will be set to 0
44
    fn load_lines_3d(&mut self) -> VectorLines3DWithOffset;
45
    /// (flattened geometry & tesslation if applicable, indices)
46
    fn load_geometry_flat(&mut self) -> (Vec<f64>, Vec<u32>);
47
    /// load the geometry
48
    fn load_geometry(&mut self) -> VectorGeometry;
49
    /// load the indices
50
    fn read_indices(&mut self) -> Vec<u32>;
51
    /// Add tesselation data to the geometry
52
    fn add_tesselation(&mut self, geometry: &mut Vec<f64>, multiplier: f64);
53
    /// Add 3D tesselation data to the geometry
54
    fn add_tesselation_3d(&mut self, geometry: &mut Vec<f64>, multiplier: f64);
55
}
56

57
/// Methods that all vector layers should have
58
pub trait VectorLayerMethods {
59
    /// the version of the vector tile layer.
60
    fn version(&self) -> u16;
61
    /// the name of the layer
62
    fn name(&self) -> String;
63
    /// the extent of the vector tile (only **512**, **1_024**, **2_048**, **4_096**, and **8_192**
64
    /// are supported for the open spec)
65
    fn extent(&self) -> usize;
66
    /// grab a feature from the layer
67
    fn feature(&mut self, i: usize) -> Option<&mut dyn VectorFeatureMethods>;
68
    /// length (layer count)
69
    fn len(&self) -> usize;
70
    /// empty (layer count is 0)
71
    fn is_empty(&self) -> bool;
72
}
73

74
/// Layer container supporting both mapbox and open vector layers
75
#[derive(Debug)]
76
pub enum VectorLayer {
77
    /// Mapbox vector layer
78
    Mapbox(MapboxVectorLayer),
79
    /// Open vector layer
80
    Open(OpenVectorLayer),
81
}
82
impl VectorLayerMethods for VectorLayer {
83
    fn version(&self) -> u16 {
×
84
        match self {
×
85
            VectorLayer::Mapbox(layer) => layer.version(),
×
86
            VectorLayer::Open(layer) => layer.version(),
×
87
        }
88
    }
×
89

90
    fn name(&self) -> String {
×
91
        match self {
×
92
            VectorLayer::Mapbox(layer) => layer.name(),
×
93
            VectorLayer::Open(layer) => layer.name(),
×
94
        }
95
    }
×
96

97
    fn extent(&self) -> usize {
×
98
        match self {
×
99
            VectorLayer::Mapbox(layer) => layer.extent(),
×
100
            VectorLayer::Open(layer) => layer.extent(),
×
101
        }
102
    }
×
103

104
    fn feature(&mut self, i: usize) -> Option<&mut dyn VectorFeatureMethods> {
×
105
        match self {
×
106
            VectorLayer::Mapbox(layer) => layer.feature(i),
×
107
            VectorLayer::Open(layer) => layer.feature(i),
×
108
        }
109
    }
×
110

111
    fn len(&self) -> usize {
×
112
        match self {
×
113
            VectorLayer::Mapbox(layer) => layer.len(),
×
114
            VectorLayer::Open(layer) => layer.len(),
×
115
        }
116
    }
×
117

118
    fn is_empty(&self) -> bool {
×
119
        match self {
×
120
            VectorLayer::Mapbox(layer) => layer.is_empty(),
×
121
            VectorLayer::Open(layer) => layer.is_empty(),
×
122
        }
123
    }
×
124
}
125

126
/// The vector tile struct that covers both "open" and "mapbox" specifications
127
#[derive(Debug)]
128
pub struct VectorTile {
129
    /// the layers in the vector tile
130
    pub layers: BTreeMap<String, VectorLayer>,
131
    /// indexes to track the layers. Needed for the open spec because we need the cache before we can
132
    /// parse layers and features
133
    layer_indexes: Vec<usize>,
134
    /// the protobuf for the vector tile
135
    pbf: Rc<RefCell<Protobuf>>,
136
    /// the column cache
137
    columns: Option<Rc<RefCell<ColumnCacheReader>>>,
138
}
139
impl VectorTile {
140
    /// Create a new vector tile
141
    pub fn new(data: Vec<u8>, end: Option<usize>) -> Self {
×
142
        let pbf = Rc::new(RefCell::new(data.into()));
×
143
        let mut vt = VectorTile {
×
144
            pbf: pbf.clone(),
×
145
            columns: None,
×
146
            layer_indexes: Vec::new(),
×
147
            layers: BTreeMap::new(),
×
148
        };
×
149

×
150
        pbf.borrow_mut().read_fields(&mut vt, end);
×
151

×
152
        if !vt.layer_indexes.is_empty() {
×
153
            vt.read_layers();
×
154
        }
×
155

156
        vt
×
157
    }
×
158

159
    /// Read the layers
160
    pub fn read_layers(&mut self) -> Option<()> {
×
161
        let layer_indexes = self.layer_indexes.clone();
×
162
        let mut tmp_pbf = self.pbf.borrow_mut();
×
163
        let cache = self.columns.as_ref()?.clone();
×
164

165
        for pos in layer_indexes {
×
166
            tmp_pbf.set_pos(pos);
×
167
            let mut layer = OpenVectorLayer::new(cache.clone());
×
168
            tmp_pbf.read_message(&mut layer);
×
169
            self.layers
×
170
                .insert(layer.name.clone(), VectorLayer::Open(layer));
×
171
        }
×
172

173
        Some(())
×
174
    }
×
175

176
    /// Get a layer given the name
177
    pub fn layer(&mut self, name: &str) -> Option<&mut VectorLayer> {
×
178
        self.layers.get_mut(name)
×
179
    }
×
180
}
181
impl ProtoRead for VectorTile {
182
    fn read(&mut self, tag: u64, pb: &mut Protobuf) {
×
183
        match tag {
×
184
            1 | 3 => {
×
185
                let mut layer = MapboxVectorLayer::new(self.pbf.clone(), tag == 1);
×
186
                pb.read_message(&mut layer);
×
187
                self.layers
×
188
                    .insert(layer.name.clone(), VectorLayer::Mapbox(layer));
×
189
            }
×
190
            4 => {
×
191
                // store the position of each layer for later retrieval.
×
192
                // Columns must be prepped before reading the layer.
×
193
                self.layer_indexes.push(pb.get_pos());
×
194
            }
×
195
            5 => {
×
196
                let mut column_reader = ColumnCacheReader::new();
×
197
                pb.read_message(&mut column_reader);
×
198
                self.columns = Some(Rc::new(RefCell::new(column_reader)));
×
199
            }
×
200
            _ => panic!("unknown tag: {}", tag),
×
201
        }
202
    }
×
203
}
204

205
/// writer for converting a BaseVectorTile to encoded bytes of the Open Vector Tile format
206
pub fn write_tile(tile: &mut BaseVectorTile) -> Vec<u8> {
×
207
    let mut pbf = Protobuf::new();
×
208
    let mut cache = ColumnCacheWriter::default();
×
209

210
    // first write layers
211
    for layer in tile.layers.values_mut() {
×
212
        pbf.write_bytes_field(4, &write_layer(layer, &mut cache));
×
213
    }
×
214
    // now we can write columns
215
    pbf.write_message(5, &cache);
×
216

×
217
    pbf.take()
×
218
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc