geoarrow_array/scalar/
linestring.rs

1use arrow_buffer::OffsetBuffer;
2use geo_traits::LineStringTrait;
3use geoarrow_schema::Dimension;
4
5use crate::array::CoordBuffer;
6use crate::eq::line_string_eq;
7use crate::scalar::Coord;
8use crate::util::OffsetBufferUtils;
9
10/// An Arrow equivalent of a LineString
11///
12/// This implements [LineStringTrait], which you can use to extract data.
13#[derive(Debug, Clone)]
14pub struct LineString<'a> {
15    pub(crate) coords: &'a CoordBuffer,
16
17    /// Offsets into the coordinate array where each geometry starts
18    pub(crate) geom_offsets: &'a OffsetBuffer<i32>,
19
20    pub(crate) geom_index: usize,
21
22    start_offset: usize,
23}
24
25impl<'a> LineString<'a> {
26    pub(crate) fn new(
27        coords: &'a CoordBuffer,
28        geom_offsets: &'a OffsetBuffer<i32>,
29        geom_index: usize,
30    ) -> Self {
31        let (start_offset, _) = geom_offsets.start_end(geom_index);
32        Self {
33            coords,
34            geom_offsets,
35            geom_index,
36            start_offset,
37        }
38    }
39
40    pub(crate) fn native_dim(&self) -> Dimension {
41        self.coords.dim()
42    }
43}
44
45impl<'a> LineStringTrait for LineString<'a> {
46    type CoordType<'b>
47        = Coord<'a>
48    where
49        Self: 'b;
50
51    fn num_coords(&self) -> usize {
52        let (start, end) = self.geom_offsets.start_end(self.geom_index);
53        end - start
54    }
55
56    unsafe fn coord_unchecked(&self, i: usize) -> Self::CoordType<'_> {
57        self.coords.value(self.start_offset + i)
58    }
59}
60
61impl<'a> LineStringTrait for &'a LineString<'a> {
62    type CoordType<'b>
63        = Coord<'a>
64    where
65        Self: 'b;
66
67    fn num_coords(&self) -> usize {
68        let (start, end) = self.geom_offsets.start_end(self.geom_index);
69        end - start
70    }
71
72    unsafe fn coord_unchecked(&self, i: usize) -> Self::CoordType<'_> {
73        self.coords.value(self.start_offset + i)
74    }
75}
76
77impl<G: LineStringTrait<T = f64>> PartialEq<G> for LineString<'_> {
78    fn eq(&self, other: &G) -> bool {
79        line_string_eq(self, other)
80    }
81}