geoarrow_array/geozero/import/
point.rs1use geoarrow_schema::PointType;
2use geozero::{GeomProcessor, GeozeroGeometry};
3
4use crate::array::PointArray;
5use crate::builder::PointBuilder;
6use crate::geozero::import::util::{from_xy, from_xyzm};
7
8pub trait ToPointArray {
10 fn to_point_array(&self, typ: PointType) -> geozero::error::Result<PointArray> {
12 Ok(self.to_point_builder(typ)?.finish())
13 }
14
15 fn to_point_builder(&self, typ: PointType) -> geozero::error::Result<PointBuilder>;
17}
18
19impl<T: GeozeroGeometry> ToPointArray for T {
20 fn to_point_builder(&self, typ: PointType) -> geozero::error::Result<PointBuilder> {
21 let mut mutable_point_array = PointBuilder::new(typ);
22 self.process_geom(&mut mutable_point_array)?;
23 Ok(mutable_point_array)
24 }
25}
26
27#[allow(unused_variables)]
28impl GeomProcessor for PointBuilder {
29 fn empty_point(&mut self, idx: usize) -> geozero::error::Result<()> {
30 self.push_empty();
31 Ok(())
32 }
33
34 fn xy(&mut self, x: f64, y: f64, _idx: usize) -> geozero::error::Result<()> {
35 self.push_coord(from_xy(x, y).as_ref());
36 Ok(())
37 }
38
39 fn coordinate(
40 &mut self,
41 x: f64,
42 y: f64,
43 z: Option<f64>,
44 m: Option<f64>,
45 t: Option<f64>,
46 tm: Option<u64>,
47 idx: usize,
48 ) -> geozero::error::Result<()> {
49 self.push_coord(from_xyzm(x, y, z, m).as_ref());
50 Ok(())
51 }
52
53 fn geometrycollection_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
54 self.reserve_exact(size);
55 Ok(())
56 }
57
58 fn circularstring_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
60 Err(geozero::error::GeozeroError::Geometry(
61 "Only point geometries allowed".to_string(),
62 ))
63 }
64
65 fn compoundcurve_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
66 Err(geozero::error::GeozeroError::Geometry(
67 "Only point geometries allowed".to_string(),
68 ))
69 }
70
71 fn tin_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
72 Err(geozero::error::GeozeroError::Geometry(
73 "Only point geometries allowed".to_string(),
74 ))
75 }
76
77 fn polygon_begin(
78 &mut self,
79 tagged: bool,
80 size: usize,
81 idx: usize,
82 ) -> geozero::error::Result<()> {
83 Err(geozero::error::GeozeroError::Geometry(
84 "Only point geometries allowed".to_string(),
85 ))
86 }
87
88 fn triangle_begin(
89 &mut self,
90 tagged: bool,
91 size: usize,
92 idx: usize,
93 ) -> geozero::error::Result<()> {
94 Err(geozero::error::GeozeroError::Geometry(
95 "Only point geometries allowed".to_string(),
96 ))
97 }
98
99 fn linestring_begin(
100 &mut self,
101 tagged: bool,
102 size: usize,
103 idx: usize,
104 ) -> geozero::error::Result<()> {
105 Err(geozero::error::GeozeroError::Geometry(
106 "Only point geometries allowed".to_string(),
107 ))
108 }
109
110 fn multipoint_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
117 Err(geozero::error::GeozeroError::Geometry(
118 "Only point geometries allowed".to_string(),
119 ))
120 }
121
122 fn curvepolygon_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
123 Err(geozero::error::GeozeroError::Geometry(
124 "Only point geometries allowed".to_string(),
125 ))
126 }
127
128 fn multipolygon_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
129 Err(geozero::error::GeozeroError::Geometry(
130 "Only point geometries allowed".to_string(),
131 ))
132 }
133
134 fn multisurface_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
135 Err(geozero::error::GeozeroError::Geometry(
136 "Only point geometries allowed".to_string(),
137 ))
138 }
139
140 fn multilinestring_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
141 Err(geozero::error::GeozeroError::Geometry(
142 "Only point geometries allowed".to_string(),
143 ))
144 }
145
146 fn polyhedralsurface_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
147 Err(geozero::error::GeozeroError::Geometry(
148 "Only point geometries allowed".to_string(),
149 ))
150 }
151}
152
153#[cfg(test)]
154mod test {
155
156 use geo_types::{Geometry, GeometryCollection};
157 use geoarrow_schema::Dimension;
158
159 use super::*;
160 use crate::GeoArrowArrayAccessor;
161 use crate::test::{linestring, point};
162
163 #[test]
164 fn from_geozero() {
165 let geo = Geometry::GeometryCollection(
166 vec![
167 Geometry::Point(point::p0()),
168 Geometry::Point(point::p1()),
169 Geometry::Point(point::p2()),
170 ]
171 .into(),
172 );
173
174 let typ = PointType::new(Dimension::XY, Default::default());
175 let point_array = geo.to_point_array(typ).unwrap();
176 assert_eq!(point_array.value(0).unwrap(), point::p0());
177 assert_eq!(point_array.value(1).unwrap(), point::p1());
178 assert_eq!(point_array.value(2).unwrap(), point::p2());
179 }
180
181 #[test]
182 fn from_geozero_error_multiple_geom_types() {
183 let geo = Geometry::GeometryCollection(GeometryCollection(vec![
184 Geometry::Point(point::p0()),
185 Geometry::LineString(linestring::ls0()),
186 ]));
187
188 let typ = PointType::new(Dimension::XY, Default::default());
189 let err = ToPointArray::to_point_array(&geo, typ).unwrap_err();
190 assert!(matches!(err, geozero::error::GeozeroError::Geometry(..)));
191 }
192}