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