diff --git a/Cargo.lock b/Cargo.lock index ab381c0d..b23f3476 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1777,6 +1777,7 @@ dependencies = [ "reqwest-middleware-cache", "rstar 0.9.2", "style-spec", + "tile-grid", "tilejson-spec", "tokio", "tracing", @@ -2359,31 +2360,6 @@ dependencies = [ "prost", ] -[[package]] -name = "protobuf" -version = "2.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf7e6d18738ecd0902d30d1ad232c9125985a3422929b16c65517b38adc14f96" - -[[package]] -name = "protobuf-codegen" -version = "2.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aec1632b7c8f2e620343439a7dfd1f3c47b18906c4be58982079911482b5d707" -dependencies = [ - "protobuf", -] - -[[package]] -name = "protobuf-codegen-pure" -version = "2.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f8122fdb18e55190c796b088a16bdb70cd7acdcd48f7a8b796b58c62e532cc6" -dependencies = [ - "protobuf", - "protobuf-codegen", -] - [[package]] name = "quote" version = "1.0.17" @@ -3392,16 +3368,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vector-tile" -version = "0.1.0" -dependencies = [ - "log", - "protobuf", - "protobuf-codegen-pure", - "tile-grid", -] - [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index cd17c7e0..afb197f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,6 @@ [workspace] members = [ - "libs/vector_tile", "libs/style_spec", "libs/tilejson_spec", "libs/wgsl_validate", @@ -87,6 +86,8 @@ rstar = { version = "0.9" } prost = "0.9" geozero = { git = "https://github.com/georust/geozero", rev = "373b731", default-features = false, features = ["with-mvt", "with-geo"]} +tile-grid = "0.3" + # Rendering wgpu = { version = "0.12" } lyon = { version = "0.17", features = [] } diff --git a/libs/vector_tile/Cargo.toml b/libs/vector_tile/Cargo.toml deleted file mode 100644 index ef7d0682..00000000 --- a/libs/vector_tile/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "vector-tile" -version = "0.1.0" -description = "A library for decoding vector tiles" -readme = "README.md" -categories = ["encoding"] -edition = "2021" -build = "build.rs" - -[dependencies] -log = "0.4" -protobuf = { version = "2.27", features = [] } -tile-grid = "0.3" - - -[build-dependencies] -protobuf-codegen-pure = "2.27" - - diff --git a/libs/vector_tile/build.rs b/libs/vector_tile/build.rs deleted file mode 100644 index d4127f86..00000000 --- a/libs/vector_tile/build.rs +++ /dev/null @@ -1,18 +0,0 @@ -use protobuf_codegen_pure::Customize; -use std::path::PathBuf; - -fn main() { - let out_path = PathBuf::from("src/protos"); - protobuf_codegen_pure::Codegen::new() - .customize(Customize { - //carllerche_bytes_for_bytes: Some(true), - //carllerche_bytes_for_string: Some(true), - lite_runtime: Some(true), - ..Default::default() - }) - .out_dir(out_path) - .inputs(&["spec/2.1/vector_tile.proto"]) - .include("spec/2.1") - .run() - .expect("Codegen failed."); -} diff --git a/libs/vector_tile/spec b/libs/vector_tile/spec deleted file mode 160000 index c8d178da..00000000 --- a/libs/vector_tile/spec +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c8d178da65cce0ea474e3d99e3368970ce217093 diff --git a/libs/vector_tile/src/encoding.rs b/libs/vector_tile/src/encoding.rs deleted file mode 100644 index 99895746..00000000 --- a/libs/vector_tile/src/encoding.rs +++ /dev/null @@ -1,259 +0,0 @@ -use std::collections::HashMap; - -use crate::geometry::{ - Command, Geometry, GeometryLineString, GeometryPoint, GeometryPolygon, LineTo, MoveTo, - MultiPoint, Point, -}; -use crate::protos::vector_tile::{ - Tile as ProtoTile, Tile_Feature as ProtoFeature, Tile_GeomType, Tile_Layer as ProtoLayer, - Tile_Value as ProtoValue, -}; -use crate::tile::{Feature, Layer, PropertyValue, Tile}; - -pub trait Decode { - fn decode(self) -> T; -} - -/// Decode a PropertyValue -impl Decode for ProtoValue { - fn decode(mut self) -> PropertyValue { - if self.has_bool_value() { - PropertyValue::BoolValue(self.get_bool_value()) - } else if self.has_string_value() { - PropertyValue::StringValue(self.take_string_value()) - } else if self.has_float_value() { - PropertyValue::FloatValue(self.get_float_value()) - } else if self.has_int_value() { - PropertyValue::IntValue(self.get_int_value()) - } else if self.has_sint_value() { - PropertyValue::SIntValue(self.get_sint_value()) - } else if self.has_uint_value() { - PropertyValue::UIntValue(self.get_uint_value()) - } else if self.has_double_value() { - PropertyValue::DoubleValue(self.get_double_value()) - } else { - PropertyValue::Unknown - } - } -} - -/// Decode a list of PropertyValues -impl Decode> for Vec { - fn decode(self) -> Vec { - self.into_iter().map(|value| value.decode()).collect() - } -} - -const CMD_MOVE_TO: u32 = 1; -const CMD_LINE_TO: u32 = 2; -const CMD_CLOSE_PATH: u32 = 7; - -const CMD_MOVE_TO_PARAMETERS: usize = 2; -const CMD_LINE_TO_PARAMETERS: usize = 2; -const CMD_CLOSE_PATH_PARAMETERS: usize = 0; - -trait ZigZag { - /// Decodes a value from zigzag encoding - fn zagzig(self) -> i32; -} - -impl ZigZag for u32 { - fn zagzig(self) -> i32 { - ((self >> 1) as i32) ^ (-((self & 1) as i32)) - } -} - -impl Decode for Vec { - fn decode(self) -> GeometryPoint { - let mut points = vec![]; - let mut i = 0; - - while i < self.len() { - let command = self[i] & 0x7; - - if command != CMD_MOVE_TO { - // FIXME: Not allowed in Points - panic!("error") - } - - let count = self[i] >> 3; - i += 1; - - for _ in 0..count { - points.push(Point::new(self[i].zagzig(), self[i + 1].zagzig())); - - i += CMD_MOVE_TO_PARAMETERS; - } - } - - match points.len() { - 0 => GeometryPoint::Point(Point::new(0, 0)), - 1 => GeometryPoint::Point(points.remove(0)), - _ => GeometryPoint::MultiPoint(MultiPoint::new(points)), - } - } -} - -impl Decode for Vec { - fn decode(self) -> GeometryLineString { - let mut commands = Vec::with_capacity(self.len()); // Create vec of maximum size - let mut i = 0; - - while i < self.len() { - let command = self[i] & 0x7; - - let count = self[i] >> 3; - i += 1; - - match command { - CMD_MOVE_TO => { - for _ in 0..count { - commands.push(Command::MoveTo(MoveTo { - x: self[i].zagzig(), - y: self[i + 1].zagzig(), - })); - i += CMD_MOVE_TO_PARAMETERS; - } - } - CMD_LINE_TO => { - for _ in 0..count { - commands.push(Command::LineTo(LineTo { - x: self[i].zagzig(), - y: self[i + 1].zagzig(), - })); - i += CMD_LINE_TO_PARAMETERS; - } - } - CMD_CLOSE_PATH => { - // FIXME: Not allowed in LineStrings - panic!("error") - } - _ => { - panic!("error") - } - } - } - - GeometryLineString { commands } - } -} - -impl Decode for Vec { - fn decode(self) -> GeometryPolygon { - let mut commands = vec![]; - let mut i = 0; - - while i < self.len() { - let command = self[i] & 0x7; - let count = self[i] >> 3; - - // parsed command and count => +1 - i += 1; - - match command { - CMD_MOVE_TO => { - for _ in 0..count { - commands.push(Command::MoveTo(MoveTo { - x: self[i].zagzig(), - y: self[i + 1].zagzig(), - })); - i += CMD_MOVE_TO_PARAMETERS; - } - } - CMD_LINE_TO => { - for _ in 0..count { - commands.push(Command::LineTo(LineTo { - x: self[i].zagzig(), - y: self[i + 1].zagzig(), - })); - i += CMD_LINE_TO_PARAMETERS; - } - } - CMD_CLOSE_PATH => { - if count != 1 { - panic!("error") - } - commands.push(Command::Close); - i += CMD_CLOSE_PATH_PARAMETERS; - } - _ => { - panic!("error") - } - } - } - - GeometryPolygon { commands } - } -} - -/// Decode a Geometry -impl Decode for ProtoFeature { - fn decode(self) -> Geometry { - match &self.get_field_type() { - Tile_GeomType::UNKNOWN => Geometry::Unknown, - Tile_GeomType::POINT => Geometry::GeometryPoint(self.geometry.decode()), - Tile_GeomType::LINESTRING => Geometry::GeometryLineString(self.geometry.decode()), - Tile_GeomType::POLYGON => Geometry::GeometryPolygon(self.geometry.decode()), - } - } -} - -/// Decode a Feature -// FIXME: Decoding is very slow right now on development builds of wasm: (Development: 15s, Production: 60ms) -impl Decode for (&mut ProtoLayer, ProtoFeature) { - fn decode(self) -> Feature { - let (layer, feature) = self; - - let mut properties = HashMap::with_capacity(feature.tags.len()); - - let keys = &mut layer.keys; - - for chunk in feature.tags.chunks(2) { - let key = chunk[0]; - let value = chunk[1]; - - if let Some(actual_key) = keys.get(key as usize) { - let values = &layer.values; - if let Some(actual_value) = values.get(value as usize) { - properties.insert(actual_key.clone(), actual_value.clone().decode()); - } - } - } - - let id = feature.get_id(); - let geometry = feature.decode(); - - Feature::new(id, geometry, properties) - } -} - -/// Decode a Layer -impl Decode for ProtoLayer { - fn decode(mut self) -> Layer { - let mut features = Vec::new(); - - while let Some(feature) = self.features.pop() { - features.insert(0, (&mut self, feature).decode()) - } - - Layer::new( - self.take_name(), - self.get_version(), - features, - self.get_extent(), - ) - } -} - -/// Decode a whole Tile -impl Decode for ProtoTile { - fn decode(mut self) -> Tile { - let mut layers = Vec::new(); - - while let Some(layer) = self.layers.pop() { - layers.insert(0, layer.decode()) - } - - Tile::new(layers) - } -} diff --git a/libs/vector_tile/src/error.rs b/libs/vector_tile/src/error.rs deleted file mode 100644 index 2087a8d8..00000000 --- a/libs/vector_tile/src/error.rs +++ /dev/null @@ -1,21 +0,0 @@ -use protobuf::ProtobufError; -use std::io; - -#[derive(Debug)] -pub enum Error { - Generic(String), - Protobuf(ProtobufError), - IO(io::Error), -} - -impl From for Error { - fn from(err: ProtobufError) -> Self { - Error::Protobuf(err) - } -} - -impl From for Error { - fn from(err: io::Error) -> Self { - Error::IO(err) - } -} diff --git a/libs/vector_tile/src/geometry.rs b/libs/vector_tile/src/geometry.rs deleted file mode 100644 index 9d972407..00000000 --- a/libs/vector_tile/src/geometry.rs +++ /dev/null @@ -1,68 +0,0 @@ -#[derive(Debug, Clone)] -pub enum GeometryPoint { - Point(Point), - MultiPoint(MultiPoint), - Unknown, -} - -#[derive(Debug, Clone)] -pub struct MultiPoint { - points: Vec, -} - -#[derive(Debug, Clone)] -pub struct Point { - x: i32, - y: i32, -} - -/// Contains relative coordinates to which the cursor is moved -#[derive(Debug, Clone)] -pub struct MoveTo { - pub x: i32, - pub y: i32, -} - -/// Contains relative coordinates to which a line is drawn -#[derive(Debug, Clone)] -pub struct LineTo { - pub x: i32, - pub y: i32, -} - -#[derive(Debug, Clone)] -pub enum Command { - MoveTo(MoveTo), - LineTo(LineTo), - Close, -} - -#[derive(Debug, Clone)] -pub struct GeometryLineString { - pub commands: Vec, -} - -#[derive(Debug, Clone)] -pub struct GeometryPolygon { - pub commands: Vec, -} - -#[derive(Debug, Clone)] -pub enum Geometry { - GeometryPoint(GeometryPoint), - GeometryLineString(GeometryLineString), - GeometryPolygon(GeometryPolygon), - Unknown, -} - -impl Point { - pub(crate) fn new(x: i32, y: i32) -> Self { - Self { x, y } - } -} - -impl MultiPoint { - pub(crate) fn new(points: Vec) -> Self { - Self { points } - } -} diff --git a/libs/vector_tile/src/lib.rs b/libs/vector_tile/src/lib.rs deleted file mode 100644 index 1ec59064..00000000 --- a/libs/vector_tile/src/lib.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::fs::File; -use std::io::{BufRead, BufReader}; -use std::path::Path; - -use protobuf::Message; - -use crate::encoding::Decode; -use crate::error::Error; -use crate::protos::vector_tile::Tile as TileProto; -use crate::tile::Tile; - -mod encoding; -mod protos; - -#[cfg(test)] -mod tests; - -pub mod error; -pub mod geometry; -pub mod grid; -pub mod tile; - -pub fn parse_tile>(path: P) -> Result { - let f = File::open(path)?; - let mut reader = BufReader::new(f); - parse_tile_reader(&mut reader) -} - -pub fn parse_tile_reader(reader: &mut B) -> Result { - let proto_tile = TileProto::parse_from_reader(reader)?; - Ok(proto_tile.decode()) -} - -pub fn parse_tile_bytes(bytes: &[u8]) -> Result { - let proto_tile = TileProto::parse_from_bytes(bytes)?; - Ok(proto_tile.decode()) -} diff --git a/libs/vector_tile/src/protos/.gitignore b/libs/vector_tile/src/protos/.gitignore deleted file mode 100644 index 1efd6264..00000000 --- a/libs/vector_tile/src/protos/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.rs -!mod.rs \ No newline at end of file diff --git a/libs/vector_tile/src/protos/mod.rs b/libs/vector_tile/src/protos/mod.rs deleted file mode 100644 index 8851aed1..00000000 --- a/libs/vector_tile/src/protos/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -#[path = "vector_tile.rs"] -#[rustfmt::skip] // Skip because it does not exist without building -pub mod vector_tile; diff --git a/libs/vector_tile/src/tests.rs b/libs/vector_tile/src/tests.rs deleted file mode 100644 index e6a71b8e..00000000 --- a/libs/vector_tile/src/tests.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::fs::File; -use std::io::{BufReader, Cursor}; - -use protobuf::Message; - -use crate::encoding::Decode; -use crate::grid::{google_mercator, tile_coordinates_bavaria}; -use crate::protos::vector_tile::Tile; -use crate::{parse_tile, parse_tile_reader}; - -#[test] -fn test_parsing_europe_pbf() { - parse_tile("libs/vector_tile/test_data/europe.pbf"); -} - -#[test] -fn test_tile_coordinates_bavaria() { - println!("{:?}", tile_coordinates_bavaria(&google_mercator(), 6)); -} - -#[test] -fn test_empty_fail() { - assert!(parse_tile_reader(&mut Cursor::new(&[])).is_err()) -} diff --git a/libs/vector_tile/src/tile.rs b/libs/vector_tile/src/tile.rs deleted file mode 100644 index f1dcbee1..00000000 --- a/libs/vector_tile/src/tile.rs +++ /dev/null @@ -1,96 +0,0 @@ -use crate::geometry::Geometry; -use std::collections::HashMap; - -#[derive(Debug, Clone)] -pub struct Tile { - layers: Vec, -} - -#[derive(Debug, Clone)] -pub struct Layer { - name: String, - version: u32, - features: Vec, - extent: u32, -} - -#[derive(Debug, Clone)] -pub struct Feature { - id: u64, - geometry: Geometry, - properties: HashMap, -} - -#[derive(Debug, Clone)] -pub enum PropertyValue { - StringValue(String), - FloatValue(f32), - DoubleValue(f64), - IntValue(i64), - UIntValue(u64), - SIntValue(i64), - BoolValue(bool), - Unknown, -} - -impl Feature { - pub(crate) fn new( - id: u64, - geometry: Geometry, - properties: HashMap, - ) -> Self { - Feature { - id, - geometry, - properties, - } - } - - pub fn id(&self) -> u64 { - self.id - } - - pub fn geometry(&self) -> &Geometry { - &self.geometry - } - pub fn properties(&self) -> &HashMap { - &self.properties - } -} - -impl Layer { - pub(crate) fn new(name: String, version: u32, features: Vec, extent: u32) -> Self { - Layer { - name, - version, - features, - extent, - } - } - - pub fn extent(&self) -> u32 { - self.extent - } - - pub fn version(&self) -> u32 { - self.version - } - - pub fn name(&self) -> &str { - self.name.as_str() - } - - pub fn features(&self) -> &Vec { - &self.features - } -} - -impl Tile { - pub(crate) fn new(layers: Vec) -> Self { - Tile { layers } - } - - pub fn layers(&self) -> &Vec { - &self.layers - } -} diff --git a/libs/vector_tile/test_data/europe.pbf b/libs/vector_tile/test_data/europe.pbf deleted file mode 100644 index bd48bf59..00000000 Binary files a/libs/vector_tile/test_data/europe.pbf and /dev/null differ diff --git a/src/tessellation/layer.rs b/src/tessellation/layer.rs deleted file mode 100644 index ae1c951f..00000000 --- a/src/tessellation/layer.rs +++ /dev/null @@ -1,106 +0,0 @@ -use std::ops::Add; - -use bytemuck::Pod; -use lyon::geom::point; - -use lyon::lyon_tessellation::VertexBuffers; -use lyon::path::{FillRule, Path}; -use lyon::tessellation::geometry_builder::MaxIndex; -use lyon::tessellation::{ - BuffersBuilder, FillOptions, FillTessellator, StrokeOptions, StrokeTessellator, -}; - -use crate::error::Error; - -use crate::render::ShaderVertex; -use crate::tessellation::{Tessellated, VertexConstructor, DEFAULT_TOLERANCE}; - -impl + MaxIndex + Pod> Tessellated for Layer { - #[tracing::instrument(skip_all)] - fn tessellate(&self) -> Result<(VertexBuffers, Vec), Error> { - let mut buffer: VertexBuffers = VertexBuffers::new(); - let mut feature_indices: Vec = Vec::new(); - let mut current_index = 0; - - for feature in self.features() { - match feature.geometry() { - Geometry::GeometryPolygon(polygon) => { - let mut polygon_builder = Path::builder(); - let mut cursor = point(0.0, 0.0); - for command in &polygon.commands { - match command { - Command::MoveTo(cmd) => { - let delta = lyon::path::math::vector(cmd.x as f32, cmd.y as f32); - cursor += delta; - polygon_builder.begin(cursor); - } - Command::LineTo(cmd) => { - let delta = lyon::path::math::vector(cmd.x as f32, cmd.y as f32); - cursor += delta; - polygon_builder.line_to(cursor); - } - Command::Close => { - polygon_builder.close(); - } - }; - } - - let mut fill_tessellator = FillTessellator::new(); - fill_tessellator.tessellate_path( - &polygon_builder.build(), - &FillOptions::tolerance(DEFAULT_TOLERANCE) - .with_fill_rule(FillRule::NonZero), - &mut BuffersBuilder::new(&mut buffer, VertexConstructor {}), - )?; - } - Geometry::GeometryLineString(line_string) => { - let mut line_string_builder = Path::builder(); - let mut cursor = point(0.0, 0.0); - let mut subpath_open = false; - for command in &line_string.commands { - match command { - Command::MoveTo(cmd) => { - if subpath_open { - line_string_builder.end(false); - } - - let delta = lyon::path::math::vector(cmd.x as f32, cmd.y as f32); - cursor += delta; - line_string_builder.begin(cursor); - subpath_open = true; - } - Command::LineTo(cmd) => { - let delta = lyon::path::math::vector(cmd.x as f32, cmd.y as f32); - cursor += delta; - line_string_builder.line_to(cursor); - } - Command::Close => { - panic!("error") - } - }; - } - - if subpath_open { - line_string_builder.end(false); - } - - let mut stroke_tessellator = StrokeTessellator::new(); - - stroke_tessellator.tessellate_path( - &line_string_builder.build(), - &StrokeOptions::tolerance(DEFAULT_TOLERANCE), - &mut BuffersBuilder::new(&mut buffer, VertexConstructor {}), - )?; - } - _ => {} - }; - - let next_index = buffer.indices.len(); - let indices = (next_index - current_index) as u32; - feature_indices.push(indices); - current_index = next_index; - } - - Ok((buffer, feature_indices)) - } -} diff --git a/libs/vector_tile/src/grid.rs b/src/util/grid.rs similarity index 100% rename from libs/vector_tile/src/grid.rs rename to src/util/grid.rs diff --git a/src/util/mod.rs b/src/util/mod.rs index 1f1f2243..8a757f63 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,6 +1,7 @@ //! Utils which are used internally mod fps_meter; +pub mod grid; pub mod math; use crate::coords::WorldTileCoords;