]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/index/detail/distance_predicates.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / index / detail / distance_predicates.hpp
1 // Boost.Geometry Index
2 //
3 // Spatial index distance predicates, calculators and checkers
4 // used in nearest query - specialized for envelopes
5 //
6 // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
7 //
8 // This file was modified by Oracle on 2019-2020.
9 // Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
11 //
12 // Use, modification and distribution is subject to the Boost Software License,
13 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
14 // http://www.boost.org/LICENSE_1_0.txt)
15
16 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_DISTANCE_PREDICATES_HPP
17 #define BOOST_GEOMETRY_INDEX_DETAIL_DISTANCE_PREDICATES_HPP
18
19 #include <boost/geometry/core/static_assert.hpp>
20
21 #include <boost/geometry/index/detail/algorithms/comparable_distance_near.hpp>
22 #include <boost/geometry/index/detail/algorithms/comparable_distance_far.hpp>
23 #include <boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp>
24 #include <boost/geometry/index/detail/algorithms/path_intersection.hpp>
25
26 #include <boost/geometry/index/detail/tags.hpp>
27
28 namespace boost { namespace geometry { namespace index { namespace detail {
29
30 // ------------------------------------------------------------------ //
31 // relations
32 // ------------------------------------------------------------------ //
33
34 template <typename T>
35 struct to_nearest
36 {
37 to_nearest(T const& v) : value(v) {}
38 T value;
39 };
40
41 template <typename T>
42 struct to_centroid
43 {
44 to_centroid(T const& v) : value(v) {}
45 T value;
46 };
47
48 template <typename T>
49 struct to_furthest
50 {
51 to_furthest(T const& v) : value(v) {}
52 T value;
53 };
54
55 // tags
56
57 struct to_nearest_tag {};
58 struct to_centroid_tag {};
59 struct to_furthest_tag {};
60
61 // ------------------------------------------------------------------ //
62 // relation traits and access
63 // ------------------------------------------------------------------ //
64
65 template <typename T>
66 struct relation
67 {
68 typedef T value_type;
69 typedef to_nearest_tag tag;
70 static inline T const& value(T const& v) { return v; }
71 static inline T & value(T & v) { return v; }
72 };
73
74 template <typename T>
75 struct relation< to_nearest<T> >
76 {
77 typedef T value_type;
78 typedef to_nearest_tag tag;
79 static inline T const& value(to_nearest<T> const& r) { return r.value; }
80 static inline T & value(to_nearest<T> & r) { return r.value; }
81 };
82
83 template <typename T>
84 struct relation< to_centroid<T> >
85 {
86 typedef T value_type;
87 typedef to_centroid_tag tag;
88 static inline T const& value(to_centroid<T> const& r) { return r.value; }
89 static inline T & value(to_centroid<T> & r) { return r.value; }
90 };
91
92 template <typename T>
93 struct relation< to_furthest<T> >
94 {
95 typedef T value_type;
96 typedef to_furthest_tag tag;
97 static inline T const& value(to_furthest<T> const& r) { return r.value; }
98 static inline T & value(to_furthest<T> & r) { return r.value; }
99 };
100
101 // ------------------------------------------------------------------ //
102
103 template
104 <
105 typename G1, typename G2, typename Strategy,
106 typename Tag1 = typename geometry::tag<G1>::type,
107 typename Tag2 = typename geometry::tag<G2>::type
108 >
109 struct comparable_distance_call_base
110 {
111 typedef typename geometry::default_comparable_distance_result
112 <
113 G1, G2
114 >::type result_type;
115
116 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const&)
117 {
118 return geometry::comparable_distance(g1, g2);
119 }
120 };
121
122 template
123 <
124 typename G1, typename G2, typename Strategy
125 >
126 struct comparable_distance_call_base<G1, G2, Strategy, point_tag, point_tag>
127 {
128 typedef typename geometry::comparable_distance_result
129 <
130 G1, G2,
131 typename Strategy::comparable_distance_point_point_strategy_type
132 >::type result_type;
133
134 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
135 {
136 return geometry::comparable_distance(g1, g2,
137 s.get_comparable_distance_point_point_strategy());
138 }
139 };
140
141 template
142 <
143 typename G1, typename G2, typename Strategy
144 >
145 struct comparable_distance_call_base<G1, G2, Strategy, point_tag, box_tag>
146 {
147 typedef typename geometry::comparable_distance_result
148 <
149 G1, G2,
150 typename Strategy::comparable_distance_point_box_strategy_type
151 >::type result_type;
152
153 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
154 {
155 return geometry::comparable_distance(g1, g2,
156 s.get_comparable_distance_point_box_strategy());
157 }
158 };
159
160 template
161 <
162 typename G1, typename G2, typename Strategy
163 >
164 struct comparable_distance_call_base<G1, G2, Strategy, segment_tag, point_tag>
165 {
166 typedef typename geometry::comparable_distance_result
167 <
168 G1, G2,
169 typename Strategy::comparable_distance_point_segment_strategy_type
170 >::type result_type;
171
172 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
173 {
174 return geometry::comparable_distance(g1, g2,
175 s.get_comparable_distance_point_segment_strategy());
176 }
177 };
178
179 template
180 <
181 typename G1, typename G2, typename Strategy
182 >
183 struct comparable_distance_call_base<G1, G2, Strategy, segment_tag, box_tag>
184 {
185 typedef typename geometry::comparable_distance_result
186 <
187 G1, G2,
188 typename Strategy::comparable_distance_segment_box_strategy_type
189 >::type result_type;
190
191 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
192 {
193 return geometry::comparable_distance(g1, g2,
194 s.get_comparable_distance_segment_box_strategy());
195 }
196 };
197
198 template
199 <
200 typename G1, typename G2, typename Strategy
201 >
202 struct comparable_distance_call_base<G1, G2, Strategy, segment_tag, segment_tag>
203 {
204 typedef typename geometry::comparable_distance_result
205 <
206 G1, G2,
207 typename Strategy::comparable_distance_point_segment_strategy_type
208 >::type result_type;
209
210 static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
211 {
212 return geometry::comparable_distance(g1, g2,
213 s.get_comparable_distance_point_segment_strategy());
214 }
215 };
216
217 template
218 <
219 typename G1, typename G2, typename Strategy
220 >
221 struct comparable_distance_call
222 : comparable_distance_call_base<G1, G2, Strategy>
223 {};
224
225 template
226 <
227 typename G1, typename G2
228 >
229 struct comparable_distance_call<G1, G2, default_strategy>
230 : comparable_distance_call_base<G1, G2, default_strategy, void, void>
231 {};
232
233 // ------------------------------------------------------------------ //
234 // calculate_distance
235 // ------------------------------------------------------------------ //
236
237 template <typename Predicate, typename Indexable, typename Strategy, typename Tag>
238 struct calculate_distance
239 {
240 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
241 "Invalid Predicate or Tag.",
242 Predicate, Indexable, Strategy, Tag);
243 };
244
245 // this handles nearest() with default Point parameter, to_nearest() and bounds
246 template <typename PointRelation, typename Indexable, typename Strategy, typename Tag>
247 struct calculate_distance< predicates::nearest<PointRelation>, Indexable, Strategy, Tag>
248 {
249 typedef detail::relation<PointRelation> relation;
250 typedef comparable_distance_call
251 <
252 typename relation::value_type,
253 Indexable,
254 Strategy
255 > call_type;
256 typedef typename call_type::result_type result_type;
257
258 static inline bool apply(predicates::nearest<PointRelation> const& p, Indexable const& i,
259 Strategy const& s, result_type & result)
260 {
261 result = call_type::apply(relation::value(p.point_or_relation), i, s);
262 return true;
263 }
264 };
265
266 template <typename Point, typename Indexable, typename Strategy>
267 struct calculate_distance< predicates::nearest< to_centroid<Point> >, Indexable, Strategy, value_tag>
268 {
269 typedef Point point_type;
270 typedef typename geometry::default_comparable_distance_result
271 <
272 point_type, Indexable
273 >::type result_type;
274
275 static inline bool apply(predicates::nearest< to_centroid<Point> > const& p, Indexable const& i,
276 Strategy const& , result_type & result)
277 {
278 result = index::detail::comparable_distance_centroid(p.point_or_relation.value, i);
279 return true;
280 }
281 };
282
283 template <typename Point, typename Indexable, typename Strategy>
284 struct calculate_distance< predicates::nearest< to_furthest<Point> >, Indexable, Strategy, value_tag>
285 {
286 typedef Point point_type;
287 typedef typename geometry::default_comparable_distance_result
288 <
289 point_type, Indexable
290 >::type result_type;
291
292 static inline bool apply(predicates::nearest< to_furthest<Point> > const& p, Indexable const& i,
293 Strategy const& , result_type & result)
294 {
295 result = index::detail::comparable_distance_far(p.point_or_relation.value, i);
296 return true;
297 }
298 };
299
300 template <typename SegmentOrLinestring, typename Indexable, typename Strategy, typename Tag>
301 struct calculate_distance< predicates::path<SegmentOrLinestring>, Indexable, Strategy, Tag>
302 {
303 typedef typename index::detail::default_path_intersection_distance_type<
304 Indexable, SegmentOrLinestring
305 >::type result_type;
306
307 static inline bool apply(predicates::path<SegmentOrLinestring> const& p, Indexable const& i,
308 Strategy const& , result_type & result)
309 {
310 return index::detail::path_intersection(i, p.geometry, result);
311 }
312 };
313
314 }}}} // namespace boost::geometry::index::detail
315
316 #endif // BOOST_GEOMETRY_INDEX_RTREE_DISTANCE_PREDICATES_HPP