geoarrow_array/geozero/export/scalar/
point.rs

1use geo_traits::{CoordTrait, PointTrait};
2use geozero::{GeomProcessor, GeozeroGeometry};
3
4use crate::scalar::Point;
5
6/// Process a [PointTrait] through a [GeomProcessor].
7pub(crate) fn process_point<P: GeomProcessor>(
8    geom: &impl PointTrait<T = f64>,
9    geom_idx: usize,
10    processor: &mut P,
11) -> geozero::error::Result<()> {
12    processor.point_begin(geom_idx)?;
13    process_point_as_coord(geom, 0, processor)?;
14    processor.point_end(geom_idx)?;
15    Ok(())
16}
17
18/// Note that this does _not_ call `processor.point_begin` and `processor.point_end` because as of
19/// geozero v0.12, `point_begin` and `point_end` are **not** called for each point in a
20/// MultiPoint
21/// <https://github.com/georust/geozero/pull/183/files#diff-a583e23825ff28368eabfdbfdc362c6512e42097024d548fb18d88409feba76aR142-R143>
22pub(crate) fn process_point_as_coord<P: GeomProcessor>(
23    geom: &impl PointTrait<T = f64>,
24    coord_idx: usize,
25    processor: &mut P,
26) -> geozero::error::Result<()> {
27    use geo_traits::Dimensions;
28
29    if let Some(coord) = geom.coord() {
30        match coord.dim() {
31            Dimensions::Xy | Dimensions::Unknown(2) => {
32                processor.xy(coord.x(), coord.y(), coord_idx)?
33            }
34            Dimensions::Xyz | Dimensions::Unknown(3) => processor.coordinate(
35                coord.x(),
36                coord.y(),
37                Some(unsafe { coord.nth_unchecked(2) }),
38                None,
39                None,
40                None,
41                coord_idx,
42            )?,
43            Dimensions::Xym => processor.coordinate(
44                coord.x(),
45                coord.y(),
46                None,
47                Some(unsafe { coord.nth_unchecked(2) }),
48                None,
49                None,
50                coord_idx,
51            )?,
52            Dimensions::Xyzm | Dimensions::Unknown(4) => processor.coordinate(
53                coord.x(),
54                coord.y(),
55                Some(unsafe { coord.nth_unchecked(2) }),
56                Some(unsafe { coord.nth_unchecked(3) }),
57                None,
58                None,
59                coord_idx,
60            )?,
61            d => {
62                return Err(geozero::error::GeozeroError::Geometry(format!(
63                    "Unexpected dimension {d:?}",
64                )));
65            }
66        };
67    } else {
68        processor.empty_point(coord_idx)?;
69    }
70
71    Ok(())
72}
73
74impl GeozeroGeometry for Point<'_> {
75    fn process_geom<P: GeomProcessor>(&self, processor: &mut P) -> geozero::error::Result<()>
76    where
77        Self: Sized,
78    {
79        process_point(self, 0, processor)
80    }
81}