gistools/geometry/wm/convert/
mod.rs1mod flat;
2mod s2;
3mod vector;
4
5use crate::geometry::ConvertVectorFeatureS2;
6use alloc::{vec, vec::Vec};
7pub use flat::*;
8pub use s2::*;
9use s2json::{
10 BBox3D, Feature, MValue, Properties, VectorFeature, VectorFeatureType, VectorGeometry,
11};
12pub use vector::*;
13
14pub trait ConvertFeature<
16 M: Clone = (),
17 P: Clone + Default = Properties,
18 D: Clone + Default = MValue,
19>
20{
21 fn to_vector(&self, build_bbox: Option<bool>) -> VectorFeature<M, P, D>;
23}
24
25impl<M: Clone, P: Clone + Default, D: Clone + Default> ConvertFeature<M, P, D>
26 for Feature<M, P, D>
27{
28 fn to_vector(&self, build_bbox: Option<bool>) -> VectorFeature<M, P, D> {
30 let build_bbox = build_bbox.unwrap_or(false);
31 let Feature { id, properties, metadata, geometry, .. } = self;
32 let vector_geo = convert_geometry_to_vector(geometry, build_bbox);
33 VectorFeature::new_wm(*id, properties.clone(), vector_geo, metadata.clone())
34 }
35}
36
37pub trait ConvertVectorFeatureWM<
39 M: Clone = (),
40 P: Clone + Default = Properties,
41 D: Clone + Default = MValue,
42>
43{
44 fn to_unit_scale(&mut self);
46 fn to_ll(&mut self);
48 fn to_s2(&self) -> Vec<VectorFeature<M, P, D>>;
50 fn to_feature(&self, build_bbox: bool) -> Feature<M, P, D>;
52}
53
54impl<M: Clone, P: Clone + Default, D: Clone + Default> ConvertVectorFeatureWM<M, P, D>
55 for VectorFeature<M, P, D>
56{
57 fn to_unit_scale(&mut self) {
59 let mut bbox = BBox3D::default();
60 match &mut self.geometry {
61 VectorGeometry::Point(geo) => {
62 geo.coordinates.project(Some(&mut bbox));
63 geo.vec_bbox = Some(bbox);
64 }
65 VectorGeometry::LineString(geo) | VectorGeometry::MultiPoint(geo) => {
66 geo.coordinates.iter_mut().for_each(|p| p.project(Some(&mut bbox)));
67 geo.vec_bbox = Some(bbox);
68 }
69 VectorGeometry::Polygon(geo) | VectorGeometry::MultiLineString(geo) => {
70 geo.coordinates
71 .iter_mut()
72 .for_each(|p| p.iter_mut().for_each(|p| p.project(Some(&mut bbox))));
73 geo.vec_bbox = Some(bbox);
74 }
75 VectorGeometry::MultiPolygon(geo) => {
76 geo.coordinates.iter_mut().for_each(|p| {
77 p.iter_mut().for_each(|p| p.iter_mut().for_each(|p| p.project(Some(&mut bbox))))
78 });
79 geo.vec_bbox = Some(bbox);
80 }
81 }
82 }
83
84 fn to_ll(&mut self) {
86 match &mut self.geometry {
87 VectorGeometry::Point(geo) => {
88 geo.coordinates.unproject();
89 }
90 VectorGeometry::LineString(geo) | VectorGeometry::MultiPoint(geo) => {
91 geo.coordinates.iter_mut().for_each(|p| p.unproject());
92 }
93 VectorGeometry::Polygon(geo) | VectorGeometry::MultiLineString(geo) => {
94 geo.coordinates.iter_mut().for_each(|p| p.iter_mut().for_each(|p| p.unproject()));
95 }
96 VectorGeometry::MultiPolygon(geo) => {
97 geo.coordinates.iter_mut().for_each(|p| {
98 p.iter_mut().for_each(|p| p.iter_mut().for_each(|p| p.unproject()))
99 });
100 }
101 }
102 }
103
104 fn to_s2(&self) -> Vec<VectorFeature<M, P, D>> {
106 let VectorFeature { _type, id, properties, metadata, geometry, .. } = self;
107 let mut res: Vec<VectorFeature<M, P, D>> = vec![];
108
109 if *_type == VectorFeatureType::S2Feature {
110 res.push(self.clone());
111 } else {
112 let vector_geo = convert_geometry_wm_to_s2(geometry);
113 for ConvertedGeometry { geometry, face } in vector_geo {
114 res.push(VectorFeature::<M, P, D>::new_s2(
115 *id,
116 face,
117 properties.clone(),
118 geometry,
119 metadata.clone(),
120 ));
121 }
122 }
123
124 res
125 }
126
127 fn to_feature(&self, build_bbox: bool) -> Feature<M, P, D> {
129 if self._type == VectorFeatureType::S2Feature {
130 let VectorFeature { id, properties, metadata, geometry, .. } = &self.to_wm();
131 let geo = convert_vector_to_geometry(geometry, build_bbox);
132 Feature::new(*id, properties.clone(), geo, metadata.clone())
133 } else {
134 let VectorFeature { id, properties, metadata, geometry, .. } = self;
135 let geo = convert_vector_to_geometry(geometry, build_bbox);
136 Feature::new(*id, properties.clone(), geo, metadata.clone())
137 }
138 }
139}