rstar/algorithm/
selection_functions.rs1use crate::object::PointDistance;
2use crate::object::RTreeObject;
3use crate::{envelope::Envelope, object::Distance};
4
5pub trait SelectionFunction<T>
24where
25 T: RTreeObject,
26{
27 fn should_unpack_parent(&self, envelope: &T::Envelope) -> bool;
31
32 fn should_unpack_leaf(&self, _leaf: &T) -> bool {
35 true
36 }
37}
38
39pub struct SelectInEnvelopeFunction<T>
40where
41 T: RTreeObject,
42{
43 envelope: T::Envelope,
44}
45
46impl<T> SelectInEnvelopeFunction<T>
47where
48 T: RTreeObject,
49{
50 pub fn new(envelope: T::Envelope) -> Self {
51 SelectInEnvelopeFunction { envelope }
52 }
53}
54
55impl<T> SelectionFunction<T> for SelectInEnvelopeFunction<T>
56where
57 T: RTreeObject,
58{
59 fn should_unpack_parent(&self, parent_envelope: &T::Envelope) -> bool {
60 self.envelope.intersects(parent_envelope)
61 }
62
63 fn should_unpack_leaf(&self, leaf: &T) -> bool {
64 self.envelope.contains_envelope(&leaf.envelope())
65 }
66}
67
68pub struct SelectInEnvelopeFuncIntersecting<T>
69where
70 T: RTreeObject,
71{
72 envelope: T::Envelope,
73}
74
75impl<T> SelectInEnvelopeFuncIntersecting<T>
76where
77 T: RTreeObject,
78{
79 pub fn new(envelope: T::Envelope) -> Self {
80 SelectInEnvelopeFuncIntersecting { envelope }
81 }
82}
83
84impl<T> SelectionFunction<T> for SelectInEnvelopeFuncIntersecting<T>
85where
86 T: RTreeObject,
87{
88 fn should_unpack_parent(&self, envelope: &T::Envelope) -> bool {
89 self.envelope.intersects(envelope)
90 }
91
92 fn should_unpack_leaf(&self, leaf: &T) -> bool {
93 leaf.envelope().intersects(&self.envelope)
94 }
95}
96
97pub struct SelectAllFunc;
98
99impl<T> SelectionFunction<T> for SelectAllFunc
100where
101 T: RTreeObject,
102{
103 fn should_unpack_parent(&self, _: &T::Envelope) -> bool {
104 true
105 }
106}
107
108pub struct SelectAtPointFunction<T>
111where
112 T: RTreeObject,
113{
114 point: <T::Envelope as Envelope>::Point,
115}
116
117impl<T> SelectAtPointFunction<T>
118where
119 T: PointDistance,
120{
121 pub fn new(point: <T::Envelope as Envelope>::Point) -> Self {
122 SelectAtPointFunction { point }
123 }
124}
125
126impl<T> SelectionFunction<T> for SelectAtPointFunction<T>
127where
128 T: PointDistance,
129{
130 fn should_unpack_parent(&self, envelope: &T::Envelope) -> bool {
131 envelope.contains_point(&self.point)
132 }
133
134 fn should_unpack_leaf(&self, leaf: &T) -> bool {
135 leaf.contains_point(&self.point)
136 }
137}
138
139pub struct SelectEqualsFunction<'a, T>
142where
143 T: RTreeObject + PartialEq + 'a,
144{
145 object_to_remove: &'a T,
147}
148
149impl<'a, T> SelectEqualsFunction<'a, T>
150where
151 T: RTreeObject + PartialEq,
152{
153 pub fn new(object_to_remove: &'a T) -> Self {
154 SelectEqualsFunction { object_to_remove }
155 }
156}
157
158impl<T> SelectionFunction<T> for SelectEqualsFunction<'_, T>
159where
160 T: RTreeObject + PartialEq,
161{
162 fn should_unpack_parent(&self, parent_envelope: &T::Envelope) -> bool {
163 parent_envelope.contains_envelope(&self.object_to_remove.envelope())
164 }
165
166 fn should_unpack_leaf(&self, leaf: &T) -> bool {
167 leaf == self.object_to_remove
168 }
169}
170
171pub struct SelectWithinDistanceFunction<T>
172where
173 T: RTreeObject + PointDistance,
174{
175 circle_origin: <T::Envelope as Envelope>::Point,
176 squared_max_distance: Distance<T>,
177}
178
179impl<T> SelectWithinDistanceFunction<T>
180where
181 T: RTreeObject + PointDistance,
182{
183 pub fn new(
184 circle_origin: <T::Envelope as Envelope>::Point,
185 squared_max_distance: Distance<T>,
186 ) -> Self {
187 SelectWithinDistanceFunction {
188 circle_origin,
189 squared_max_distance,
190 }
191 }
192}
193
194impl<T> SelectionFunction<T> for SelectWithinDistanceFunction<T>
195where
196 T: RTreeObject + PointDistance,
197{
198 fn should_unpack_parent(&self, parent_envelope: &T::Envelope) -> bool {
199 let envelope_distance = parent_envelope.distance_2(&self.circle_origin);
200 envelope_distance <= self.squared_max_distance
201 }
202
203 fn should_unpack_leaf(&self, leaf: &T) -> bool {
204 leaf.distance_2_if_less_or_equal(&self.circle_origin, self.squared_max_distance)
205 .is_some()
206 }
207}
208
209pub struct SelectByAddressFunction<T>
210where
211 T: RTreeObject,
212{
213 envelope: T::Envelope,
214 element_address: *const T,
215}
216
217impl<T> SelectByAddressFunction<T>
218where
219 T: RTreeObject,
220{
221 pub fn new(envelope: T::Envelope, element_address: &T) -> Self {
222 Self {
223 envelope,
224 element_address,
225 }
226 }
227}
228
229impl<T> SelectionFunction<T> for SelectByAddressFunction<T>
230where
231 T: RTreeObject,
232{
233 fn should_unpack_parent(&self, parent_envelope: &T::Envelope) -> bool {
234 parent_envelope.contains_envelope(&self.envelope)
235 }
236
237 fn should_unpack_leaf(&self, leaf: &T) -> bool {
238 core::ptr::eq(self.element_address, leaf)
239 }
240}