gistools/geometry/wm/convert/
vector.rs1use alloc::{vec, vec::Vec};
2use s2json::{
3 BBox3D, BaseGeometry, Geometry, LineStringMValues, MultiLineStringMValues, MultiPolygonMValues,
4 PointOrPoint3D, VectorGeometry, VectorPoint,
5};
6
7pub fn convert_geometry_to_vector<M: Clone + Default>(
11 geometry: &Geometry<M>,
12 build_bbox: bool,
13) -> VectorGeometry<M> {
14 let mut bbox = if build_bbox { Some(BBox3D::default()) } else { None };
15 match geometry {
16 Geometry::Point(geo) => {
17 let coords = to_vector_point(geo, &mut bbox);
18 VectorGeometry::new_point(coords, bbox)
19 }
20 Geometry::Point3D(geo) => {
21 let coords = to_vector_point(geo, &mut bbox);
22 VectorGeometry::new_point(coords, bbox)
23 }
24 Geometry::MultiPoint(geo) => {
25 let coords = to_vector_multipoint(geo, &mut bbox);
26 VectorGeometry::new_multipoint(coords, bbox)
27 }
28 Geometry::MultiPoint3D(geo) => {
29 let coords = to_vector_multipoint(geo, &mut bbox);
30 VectorGeometry::new_multipoint(coords, bbox)
31 }
32 Geometry::LineString(geo) => {
33 let coords = to_vector_multipoint(geo, &mut bbox);
34 VectorGeometry::new_linestring(coords, bbox)
35 }
36 Geometry::LineString3D(geo) => {
37 let coords = to_vector_multipoint(geo, &mut bbox);
38 VectorGeometry::new_linestring(coords, bbox)
39 }
40 Geometry::MultiLineString(geo) => {
41 let coords = to_vector_multilinestring(geo, &mut bbox);
42 VectorGeometry::new_multilinestring(coords, bbox)
43 }
44 Geometry::MultiLineString3D(geo) => {
45 let coords = to_vector_multilinestring(geo, &mut bbox);
46 VectorGeometry::new_multilinestring(coords, bbox)
47 }
48 Geometry::Polygon(geo) => {
49 let coords = to_vector_multilinestring(geo, &mut bbox);
50 VectorGeometry::new_polygon(coords, bbox)
51 }
52 Geometry::Polygon3D(geo) => {
53 let coords = to_vector_multilinestring(geo, &mut bbox);
54 VectorGeometry::new_polygon(coords, bbox)
55 }
56 Geometry::MultiPolygon(geo) => {
57 let coords = to_vector_multipolygon(geo, &mut bbox);
58 VectorGeometry::new_multipolygon(coords, bbox)
59 }
60 Geometry::MultiPolygon3D(geo) => {
61 let coords = to_vector_multipolygon(geo, &mut bbox);
62 VectorGeometry::new_multipolygon(coords, bbox)
63 }
64 }
65}
66
67fn convert_point<M: Clone + Default>(
68 point: PointOrPoint3D,
69 m: Option<M>,
70 bbox: &mut Option<BBox3D>,
71) -> VectorPoint<M> {
72 let new_point = VectorPoint::new(point.0, point.1, point.2, m);
73 if let Some(b) = bbox {
74 b.extend_from_point(&new_point);
75 }
76 new_point
77}
78
79fn to_vector_point<M: Clone + Default, G: Copy, B>(
80 geo: &BaseGeometry<M, G, B>,
81 bbox: &mut Option<BBox3D>,
82) -> VectorPoint<M>
83where
84 PointOrPoint3D: core::convert::From<G>,
85{
86 convert_point(geo.coordinates.into(), geo.m_values.clone(), bbox)
87}
88
89fn to_vector_multipoint<M: Clone + Default, G: Copy, B>(
90 geo: &BaseGeometry<LineStringMValues<M>, Vec<G>, B>,
91 bbox: &mut Option<BBox3D>,
92) -> Vec<VectorPoint<M>>
93where
94 PointOrPoint3D: core::convert::From<G>,
95{
96 let binding = vec![];
97 let m_values = geo.m_values.as_ref().unwrap_or(&binding);
98 geo.coordinates
99 .iter()
100 .enumerate()
101 .map(|(i, p)| convert_point((*p).into(), m_values.get(i).cloned(), bbox))
102 .collect()
103}
104
105fn to_vector_multilinestring<M: Clone + Default, G: Copy, B>(
106 geo: &BaseGeometry<MultiLineStringMValues<M>, Vec<Vec<G>>, B>,
107 bbox: &mut Option<BBox3D>,
108) -> Vec<Vec<VectorPoint<M>>>
109where
110 PointOrPoint3D: core::convert::From<G>,
111{
112 let binding = vec![];
113 let m_values = geo.m_values.as_ref().unwrap_or(&binding);
114 geo.coordinates
115 .iter()
116 .enumerate()
117 .map(|(i, line)| {
118 line.iter()
119 .enumerate()
120 .map(|(j, p)| {
121 let m_value = m_values.get(i).and_then(|m| m.get(j)).cloned();
122 convert_point((*p).into(), m_value, bbox)
123 })
124 .collect()
125 })
126 .collect()
127}
128
129fn to_vector_multipolygon<M: Clone + Default, G: Copy, B>(
130 geo: &BaseGeometry<MultiPolygonMValues<M>, Vec<Vec<Vec<G>>>, B>,
131 bbox: &mut Option<BBox3D>,
132) -> Vec<Vec<Vec<VectorPoint<M>>>>
133where
134 PointOrPoint3D: core::convert::From<G>,
135{
136 let binding = vec![];
137 let m_values = geo.m_values.as_ref().unwrap_or(&binding);
138 geo.coordinates
139 .iter()
140 .enumerate()
141 .map(|(i, polygon)| {
142 polygon
143 .iter()
144 .enumerate()
145 .map(|(j, line)| {
146 line.iter()
147 .enumerate()
148 .map(|(k, p)| {
149 let m_value = m_values
150 .get(i)
151 .and_then(|m| m.get(j))
152 .and_then(|m| m.get(k))
153 .cloned();
154 convert_point((*p).into(), m_value, bbox)
155 })
156 .collect()
157 })
158 .collect()
159 })
160 .collect()
161}