use crate::encoder::{GeomData, GeomType};
use crate::error::{Error, Result};
use crate::vector_tile::Tile as VecTile;
use crate::vector_tile::tile::{
Feature as VtFeature, GeomType as VtGeomType, Layer as VtLayer, Value,
};
use prost::Message;
use std::collections::HashMap;
use std::io::Write;
pub struct Tile {
vec_tile: VecTile,
extent: u32,
}
#[derive(Eq, Hash, PartialEq)]
enum ValueKey {
String(String),
Float(u32),
Double(u64),
Int(i64),
Uint(u64),
Sint(i64),
Bool(bool),
Empty,
}
impl From<&Value> for ValueKey {
fn from(value: &Value) -> Self {
if let Some(value) = &value.string_value {
return Self::String(value.clone());
}
if let Some(value) = value.float_value {
return Self::Float(if value == 0.0 { 0 } else { value.to_bits() });
}
if let Some(value) = value.double_value {
return Self::Double(if value == 0.0 {
0
} else {
value.to_bits()
});
}
if let Some(value) = value.int_value {
return Self::Int(value);
}
if let Some(value) = value.uint_value {
return Self::Uint(value);
}
if let Some(value) = value.sint_value {
return Self::Sint(value);
}
if let Some(value) = value.bool_value {
return Self::Bool(value);
}
Self::Empty
}
}
pub struct Layer {
layer: VtLayer,
key_indices: HashMap<String, usize>,
value_indices: HashMap<ValueKey, usize>,
}
pub struct Feature {
feature: VtFeature,
layer: Layer,
num_keys: usize,
num_values: usize,
}
impl Tile {
pub fn new(extent: u32) -> Self {
let vec_tile = VecTile::default();
Tile { vec_tile, extent }
}
pub fn extent(&self) -> u32 {
self.extent
}
pub fn num_layers(&self) -> usize {
self.vec_tile.layers.len()
}
pub fn create_layer(&self, name: &str) -> Layer {
Layer::new(name, self.extent)
}
pub fn add_layer(&mut self, layer: Layer) -> Result<()> {
if layer.layer.extent != Some(self.extent) {
return Err(Error::WrongExtent());
}
if self
.vec_tile
.layers
.iter()
.any(|n| n.name == layer.layer.name)
{
Err(Error::DuplicateName())
} else {
self.vec_tile.layers.push(layer.layer);
Ok(())
}
}
pub fn write_to(&self, out: &mut dyn Write) -> Result<()> {
out.write_all(&self.vec_tile.encode_to_vec())?;
Ok(())
}
pub fn to_bytes(&self) -> Result<Vec<u8>> {
Ok(self.vec_tile.encode_to_vec())
}
pub fn compute_size(&self) -> usize {
self.vec_tile.encoded_len()
}
}
impl Default for Layer {
fn default() -> Self {
let layer = VtLayer::default();
Layer {
layer,
key_indices: HashMap::new(),
value_indices: HashMap::new(),
}
}
}
impl Layer {
fn new(name: &str, extent: u32) -> Self {
let layer = VtLayer {
version: 2,
name: name.to_string(),
extent: Some(extent),
..Default::default()
};
Layer {
layer,
key_indices: HashMap::new(),
value_indices: HashMap::new(),
}
}
pub fn name(&self) -> Option<&str> {
Some(&self.layer.name)
}
pub fn num_features(&self) -> usize {
self.layer.features.len()
}
pub fn into_feature(self, geom_data: GeomData) -> Feature {
let num_keys = self.layer.keys.len();
let num_values = self.layer.values.len();
let feature = VtFeature {
r#type: Some(match geom_data.geom_type() {
GeomType::Point => VtGeomType::Point as i32,
GeomType::Linestring => VtGeomType::Linestring as i32,
GeomType::Polygon => VtGeomType::Polygon as i32,
}),
geometry: geom_data.into_vec(),
..Default::default()
};
Feature {
feature,
layer: self,
num_keys,
num_values,
}
}
fn key_pos(&mut self, key: &str) -> usize {
if let Some(&index) = self.key_indices.get(key) {
return index;
}
let index = self.layer.keys.len();
let key = key.to_string();
self.layer.keys.push(key.clone());
self.key_indices.insert(key, index);
index
}
fn val_pos(&mut self, value: Value) -> usize {
let value_key = ValueKey::from(&value);
if let Some(&index) = self.value_indices.get(&value_key) {
return index;
}
let index = self.layer.values.len();
self.layer.values.push(value);
self.value_indices.insert(value_key, index);
index
}
}
impl Feature {
pub fn into_layer(mut self) -> Layer {
self.layer.layer.features.push(self.feature);
self.layer
}
pub fn layer(mut self) -> Layer {
self.layer.layer.keys.truncate(self.num_keys);
self.layer.layer.values.truncate(self.num_values);
let num_keys = self.num_keys;
let num_values = self.num_values;
self.layer.key_indices.retain(|_, idx| *idx < num_keys);
self.layer.value_indices.retain(|_, idx| *idx < num_values);
self.layer
}
pub fn set_id(&mut self, id: u64) {
let layer = &self.layer.layer;
if cfg!(debug_assertions)
&& layer.features.iter().any(|f| f.id == Some(id))
{
log::warn!("Duplicate feature ID ({id}) in layer {:?}", layer.name);
}
self.feature.id = Some(id);
}
pub fn num_tags(&self) -> usize {
self.feature.tags.len()
}
pub fn add_tag_string(&mut self, key: &str, val: &str) {
let value = Value {
string_value: Some(val.to_string()),
..Default::default()
};
self.add_tag(key, value);
}
pub fn add_tag_double(&mut self, key: &str, val: f64) {
let value = Value {
double_value: Some(val),
..Default::default()
};
self.add_tag(key, value);
}
pub fn add_tag_float(&mut self, key: &str, val: f32) {
let value = Value {
float_value: Some(val),
..Default::default()
};
self.add_tag(key, value);
}
pub fn add_tag_int(&mut self, key: &str, val: i64) {
let value = Value {
int_value: Some(val),
..Default::default()
};
self.add_tag(key, value);
}
pub fn add_tag_uint(&mut self, key: &str, val: u64) {
let value = Value {
uint_value: Some(val),
..Default::default()
};
self.add_tag(key, value);
}
pub fn add_tag_sint(&mut self, key: &str, val: i64) {
let value = Value {
sint_value: Some(val),
..Default::default()
};
self.add_tag(key, value);
}
pub fn add_tag_bool(&mut self, key: &str, val: bool) {
let value = Value {
bool_value: Some(val),
..Default::default()
};
self.add_tag(key, value);
}
fn add_tag(&mut self, key: &str, value: Value) {
let kidx = self.layer.key_pos(key);
self.feature.tags.push(kidx as u32);
let vidx = self.layer.val_pos(value);
self.feature.tags.push(vidx as u32);
}
}