use crate::{
VectorFeature, VectorLayerMethods,
base::BaseVectorLayer,
mapbox::{MapboxVectorFeature, write_feature},
};
use alloc::{
collections::{BTreeMap, btree_map::Entry},
rc::Rc,
string::String,
vec::Vec,
};
use core::cell::RefCell;
use pbf::{ProtoRead, Protobuf};
use s2json::PrimitiveValue;
#[derive(Debug)]
pub struct MapboxVectorLayer {
pub version: u16,
pub name: String,
pub extent: usize,
pub features: BTreeMap<usize, MapboxVectorFeature>,
pub feature_positions: Vec<usize>,
is_s2: bool,
pbf: Rc<RefCell<Protobuf>>,
keys: Rc<RefCell<Vec<String>>>,
values: Rc<RefCell<Vec<PrimitiveValue>>>,
}
impl MapboxVectorLayer {
pub fn new(pbf: Rc<RefCell<Protobuf>>, is_s2: bool) -> MapboxVectorLayer {
MapboxVectorLayer {
version: 5,
name: String::new(),
extent: 4_096,
is_s2,
pbf: pbf.clone(),
keys: Rc::new(RefCell::new(Vec::new())),
values: Rc::new(RefCell::new(Vec::new())),
features: BTreeMap::new(),
feature_positions: Vec::new(),
}
}
}
impl VectorLayerMethods for MapboxVectorLayer {
fn version(&self) -> u16 {
self.version
}
fn name(&self) -> String {
self.name.clone()
}
fn extent(&self) -> usize {
self.extent
}
fn len(&self) -> usize {
self.feature_positions.len()
}
fn is_empty(&self) -> bool {
self.feature_positions.is_empty()
}
fn feature(&mut self, i: usize) -> Option<VectorFeature<'_>> {
if let Entry::Vacant(e) = self.features.entry(i) {
let mut feature = MapboxVectorFeature::new(
self.pbf.clone(),
self.is_s2,
self.extent,
self.version,
self.keys.clone(),
self.values.clone(),
);
let mut pbf = self.pbf.borrow_mut();
pbf.set_pos(self.feature_positions[i]);
pbf.read_message(&mut feature);
e.insert(feature);
self.features.get_mut(&i).map(Into::into)
} else {
self.features.get_mut(&i).map(Into::into)
}
}
}
impl ProtoRead for MapboxVectorLayer {
fn read(&mut self, tag: u64, pb: &mut Protobuf) {
match tag {
15 => self.version = pb.read_varint::<u16>(),
1 => self.name = pb.read_string(),
2 => self.feature_positions.push(pb.get_pos()),
3 => {
self.keys.borrow_mut().push(pb.read_string());
}
4 => {
let mut value = PrimitiveValue::Null;
pb.read_message(&mut value);
self.values.borrow_mut().push(value);
}
5 => self.extent = pb.read_varint::<usize>(),
_ => panic!("Unknown layer type"),
}
}
}
pub fn write_layer(layer: &BaseVectorLayer, mapbox_support: bool) -> Vec<u8> {
let mut pbf = Protobuf::new();
let mut keys: BTreeMap<String, usize> = BTreeMap::new();
let mut values: BTreeMap<PrimitiveValue, usize> = BTreeMap::new();
pbf.write_varint_field(15, if mapbox_support { 1 } else { 5 });
pbf.write_string_field(1, &layer.name);
for feature in layer.features.iter() {
pbf.write_bytes_field(2, &write_feature(feature, &mut keys, &mut values, mapbox_support));
}
let mut keys: Vec<(String, usize)> = keys.into_iter().collect();
keys.sort_by(|a, b| a.1.cmp(&b.1));
for (key, _) in keys.iter() {
pbf.write_string_field(3, key);
}
let mut values: Vec<(PrimitiveValue, usize)> = values.into_iter().collect();
values.sort_by(|a, b| a.1.cmp(&b.1));
for (value, _) in values.iter() {
pbf.write_message(4, value);
}
pbf.write_varint_field(5, layer.extent as usize);
pbf.take()
}