gistools/geometry/s2/
convert.rs

1use crate::{Face, LonLat, S2CellId, VectorFeature, VectorGeometry, VectorPoint};
2
3impl<M: Clone> VectorFeature<M> {
4    /// Convert an S2 Feature to a GeoJSON Vector Feature
5    pub fn to_wm(&self) -> Self {
6        if self._type == "VectorFeature" {
7            return self.clone();
8        }
9        let mut geometry = self.geometry.clone();
10        convert_geometry(self.face, &mut geometry);
11        VectorFeature::<M>::new_wm(
12            self.id,
13            self.properties.clone(),
14            geometry,
15            self.metadata.clone(),
16        )
17    }
18}
19
20/// Underlying conversion mechanic to move S2Geometry to GeoJSON Geometry
21fn convert_geometry(face: Face, geometry: &mut VectorGeometry) {
22    match geometry {
23        VectorGeometry::Point(point) => convert_geometry_point(face, &mut point.coordinates),
24        VectorGeometry::LineString(points) | VectorGeometry::MultiPoint(points) => {
25            points.coordinates.iter_mut().for_each(|point| convert_geometry_point(face, point))
26        }
27        VectorGeometry::Polygon(lines) | VectorGeometry::MultiLineString(lines) => lines
28            .coordinates
29            .iter_mut()
30            .for_each(|line| line.iter_mut().for_each(|point| convert_geometry_point(face, point))),
31        VectorGeometry::MultiPolygon(polygons) => {
32            polygons.coordinates.iter_mut().for_each(|polygon| {
33                polygon.iter_mut().for_each(|line| {
34                    line.iter_mut().for_each(|point| convert_geometry_point(face, point))
35                })
36            })
37        }
38    }
39}
40
41/// Mutate an S2 Point to a GeoJSON Point
42fn convert_geometry_point(face: Face, point: &mut VectorPoint) {
43    let LonLat { lon, lat } = (&S2CellId::from_face_st(face.into(), point.x, point.y)).into();
44    point.x = lon;
45    point.y = lat;
46}