geoarrow_array/geozero/import/
multipolygon.rs1use geoarrow_schema::MultiPolygonType;
2use geozero::{GeomProcessor, GeozeroGeometry};
3
4use crate::array::MultiPolygonArray;
5use crate::builder::MultiPolygonBuilder;
6use crate::capacity::MultiPolygonCapacity;
7use crate::geozero::import::util::{from_xy, from_xyzm};
8
9pub trait ToMultiPolygonArray {
11 fn to_multi_polygon_array(
13 &self,
14 typ: MultiPolygonType,
15 ) -> geozero::error::Result<MultiPolygonArray>;
16
17 fn to_multi_polygon_builder(
19 &self,
20 typ: MultiPolygonType,
21 ) -> geozero::error::Result<MultiPolygonBuilder>;
22}
23
24impl<T: GeozeroGeometry> ToMultiPolygonArray for T {
25 fn to_multi_polygon_array(
26 &self,
27 typ: MultiPolygonType,
28 ) -> geozero::error::Result<MultiPolygonArray> {
29 Ok(self.to_multi_polygon_builder(typ)?.finish())
30 }
31
32 fn to_multi_polygon_builder(
33 &self,
34 typ: MultiPolygonType,
35 ) -> geozero::error::Result<MultiPolygonBuilder> {
36 let mut mutable_array = MultiPolygonBuilder::new(typ);
37 self.process_geom(&mut mutable_array)?;
38 Ok(mutable_array)
39 }
40}
41
42#[allow(unused_variables)]
43impl GeomProcessor for MultiPolygonBuilder {
44 fn geometrycollection_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
45 let capacity = MultiPolygonCapacity::new(0, 0, 0, size);
47 self.reserve(capacity);
48 Ok(())
49 }
50
51 fn geometrycollection_end(&mut self, idx: usize) -> geozero::error::Result<()> {
52 Ok(())
54 }
55
56 fn xy(&mut self, x: f64, y: f64, idx: usize) -> geozero::error::Result<()> {
57 unsafe { self.push_coord(&from_xy(x, y).expect("valid coord")) }.unwrap();
61 Ok(())
62 }
63
64 fn coordinate(
65 &mut self,
66 x: f64,
67 y: f64,
68 z: Option<f64>,
69 m: Option<f64>,
70 t: Option<f64>,
71 tm: Option<u64>,
72 idx: usize,
73 ) -> geozero::error::Result<()> {
74 unsafe { self.push_coord(&from_xyzm(x, y, z, m).expect("valid coord")) }.unwrap();
78 Ok(())
79 }
80
81 fn multipolygon_begin(&mut self, size: usize, idx: usize) -> geozero::error::Result<()> {
82 let capacity = MultiPolygonCapacity::new(0, 0, size, 0);
84 self.reserve(capacity);
85
86 self.try_push_geom_offset(size).unwrap();
90 Ok(())
91 }
92
93 fn polygon_begin(
94 &mut self,
95 tagged: bool,
96 size: usize,
97 idx: usize,
98 ) -> geozero::error::Result<()> {
99 if tagged {
101 let capacity = MultiPolygonCapacity::new(0, 0, 1, 0);
103 self.reserve(capacity);
104
105 self.try_push_geom_offset(1).unwrap();
109 }
110
111 let capacity = MultiPolygonCapacity::new(0, size, 0, 0);
113 self.reserve(capacity);
114
115 self.try_push_polygon_offset(size).unwrap();
119 Ok(())
120 }
121
122 fn linestring_begin(
123 &mut self,
124 tagged: bool,
125 size: usize,
126 idx: usize,
127 ) -> geozero::error::Result<()> {
128 assert!(!tagged);
129
130 let capacity = MultiPolygonCapacity::new(size, 0, 0, 0);
132 self.reserve(capacity);
133
134 self.try_push_ring_offset(size).unwrap();
138 Ok(())
139 }
140}
141
142#[cfg(test)]
143mod test {
144 use geo_types::Geometry;
145 use geoarrow_schema::Dimension;
146 use geozero::error::Result;
147
148 use super::*;
149 use crate::test::multipolygon::{mp0, mp1};
150
151 #[test]
152 fn from_geozero() -> Result<()> {
153 let geo_geoms = vec![mp0(), mp1()];
154
155 let geo = Geometry::GeometryCollection(
156 geo_geoms
157 .clone()
158 .into_iter()
159 .map(Geometry::MultiPolygon)
160 .collect(),
161 );
162 let typ = MultiPolygonType::new(Dimension::XY, Default::default());
163 let geo_arr = geo.to_multi_polygon_array(typ.clone()).unwrap();
164
165 let geo_arr2 = MultiPolygonBuilder::from_multi_polygons(&geo_geoms, typ).finish();
166
167 assert_eq!(geo_arr, geo_arr2);
169 Ok(())
170 }
171}