open_vector_tile/
geometry.rs

1use alloc::vec::Vec;
2use core::cmp::Ordering;
3use s2json::{LineStringMValues, MValue};
4
5/// Open Vector Spec can be an x,y but also may contain an MValue if the
6/// geometry is a line or polygon
7#[derive(Debug, Clone, PartialEq)]
8pub struct Point {
9    /// x value
10    pub x: i32,
11    /// y value
12    pub y: i32,
13    /// M value
14    pub m: Option<MValue>,
15}
16impl Point {
17    /// Create a new point
18    pub fn new(x: i32, y: i32) -> Point {
19        Point { x, y, m: None }
20    }
21
22    /// Create a new point with an MValue
23    pub fn new_with_m(x: i32, y: i32, m: MValue) -> Point {
24        Point { x, y, m: Some(m) }
25    }
26}
27impl PartialOrd for Point {
28    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
29        // only compare x and y
30        Some(core::cmp::Ord::cmp(self, other))
31    }
32}
33impl Eq for Point {}
34impl Ord for Point {
35    fn cmp(&self, other: &Self) -> Ordering {
36        // only compare x and y
37        self.x.cmp(&other.x).then(self.y.cmp(&other.y))
38    }
39}
40/// Open Vector Spec can be an x,y,z but also may contain an MValue
41/// if the geometry is a line or polygon
42#[derive(Debug, Clone, PartialEq)]
43pub struct Point3D {
44    /// x value
45    pub x: i32,
46    /// y value
47    pub y: i32,
48    /// z value
49    pub z: i32,
50    /// M value
51    pub m: Option<MValue>,
52}
53impl Point3D {
54    /// Create a new point
55    pub fn new(x: i32, y: i32, z: i32) -> Point3D {
56        Point3D { x, y, z, m: None }
57    }
58
59    /// Create a new point with an MValue
60    pub fn new_with_m(x: i32, y: i32, z: i32, m: MValue) -> Point3D {
61        Point3D { x, y, z, m: Some(m) }
62    }
63}
64impl PartialOrd for Point3D {
65    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
66        // only compare x and y
67        Some(core::cmp::Ord::cmp(self, other))
68    }
69}
70impl Eq for Point3D {}
71impl Ord for Point3D {
72    fn cmp(&self, other: &Self) -> Ordering {
73        // only compare x and y
74        self.x.cmp(&other.x).then(self.y.cmp(&other.y)).then(self.z.cmp(&other.z))
75    }
76}
77
78/// Built array line data with associated offset to help render dashed lines across tiles.
79#[derive(Debug, Clone, PartialEq)]
80pub struct VectorLineWithOffset {
81    /// the offset of the line to start processing the dash position
82    pub offset: f64,
83    /// the line data
84    pub geometry: VectorLine,
85}
86impl From<&[Point]> for VectorLineWithOffset {
87    fn from(p: &[Point]) -> Self {
88        Self { offset: 0.0, geometry: p.to_vec() }
89    }
90}
91impl VectorLineWithOffset {
92    /// Create a new VectorLineWithOffset
93    pub fn new(offset: f64, geometry: VectorLine) -> Self {
94        Self { offset, geometry }
95    }
96
97    /// check if the line has an offset. 0.0 is considered no offset
98    pub fn has_offset(&self) -> bool {
99        self.offset != 0.0
100    }
101
102    /// check if the line has M values
103    pub fn has_m_values(&self) -> bool {
104        self.geometry.iter().any(|p| p.m.is_some())
105    }
106
107    /// Get the M values for the line
108    pub fn m_values(&self) -> Option<LineStringMValues> {
109        if !self.has_m_values() {
110            return None;
111        }
112        Some(self.geometry.iter().map(|p| p.m.clone().unwrap_or_default()).collect())
113    }
114}
115/// Built array line data with associated offset to help render dashed lines across tiles.
116pub type VectorLinesWithOffset = Vec<VectorLineWithOffset>;
117
118/// Built array line data with associated offset to help render dashed lines across tiles.
119#[derive(Debug, Clone, PartialEq)]
120pub struct VectorLine3DWithOffset {
121    /// the offset of the line to start processing the dash position
122    pub offset: f64,
123    /// the line data
124    pub geometry: VectorLine3D,
125}
126impl VectorLine3DWithOffset {
127    /// Create a new VectorLine3DWithOffset
128    pub fn new(offset: f64, geometry: VectorLine3D) -> Self {
129        Self { offset, geometry }
130    }
131
132    /// check if the line has an offset. 0.0 is considered no offset
133    pub fn has_offset(&self) -> bool {
134        self.offset != 0.0
135    }
136
137    /// check if the line has M values
138    pub fn has_m_values(&self) -> bool {
139        self.geometry.iter().any(|p| p.m.is_some())
140    }
141
142    /// Get the M values for the line
143    pub fn m_values(&self) -> Option<LineStringMValues> {
144        if !self.has_m_values() {
145            return None;
146        }
147        Some(self.geometry.iter().map(|p| p.m.clone().unwrap_or_default()).collect())
148    }
149}
150/// Built array line data with associated offset to help render dashed lines across tiles.
151pub type VectorLines3DWithOffset = Vec<VectorLine3DWithOffset>;
152
153/// A set of points
154pub type VectorPoints = Vec<Point>;
155/// A set of 3D points
156pub type VectorPoints3D = Vec<Point3D>;
157/// A set of points
158pub type VectorLine = Vec<Point>;
159/// A set of 3D points
160pub type VectorLine3D = Vec<Point3D>;
161/// A set of lines
162pub type VectorLines = Vec<VectorLine>;
163/// A set of 3D lines
164pub type VectorLines3D = Vec<VectorLine3D>;
165/// A set of polygons
166pub type VectorPoly = Vec<VectorLine>;
167/// A set of 3D polygons
168pub type VectorPoly3D = Vec<VectorLine3D>;
169/// A set of multiple polygons
170pub type VectorMultiPoly = Vec<VectorPoly>;
171/// A set of multiple 3D polygons
172pub type VectorMultiPoly3D = Vec<VectorPoly3D>;
173/// An enumeration of all the geometry types
174#[derive(Debug, Clone, PartialEq)]
175pub enum VectorGeometry {
176    /// points
177    VectorPoints(VectorPoints),
178    /// lines
179    VectorLines(VectorLinesWithOffset),
180    /// polygons
181    VectorPolys(Vec<VectorLinesWithOffset>),
182    /// 3D points
183    VectorPoints3D(VectorPoints3D),
184    /// 3D lines
185    VectorLines3D(VectorLines3DWithOffset),
186    /// 3D polygons
187    VectorPolys3D(Vec<VectorLines3DWithOffset>),
188}