geoarrow_array/scalar/coord/
interleaved.rs1use arrow_buffer::ScalarBuffer;
2use geo_traits::CoordTrait;
3use geoarrow_schema::Dimension;
4
5use crate::eq::coord_eq;
6use crate::scalar::SeparatedCoord;
7
8#[derive(Debug, Clone)]
12pub struct InterleavedCoord<'a> {
13 pub(crate) coords: &'a ScalarBuffer<f64>,
14 pub(crate) i: usize,
15 pub(crate) dim: Dimension,
16}
17
18impl InterleavedCoord<'_> {
19 pub(crate) fn is_nan(&self) -> bool {
21 (0..self.dim.size()).all(|coord_dim| self.nth_or_panic(coord_dim).is_nan())
22 }
23}
24
25impl PartialEq for InterleavedCoord<'_> {
26 fn eq(&self, other: &Self) -> bool {
27 coord_eq(self, other)
28 }
29}
30
31impl PartialEq<SeparatedCoord<'_>> for InterleavedCoord<'_> {
32 fn eq(&self, other: &SeparatedCoord<'_>) -> bool {
33 coord_eq(self, other)
34 }
35}
36
37impl CoordTrait for InterleavedCoord<'_> {
38 type T = f64;
39
40 fn dim(&self) -> geo_traits::Dimensions {
41 self.dim.into()
42 }
43
44 fn nth_or_panic(&self, n: usize) -> Self::T {
45 debug_assert!(n < self.dim.size());
46 *self.coords.get(self.i * self.dim.size() + n).unwrap()
47 }
48
49 fn x(&self) -> Self::T {
50 *self.coords.get(self.i * self.dim.size()).unwrap()
51 }
52
53 fn y(&self) -> Self::T {
54 *self.coords.get(self.i * self.dim.size() + 1).unwrap()
55 }
56}
57
58impl CoordTrait for &InterleavedCoord<'_> {
59 type T = f64;
60
61 fn dim(&self) -> geo_traits::Dimensions {
62 self.dim.into()
63 }
64
65 fn nth_or_panic(&self, n: usize) -> Self::T {
66 debug_assert!(n < self.dim.size());
67 *self.coords.get(self.i * self.dim.size() + n).unwrap()
68 }
69
70 fn x(&self) -> Self::T {
71 *self.coords.get(self.i * self.dim.size()).unwrap()
72 }
73
74 fn y(&self) -> Self::T {
75 *self.coords.get(self.i * self.dim.size() + 1).unwrap()
76 }
77}
78
79#[cfg(test)]
80mod test {
81 use geoarrow_schema::Dimension;
82
83 use crate::array::{InterleavedCoordBuffer, SeparatedCoordBuffer};
84
85 #[test]
87 fn test_eq_other_index_false() {
88 let coords1 = vec![0., 3., 1., 4., 2., 5.];
89 let buf1 = InterleavedCoordBuffer::new(coords1.into(), Dimension::XY);
90 let coord1 = buf1.value(0);
91
92 let coords2 = vec![0., 3., 100., 400., 200., 500.];
93 let buf2 = InterleavedCoordBuffer::new(coords2.into(), Dimension::XY);
94 let coord2 = buf2.value(0);
95
96 assert_eq!(coord1, coord2);
97 }
98
99 #[test]
100 fn test_eq_against_separated_coord() {
101 let coords1 = vec![0., 3., 1., 4., 2., 5.];
102 let buf1 = InterleavedCoordBuffer::new(coords1.into(), Dimension::XY);
103 let coord1 = buf1.value(0);
104
105 let x = vec![0.];
106 let y = vec![3.];
107 let buf2 = SeparatedCoordBuffer::from_vec(vec![x.into(), y.into()], Dimension::XY).unwrap();
108 let coord2 = buf2.value(0);
109
110 assert_eq!(coord1, coord2);
111 }
112}