geoarrow_array/
util.rs

1use arrow_array::OffsetSizeTrait;
2use arrow_buffer::OffsetBuffer;
3use geoarrow_schema::error::{GeoArrowError, GeoArrowResult};
4
5pub(crate) fn offsets_buffer_i32_to_i64(offsets: &OffsetBuffer<i32>) -> OffsetBuffer<i64> {
6    let i64_offsets = offsets.iter().map(|x| *x as i64).collect::<Vec<_>>();
7    unsafe { OffsetBuffer::new_unchecked(i64_offsets.into()) }
8}
9
10pub(crate) fn offsets_buffer_i64_to_i32(
11    offsets: &OffsetBuffer<i64>,
12) -> GeoArrowResult<OffsetBuffer<i32>> {
13    // TODO: raise nicer error. Ref:
14    // https://github.com/jorgecarleitao/arrow2/blob/6a4b53169a48cbd234cecde6ab6a98f84146fca2/src/offset.rs#L492
15    i32::try_from(*offsets.last()).map_err(|_| GeoArrowError::Overflow)?;
16
17    let i32_offsets = offsets.iter().map(|x| *x as i32).collect::<Vec<_>>();
18    Ok(unsafe { OffsetBuffer::new_unchecked(i32_offsets.into()) })
19}
20
21/// Offsets utils that I miss from arrow2
22pub(crate) trait OffsetBufferUtils<O: OffsetSizeTrait> {
23    /// Returns the length an array with these offsets would be.
24    fn len_proxy(&self) -> usize;
25
26    /// Returns a range (start, end) corresponding to the position `index`
27    /// # Panic
28    /// This function panics iff `index >= self.len_proxy()`
29    fn start_end(&self, index: usize) -> (usize, usize);
30
31    /// Returns the last offset.
32    fn last(&self) -> &O;
33}
34
35impl<O: OffsetSizeTrait> OffsetBufferUtils<O> for OffsetBuffer<O> {
36    /// Returns the length an array with these offsets would be.
37    #[inline]
38    fn len_proxy(&self) -> usize {
39        self.len() - 1
40    }
41
42    /// Returns a range (start, end) corresponding to the position `index`
43    ///
44    /// # Panic
45    ///
46    /// Panics iff `index >= self.len_proxy()`
47    #[inline]
48    fn start_end(&self, index: usize) -> (usize, usize) {
49        assert!(index < self.len_proxy());
50        let start = self[index].to_usize().unwrap();
51        let end = self[index + 1].to_usize().unwrap();
52        (start, end)
53    }
54
55    /// Returns the last offset.
56    #[inline]
57    fn last(&self) -> &O {
58        self.as_ref().last().unwrap()
59    }
60}
61
62pub(crate) trait GeometryTypeName {
63    /// Returns the name of the geometry type.
64    fn name(&self) -> String;
65}
66
67impl<P, LS, Y, MP, ML, MY, GC, R, T, L> GeometryTypeName
68    for geo_traits::GeometryType<'_, P, LS, Y, MP, ML, MY, GC, R, T, L>
69where
70    P: geo_traits::PointTrait,
71    LS: geo_traits::LineStringTrait,
72    Y: geo_traits::PolygonTrait,
73    MP: geo_traits::MultiPointTrait,
74    ML: geo_traits::MultiLineStringTrait,
75    MY: geo_traits::MultiPolygonTrait,
76    GC: geo_traits::GeometryCollectionTrait,
77    R: geo_traits::RectTrait,
78    T: geo_traits::TriangleTrait,
79    L: geo_traits::LineTrait,
80{
81    fn name(&self) -> String {
82        match self {
83            Self::Point(_) => "Point".to_string(),
84            Self::LineString(_) => "LineString".to_string(),
85            Self::Polygon(_) => "Polygon".to_string(),
86            Self::MultiPoint(_) => "MultiPoint".to_string(),
87            Self::MultiLineString(_) => "MultiLineString".to_string(),
88            Self::MultiPolygon(_) => "MultiPolygon".to_string(),
89            Self::GeometryCollection(_) => "GeometryCollection".to_string(),
90            Self::Rect(_) => "Rect".to_string(),
91            Self::Triangle(_) => "Triangle".to_string(),
92            Self::Line(_) => "Line".to_string(),
93        }
94    }
95}