geoarrow_array/capacity/
geometrycollection.rs1use std::ops::Add;
2
3use geo_traits::{
4 GeometryCollectionTrait, GeometryTrait, GeometryType, LineStringTrait, MultiLineStringTrait,
5 MultiPointTrait, MultiPolygonTrait, PointTrait, PolygonTrait,
6};
7use geoarrow_schema::error::GeoArrowResult;
8use wkt::WktNum;
9
10use crate::builder::geo_trait_wrappers::{LineWrapper, RectWrapper, TriangleWrapper};
11use crate::capacity::MixedCapacity;
12
13#[derive(Debug, Clone, Copy)]
18pub struct GeometryCollectionCapacity {
19 pub(crate) mixed_capacity: MixedCapacity,
20 pub(crate) geom_capacity: usize,
21}
22
23impl GeometryCollectionCapacity {
24 pub fn new(mixed_capacity: MixedCapacity, geom_capacity: usize) -> Self {
26 Self {
27 mixed_capacity,
28 geom_capacity,
29 }
30 }
31
32 pub fn new_empty() -> Self {
34 Self::new(MixedCapacity::new_empty(), 0)
35 }
36
37 pub fn is_empty(&self) -> bool {
39 self.mixed_capacity.is_empty() && self.geom_capacity == 0
40 }
41
42 pub fn geom_capacity(&self) -> usize {
44 self.geom_capacity
45 }
46
47 #[inline]
48 fn add_valid_point(&mut self, _geom: &impl PointTrait) {
49 self.mixed_capacity.add_point();
50 }
51
52 #[inline]
53 fn add_valid_line_string(&mut self, geom: &impl LineStringTrait) {
54 self.mixed_capacity.add_line_string(geom);
55 }
56
57 #[inline]
58 fn add_valid_polygon(&mut self, geom: &impl PolygonTrait) {
59 self.mixed_capacity.add_polygon(geom);
60 }
61
62 #[inline]
63 fn add_valid_multi_point(&mut self, geom: &impl MultiPointTrait) {
64 self.mixed_capacity.add_multi_point(geom);
65 }
66
67 #[inline]
68 fn add_valid_multi_line_string(&mut self, geom: &impl MultiLineStringTrait) {
69 self.mixed_capacity.add_multi_line_string(geom);
70 }
71
72 #[inline]
73 fn add_valid_multi_polygon(&mut self, geom: &impl MultiPolygonTrait) {
74 self.mixed_capacity.add_multi_polygon(geom);
75 }
76
77 #[inline]
78 fn add_valid_geometry_collection<T: WktNum>(
79 &mut self,
80 geom: &impl GeometryCollectionTrait<T = T>,
81 ) -> GeoArrowResult<()> {
82 for g in geom.geometries() {
83 self.mixed_capacity.add_geometry(&g)?
84 }
85 Ok(())
86 }
87
88 #[inline]
90 pub fn add_geometry<T: WktNum>(
91 &mut self,
92 geom: Option<&impl GeometryTrait<T = T>>,
93 ) -> GeoArrowResult<()> {
94 use GeometryType::*;
95 if let Some(geom) = geom {
96 match geom.as_type() {
97 Point(p) => self.add_valid_point(p),
98 LineString(p) => self.add_valid_line_string(p),
99 Polygon(p) => self.add_valid_polygon(p),
100 MultiPoint(p) => self.add_valid_multi_point(p),
101 MultiLineString(p) => self.add_valid_multi_line_string(p),
102 MultiPolygon(p) => self.add_valid_multi_polygon(p),
103 GeometryCollection(p) => self.add_valid_geometry_collection(p)?,
104 Rect(r) => self.add_valid_polygon(&RectWrapper::try_new(r)?),
105 Triangle(tri) => self.add_valid_polygon(&TriangleWrapper(tri)),
106 Line(l) => self.add_valid_line_string(&LineWrapper(l)),
107 }
108 };
109 Ok(())
110 }
111
112 #[inline]
114 pub fn add_geometry_collection<'a, T: WktNum>(
115 &mut self,
116 geom: Option<&'a (impl GeometryCollectionTrait<T = T> + 'a)>,
117 ) -> GeoArrowResult<()> {
118 if let Some(geom) = geom {
119 self.add_valid_geometry_collection(geom)?;
120 }
121 self.geom_capacity += 1;
122 Ok(())
123 }
124
125 pub fn from_geometry_collections<'a, T: WktNum>(
127 geoms: impl Iterator<Item = Option<&'a (impl GeometryCollectionTrait<T = T> + 'a)>>,
128 ) -> GeoArrowResult<Self> {
129 let mut counter = Self::new_empty();
130 for maybe_geom in geoms.into_iter() {
131 counter.add_geometry_collection(maybe_geom)?;
132 }
133 Ok(counter)
134 }
135
136 pub fn from_geometries<'a, T: WktNum>(
138 geoms: impl Iterator<Item = Option<&'a (impl GeometryTrait<T = T> + 'a)>>,
139 ) -> GeoArrowResult<Self> {
140 let mut counter = Self::new_empty();
141 for maybe_geom in geoms.into_iter() {
142 counter.add_geometry(maybe_geom)?;
143 }
144 Ok(counter)
145 }
146
147 pub fn num_bytes(&self) -> usize {
149 let offsets_byte_width = 4;
150 let num_offsets = self.geom_capacity;
151 (offsets_byte_width * num_offsets) + self.mixed_capacity.num_bytes()
152 }
153}
154
155impl Default for GeometryCollectionCapacity {
156 fn default() -> Self {
157 Self::new_empty()
158 }
159}
160
161impl Add for GeometryCollectionCapacity {
162 type Output = Self;
163
164 fn add(self, rhs: Self) -> Self::Output {
165 let mixed_capacity = self.mixed_capacity + rhs.mixed_capacity;
166 let geom_capacity = self.geom_capacity + rhs.geom_capacity;
167
168 Self::new(mixed_capacity, geom_capacity)
169 }
170}