1use geo_traits::{
4 GeometryTrait, RectTrait, UnimplementedGeometryCollection, UnimplementedLine,
5 UnimplementedLineString, UnimplementedMultiLineString, UnimplementedMultiPoint,
6 UnimplementedMultiPolygon, UnimplementedPoint, UnimplementedPolygon, UnimplementedTriangle,
7};
8
9use crate::kdtree::KDTreeIndex;
10use crate::r#type::{Coord, IndexableNum};
11use std::marker::PhantomData;
12
13#[derive(Debug, Clone)]
15pub struct Node<'a, N: IndexableNum, T: KDTreeIndex<N>> {
16 tree: &'a T,
18
19 axis: usize,
23
24 right_child: usize,
26
27 left_child: usize,
29
30 min_x: N,
32 min_y: N,
34 max_x: N,
36 max_y: N,
38
39 phantom: PhantomData<N>,
40}
41
42impl<'a, N: IndexableNum, T: KDTreeIndex<N>> Node<'a, N, T> {
43 pub(crate) fn from_root(tree: &'a T) -> Self {
44 Self {
45 tree,
46 axis: 0,
47 right_child: tree.indices().len() - 1,
48 left_child: 0,
49 min_x: N::max_value(),
50 min_y: N::max_value(),
51 max_x: N::min_value(),
52 max_y: N::min_value(),
53 phantom: PhantomData,
54 }
55 }
56
57 #[inline]
61 pub(crate) fn middle_index(&self) -> usize {
62 (self.left_child + self.right_child) >> 1
63 }
64
65 #[inline]
68 pub(crate) fn middle_xy(&self, m: usize) -> (N, N) {
69 let x = self.tree.coords()[2 * m];
70 let y = self.tree.coords()[2 * m + 1];
71 (x, y)
72 }
73
74 pub fn left_child(&self) -> Option<Node<'_, N, T>> {
78 if self.is_parent() {
79 Some(self.left_child_unchecked())
80 } else {
81 None
82 }
83 }
84
85 pub fn left_child_unchecked(&self) -> Node<'_, N, T> {
89 debug_assert!(self.is_parent());
90
91 let m = self.middle_index();
92 let (x, y) = self.middle_xy(m);
93
94 let mut max_x = self.max_x;
95 let mut max_y = self.max_y;
96 if self.axis == 0 {
97 max_x = x;
98 } else {
99 max_y = y;
100 };
101
102 Self {
103 tree: self.tree,
104 axis: 1 - self.axis,
105 right_child: m - 1,
106 left_child: self.left_child,
107 min_x: self.min_x,
108 min_y: self.min_y,
109 max_x,
110 max_y,
111 phantom: self.phantom,
112 }
113 }
114
115 pub fn right_child(&self) -> Option<Node<'_, N, T>> {
119 if self.is_parent() {
120 Some(self.right_child_unchecked())
121 } else {
122 None
123 }
124 }
125
126 pub fn right_child_unchecked(&self) -> Node<'_, N, T> {
130 debug_assert!(self.is_parent());
131
132 let m = self.middle_index();
133 let (x, y) = self.middle_xy(m);
134
135 let mut min_x = self.min_x;
136 let mut min_y = self.min_y;
137 if self.axis == 0 {
138 min_x = x;
139 } else {
140 min_y = y;
141 };
142
143 Self {
144 tree: self.tree,
145 axis: 1 - self.axis,
146 right_child: self.right_child,
147 left_child: m + 1,
148 min_x,
149 min_y,
150 max_x: self.max_x,
151 max_y: self.max_y,
152 phantom: self.phantom,
153 }
154 }
155
156 #[inline]
158 pub fn is_leaf(&self) -> bool {
159 self.right_child - self.left_child <= self.tree.node_size() as usize
160 }
161
162 #[inline]
164 pub fn is_parent(&self) -> bool {
165 !self.is_leaf()
166 }
167
168 #[inline]
173 pub fn middle_insertion_index(&self) -> Option<u32> {
174 if self.is_parent() {
175 Some(self.middle_insertion_index_unchecked())
176 } else {
177 None
178 }
179 }
180
181 #[inline]
184 pub fn middle_insertion_index_unchecked(&self) -> u32 {
185 debug_assert!(self.is_parent());
186
187 let m = self.middle_index();
188 let indices = self.tree.indices();
189 indices.get(m) as u32
190 }
191
192 #[inline]
197 pub fn leaf_insertion_indices(&self) -> Option<Vec<u32>> {
198 if self.is_leaf() {
199 Some(self.leaf_insertion_indices_unchecked())
200 } else {
201 None
202 }
203 }
204
205 #[inline]
208 pub fn leaf_insertion_indices_unchecked(&self) -> Vec<u32> {
209 debug_assert!(self.is_leaf());
210
211 let mut result = Vec::with_capacity(self.tree.node_size() as _);
212
213 let indices = self.tree.indices();
214 for i in self.left_child..self.right_child + 1 {
215 result.push(indices.get(i) as u32);
216 }
217
218 result
219 }
220}
221
222impl<N: IndexableNum, T: KDTreeIndex<N>> RectTrait for Node<'_, N, T> {
223 type CoordType<'a>
224 = Coord<N>
225 where
226 Self: 'a;
227
228 fn min(&self) -> Self::CoordType<'_> {
229 Coord {
230 x: self.min_x,
231 y: self.min_y,
232 }
233 }
234
235 fn max(&self) -> Self::CoordType<'_> {
236 Coord {
237 x: self.max_x,
238 y: self.max_y,
239 }
240 }
241}
242
243impl<N: IndexableNum, T: KDTreeIndex<N>> GeometryTrait for Node<'_, N, T> {
244 type T = N;
245
246 type PointType<'a>
247 = UnimplementedPoint<N>
248 where
249 Self: 'a;
250
251 type LineStringType<'a>
252 = UnimplementedLineString<N>
253 where
254 Self: 'a;
255
256 type PolygonType<'a>
257 = UnimplementedPolygon<N>
258 where
259 Self: 'a;
260
261 type MultiPointType<'a>
262 = UnimplementedMultiPoint<N>
263 where
264 Self: 'a;
265
266 type MultiLineStringType<'a>
267 = UnimplementedMultiLineString<N>
268 where
269 Self: 'a;
270
271 type MultiPolygonType<'a>
272 = UnimplementedMultiPolygon<N>
273 where
274 Self: 'a;
275
276 type GeometryCollectionType<'a>
277 = UnimplementedGeometryCollection<N>
278 where
279 Self: 'a;
280
281 type RectType<'a>
282 = Node<'a, N, T>
283 where
284 Self: 'a;
285
286 type TriangleType<'a>
287 = UnimplementedTriangle<N>
288 where
289 Self: 'a;
290
291 type LineType<'a>
292 = UnimplementedLine<N>
293 where
294 Self: 'a;
295
296 fn dim(&self) -> geo_traits::Dimensions {
297 geo_traits::Dimensions::Xy
298 }
299
300 fn as_type(
301 &self,
302 ) -> geo_traits::GeometryType<
303 '_,
304 Self::PointType<'_>,
305 Self::LineStringType<'_>,
306 Self::PolygonType<'_>,
307 Self::MultiPointType<'_>,
308 Self::MultiLineStringType<'_>,
309 Self::MultiPolygonType<'_>,
310 Self::GeometryCollectionType<'_>,
311 Self::RectType<'_>,
312 Self::TriangleType<'_>,
313 Self::LineType<'_>,
314 > {
315 geo_traits::GeometryType::Rect(self)
316 }
317}