Remove custom vector_tile library because we use geozero now

This commit is contained in:
Maximilian Ammann 2022-04-18 20:17:00 +02:00
parent ff642df404
commit a2f879ba14
17 changed files with 4 additions and 690 deletions

36
Cargo.lock generated
View File

@ -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"

View File

@ -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 = [] }

View File

@ -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"

View File

@ -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.");
}

@ -1 +0,0 @@
Subproject commit c8d178da65cce0ea474e3d99e3368970ce217093

View File

@ -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<T> {
fn decode(self) -> T;
}
/// Decode a PropertyValue
impl Decode<PropertyValue> 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<Vec<PropertyValue>> for Vec<ProtoValue> {
fn decode(self) -> Vec<PropertyValue> {
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<GeometryPoint> for Vec<u32> {
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<GeometryLineString> for Vec<u32> {
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<GeometryPolygon> for Vec<u32> {
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<Geometry> 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<Feature> 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<Layer> 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<Tile> 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)
}
}

View File

@ -1,21 +0,0 @@
use protobuf::ProtobufError;
use std::io;
#[derive(Debug)]
pub enum Error {
Generic(String),
Protobuf(ProtobufError),
IO(io::Error),
}
impl From<ProtobufError> for Error {
fn from(err: ProtobufError) -> Self {
Error::Protobuf(err)
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
Error::IO(err)
}
}

View File

@ -1,68 +0,0 @@
#[derive(Debug, Clone)]
pub enum GeometryPoint {
Point(Point),
MultiPoint(MultiPoint),
Unknown,
}
#[derive(Debug, Clone)]
pub struct MultiPoint {
points: Vec<Point>,
}
#[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<Command>,
}
#[derive(Debug, Clone)]
pub struct GeometryPolygon {
pub commands: Vec<Command>,
}
#[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<Point>) -> Self {
Self { points }
}
}

View File

@ -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<P: AsRef<Path>>(path: P) -> Result<Tile, Error> {
let f = File::open(path)?;
let mut reader = BufReader::new(f);
parse_tile_reader(&mut reader)
}
pub fn parse_tile_reader<B: BufRead>(reader: &mut B) -> Result<Tile, Error> {
let proto_tile = TileProto::parse_from_reader(reader)?;
Ok(proto_tile.decode())
}
pub fn parse_tile_bytes(bytes: &[u8]) -> Result<Tile, Error> {
let proto_tile = TileProto::parse_from_bytes(bytes)?;
Ok(proto_tile.decode())
}

View File

@ -1,2 +0,0 @@
*.rs
!mod.rs

View File

@ -1,3 +0,0 @@
#[path = "vector_tile.rs"]
#[rustfmt::skip] // Skip because it does not exist without building
pub mod vector_tile;

View File

@ -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())
}

View File

@ -1,96 +0,0 @@
use crate::geometry::Geometry;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct Tile {
layers: Vec<Layer>,
}
#[derive(Debug, Clone)]
pub struct Layer {
name: String,
version: u32,
features: Vec<Feature>,
extent: u32,
}
#[derive(Debug, Clone)]
pub struct Feature {
id: u64,
geometry: Geometry,
properties: HashMap<String, PropertyValue>,
}
#[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<String, PropertyValue>,
) -> Self {
Feature {
id,
geometry,
properties,
}
}
pub fn id(&self) -> u64 {
self.id
}
pub fn geometry(&self) -> &Geometry {
&self.geometry
}
pub fn properties(&self) -> &HashMap<String, PropertyValue> {
&self.properties
}
}
impl Layer {
pub(crate) fn new(name: String, version: u32, features: Vec<Feature>, 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<Feature> {
&self.features
}
}
impl Tile {
pub(crate) fn new(layers: Vec<Layer>) -> Self {
Tile { layers }
}
pub fn layers(&self) -> &Vec<Layer> {
&self.layers
}
}

View File

@ -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<I: Add + From<lyon::lyon_tessellation::VertexId> + MaxIndex + Pod> Tessellated<I> for Layer {
#[tracing::instrument(skip_all)]
fn tessellate(&self) -> Result<(VertexBuffers<ShaderVertex, I>, Vec<u32>), Error> {
let mut buffer: VertexBuffers<ShaderVertex, I> = VertexBuffers::new();
let mut feature_indices: Vec<u32> = 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))
}
}

View File

@ -1,6 +1,7 @@
//! Utils which are used internally
mod fps_meter;
pub mod grid;
pub mod math;
use crate::coords::WorldTileCoords;