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