geoarrow_array/scalar/
multilinestring.rs1use arrow_buffer::OffsetBuffer;
2use geo_traits::MultiLineStringTrait;
3use geoarrow_schema::Dimension;
4
5use crate::array::CoordBuffer;
6use crate::eq::multi_line_string_eq;
7use crate::scalar::LineString;
8use crate::util::OffsetBufferUtils;
9
10#[derive(Debug, Clone)]
14pub struct MultiLineString<'a> {
15 pub(crate) coords: &'a CoordBuffer,
16
17 pub(crate) geom_offsets: &'a OffsetBuffer<i32>,
19
20 pub(crate) ring_offsets: &'a OffsetBuffer<i32>,
22
23 pub(crate) geom_index: usize,
24
25 start_offset: usize,
26}
27
28impl<'a> MultiLineString<'a> {
29 pub(crate) fn new(
30 coords: &'a CoordBuffer,
31 geom_offsets: &'a OffsetBuffer<i32>,
32 ring_offsets: &'a OffsetBuffer<i32>,
33 geom_index: usize,
34 ) -> Self {
35 let (start_offset, _) = geom_offsets.start_end(geom_index);
36 Self {
37 coords,
38 geom_offsets,
39 ring_offsets,
40 geom_index,
41 start_offset,
42 }
43 }
44
45 pub(crate) fn native_dim(&self) -> Dimension {
46 self.coords.dim()
47 }
48}
49
50impl<'a> MultiLineStringTrait for MultiLineString<'a> {
51 type InnerLineStringType<'b>
52 = LineString<'a>
53 where
54 Self: 'b;
55
56 fn num_line_strings(&self) -> usize {
57 let (start, end) = self.geom_offsets.start_end(self.geom_index);
58 end - start
59 }
60
61 unsafe fn line_string_unchecked(&self, i: usize) -> Self::InnerLineStringType<'_> {
62 LineString::new(self.coords, self.ring_offsets, self.start_offset + i)
63 }
64}
65
66impl<'a> MultiLineStringTrait for &'a MultiLineString<'a> {
67 type InnerLineStringType<'b>
68 = LineString<'a>
69 where
70 Self: 'b;
71
72 fn num_line_strings(&self) -> usize {
73 let (start, end) = self.geom_offsets.start_end(self.geom_index);
74 end - start
75 }
76
77 unsafe fn line_string_unchecked(&self, i: usize) -> Self::InnerLineStringType<'_> {
78 LineString::new(self.coords, self.ring_offsets, self.start_offset + i)
79 }
80}
81
82impl<G: MultiLineStringTrait<T = f64>> PartialEq<G> for MultiLineString<'_> {
83 fn eq(&self, other: &G) -> bool {
84 multi_line_string_eq(self, other)
85 }
86}
87
88#[cfg(test)]
89mod test {
90 use geoarrow_schema::{Dimension, MultiLineStringType};
91
92 use crate::builder::MultiLineStringBuilder;
93 use crate::test::multilinestring::{ml0, ml1};
94 use crate::trait_::GeoArrowArrayAccessor;
95
96 #[test]
98 fn test_eq_other_index_false() {
99 let typ = MultiLineStringType::new(Dimension::XY, Default::default());
100
101 let arr1 = MultiLineStringBuilder::from_multi_line_strings(
102 vec![ml0(), ml1()].as_slice(),
103 typ.clone(),
104 )
105 .finish();
106 let arr2 =
107 MultiLineStringBuilder::from_multi_line_strings(vec![ml0(), ml0()].as_slice(), typ)
108 .finish();
109
110 assert_eq!(arr1.value(0).unwrap(), arr2.value(0).unwrap());
111 assert_ne!(arr1.value(1).unwrap(), arr2.value(1).unwrap());
112 }
113}