]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry Index |
2 | // | |
3 | // Spatial query predicates | |
4 | // | |
11fdf7f2 | 5 | // Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland. |
7c673cae | 6 | // |
20effc67 TL |
7 | // This file was modified by Oracle on 2019-2020. |
8 | // Modifications copyright (c) 2019-2020 Oracle and/or its affiliates. | |
f67539c2 TL |
9 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle |
10 | // | |
7c673cae FG |
11 | // Use, modification and distribution is subject to the Boost Software License, |
12 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
13 | // http://www.boost.org/LICENSE_1_0.txt) | |
14 | ||
15 | #ifndef BOOST_GEOMETRY_INDEX_PREDICATES_HPP | |
16 | #define BOOST_GEOMETRY_INDEX_PREDICATES_HPP | |
17 | ||
7c673cae | 18 | #include <boost/geometry/index/detail/predicates.hpp> |
f67539c2 | 19 | #include <boost/geometry/util/tuples.hpp> |
7c673cae FG |
20 | |
21 | /*! | |
22 | \defgroup predicates Predicates (boost::geometry::index::) | |
23 | */ | |
24 | ||
25 | namespace boost { namespace geometry { namespace index { | |
26 | ||
27 | /*! | |
28 | \brief Generate \c contains() predicate. | |
29 | ||
11fdf7f2 TL |
30 | Generate a predicate defining Value and Geometry relationship. With this |
31 | predicate query returns indexed Values that contain passed Geometry. | |
32 | Value is returned by the query if <tt>bg::within(Geometry, Indexable)</tt> | |
33 | returns <tt>true</tt>. | |
7c673cae FG |
34 | |
35 | \par Example | |
36 | \verbatim | |
37 | bgi::query(spatial_index, bgi::contains(box), std::back_inserter(result)); | |
38 | \endverbatim | |
39 | ||
40 | \ingroup predicates | |
41 | ||
42 | \tparam Geometry The Geometry type. | |
43 | ||
44 | \param g The Geometry object. | |
45 | */ | |
46 | template <typename Geometry> inline | |
47 | detail::predicates::spatial_predicate<Geometry, detail::predicates::contains_tag, false> | |
48 | contains(Geometry const& g) | |
49 | { | |
50 | return detail::predicates::spatial_predicate | |
51 | < | |
52 | Geometry, | |
53 | detail::predicates::contains_tag, | |
54 | false | |
55 | >(g); | |
56 | } | |
57 | ||
58 | /*! | |
59 | \brief Generate \c covered_by() predicate. | |
60 | ||
11fdf7f2 TL |
61 | Generate a predicate defining Value and Geometry relationship. With this |
62 | predicate query returns indexed Values that are covered by passed Geometry. | |
63 | Value is returned by the query if <tt>bg::covered_by(Indexable, Geometry)</tt> | |
64 | returns <tt>true</tt>. | |
7c673cae FG |
65 | |
66 | \par Example | |
67 | \verbatim | |
68 | bgi::query(spatial_index, bgi::covered_by(box), std::back_inserter(result)); | |
69 | \endverbatim | |
70 | ||
71 | \ingroup predicates | |
72 | ||
73 | \tparam Geometry The Geometry type. | |
74 | ||
75 | \param g The Geometry object. | |
76 | */ | |
77 | template <typename Geometry> inline | |
78 | detail::predicates::spatial_predicate<Geometry, detail::predicates::covered_by_tag, false> | |
79 | covered_by(Geometry const& g) | |
80 | { | |
81 | return detail::predicates::spatial_predicate | |
82 | < | |
83 | Geometry, | |
84 | detail::predicates::covered_by_tag, | |
85 | false | |
86 | >(g); | |
87 | } | |
88 | ||
89 | /*! | |
90 | \brief Generate \c covers() predicate. | |
91 | ||
11fdf7f2 TL |
92 | Generate a predicate defining Value and Geometry relationship. With this |
93 | predicate query returns indexed Values that cover passed Geometry. | |
94 | Value is returned by the query if <tt>bg::covered_by(Geometry, Indexable)</tt> | |
95 | returns <tt>true</tt>. | |
7c673cae FG |
96 | |
97 | \par Example | |
98 | \verbatim | |
99 | bgi::query(spatial_index, bgi::covers(box), std::back_inserter(result)); | |
100 | \endverbatim | |
101 | ||
102 | \ingroup predicates | |
103 | ||
104 | \tparam Geometry The Geometry type. | |
105 | ||
106 | \param g The Geometry object. | |
107 | */ | |
108 | template <typename Geometry> inline | |
109 | detail::predicates::spatial_predicate<Geometry, detail::predicates::covers_tag, false> | |
110 | covers(Geometry const& g) | |
111 | { | |
112 | return detail::predicates::spatial_predicate | |
113 | < | |
114 | Geometry, | |
115 | detail::predicates::covers_tag, | |
116 | false | |
117 | >(g); | |
118 | } | |
119 | ||
120 | /*! | |
121 | \brief Generate \c disjoint() predicate. | |
122 | ||
11fdf7f2 TL |
123 | Generate a predicate defining Value and Geometry relationship. With this |
124 | predicate query returns indexed Values that are disjoint with passed Geometry. | |
125 | Value is returned by the query if <tt>bg::disjoint(Indexable, Geometry)</tt> | |
126 | returns <tt>true</tt>. | |
7c673cae FG |
127 | |
128 | \par Example | |
129 | \verbatim | |
130 | bgi::query(spatial_index, bgi::disjoint(box), std::back_inserter(result)); | |
131 | \endverbatim | |
132 | ||
133 | \ingroup predicates | |
134 | ||
135 | \tparam Geometry The Geometry type. | |
136 | ||
137 | \param g The Geometry object. | |
138 | */ | |
139 | template <typename Geometry> inline | |
140 | detail::predicates::spatial_predicate<Geometry, detail::predicates::disjoint_tag, false> | |
141 | disjoint(Geometry const& g) | |
142 | { | |
143 | return detail::predicates::spatial_predicate | |
144 | < | |
145 | Geometry, | |
146 | detail::predicates::disjoint_tag, | |
147 | false | |
148 | >(g); | |
149 | } | |
150 | ||
151 | /*! | |
152 | \brief Generate \c intersects() predicate. | |
153 | ||
11fdf7f2 TL |
154 | Generate a predicate defining Value and Geometry relationship. With this |
155 | predicate query returns indexed Values that intersect passed Geometry. | |
156 | Value is returned by the query if <tt>bg::intersects(Indexable, Geometry)</tt> | |
157 | returns <tt>true</tt>. | |
7c673cae FG |
158 | |
159 | \par Example | |
160 | \verbatim | |
161 | bgi::query(spatial_index, bgi::intersects(box), std::back_inserter(result)); | |
162 | bgi::query(spatial_index, bgi::intersects(ring), std::back_inserter(result)); | |
163 | bgi::query(spatial_index, bgi::intersects(polygon), std::back_inserter(result)); | |
164 | \endverbatim | |
165 | ||
166 | \ingroup predicates | |
167 | ||
168 | \tparam Geometry The Geometry type. | |
169 | ||
170 | \param g The Geometry object. | |
171 | */ | |
172 | template <typename Geometry> inline | |
173 | detail::predicates::spatial_predicate<Geometry, detail::predicates::intersects_tag, false> | |
174 | intersects(Geometry const& g) | |
175 | { | |
176 | return detail::predicates::spatial_predicate | |
177 | < | |
178 | Geometry, | |
179 | detail::predicates::intersects_tag, | |
180 | false | |
181 | >(g); | |
182 | } | |
183 | ||
184 | /*! | |
185 | \brief Generate \c overlaps() predicate. | |
186 | ||
11fdf7f2 TL |
187 | Generate a predicate defining Value and Geometry relationship. With this |
188 | predicate query returns indexed Values that overlap passed Geometry. | |
189 | Value is returned by the query if <tt>bg::overlaps(Indexable, Geometry)</tt> | |
190 | returns <tt>true</tt>. | |
7c673cae FG |
191 | |
192 | \par Example | |
193 | \verbatim | |
194 | bgi::query(spatial_index, bgi::overlaps(box), std::back_inserter(result)); | |
195 | \endverbatim | |
196 | ||
197 | \ingroup predicates | |
198 | ||
199 | \tparam Geometry The Geometry type. | |
200 | ||
201 | \param g The Geometry object. | |
202 | */ | |
203 | template <typename Geometry> inline | |
204 | detail::predicates::spatial_predicate<Geometry, detail::predicates::overlaps_tag, false> | |
205 | overlaps(Geometry const& g) | |
206 | { | |
207 | return detail::predicates::spatial_predicate | |
208 | < | |
209 | Geometry, | |
210 | detail::predicates::overlaps_tag, | |
211 | false | |
212 | >(g); | |
213 | } | |
214 | ||
215 | #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL | |
216 | ||
217 | /*! | |
218 | \brief Generate \c touches() predicate. | |
219 | ||
11fdf7f2 TL |
220 | Generate a predicate defining Value and Geometry relationship. With this |
221 | predicate query returns indexed Values that touch passed Geometry. | |
222 | Value is returned by the query if <tt>bg::touches(Indexable, Geometry)</tt> | |
223 | returns <tt>true</tt>. | |
7c673cae FG |
224 | |
225 | \ingroup predicates | |
226 | ||
227 | \tparam Geometry The Geometry type. | |
228 | ||
229 | \param g The Geometry object. | |
230 | */ | |
231 | template <typename Geometry> inline | |
232 | detail::predicates::spatial_predicate<Geometry, detail::predicates::touches_tag, false> | |
233 | touches(Geometry const& g) | |
234 | { | |
235 | return detail::predicates::spatial_predicate | |
236 | < | |
237 | Geometry, | |
238 | detail::predicates::touches_tag, | |
239 | false | |
240 | >(g); | |
241 | } | |
242 | ||
243 | #endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL | |
244 | ||
245 | /*! | |
246 | \brief Generate \c within() predicate. | |
247 | ||
11fdf7f2 TL |
248 | Generate a predicate defining Value and Geometry relationship. With this |
249 | predicate query returns indexed Values that are within passed Geometry. | |
250 | Value is returned by the query if <tt>bg::within(Indexable, Geometry)</tt> | |
251 | returns <tt>true</tt>. | |
7c673cae FG |
252 | |
253 | \par Example | |
254 | \verbatim | |
255 | bgi::query(spatial_index, bgi::within(box), std::back_inserter(result)); | |
256 | \endverbatim | |
257 | ||
258 | \ingroup predicates | |
259 | ||
260 | \tparam Geometry The Geometry type. | |
261 | ||
262 | \param g The Geometry object. | |
263 | */ | |
264 | template <typename Geometry> inline | |
265 | detail::predicates::spatial_predicate<Geometry, detail::predicates::within_tag, false> | |
266 | within(Geometry const& g) | |
267 | { | |
268 | return detail::predicates::spatial_predicate | |
269 | < | |
270 | Geometry, | |
271 | detail::predicates::within_tag, | |
272 | false | |
273 | >(g); | |
274 | } | |
275 | ||
276 | /*! | |
277 | \brief Generate satisfies() predicate. | |
278 | ||
279 | A wrapper around user-defined UnaryPredicate checking if Value should be returned by spatial query. | |
280 | ||
281 | \par Example | |
282 | \verbatim | |
283 | bool is_red(Value const& v) { return v.is_red(); } | |
284 | ||
285 | struct is_red_o { | |
286 | template <typename Value> bool operator()(Value const& v) { return v.is_red(); } | |
287 | } | |
288 | ||
289 | // ... | |
290 | ||
291 | rt.query(index::intersects(box) && index::satisfies(is_red), | |
292 | std::back_inserter(result)); | |
293 | ||
294 | rt.query(index::intersects(box) && index::satisfies(is_red_o()), | |
295 | std::back_inserter(result)); | |
296 | ||
297 | #ifndef BOOST_NO_CXX11_LAMBDAS | |
298 | rt.query(index::intersects(box) && index::satisfies([](Value const& v) { return v.is_red(); }), | |
299 | std::back_inserter(result)); | |
300 | #endif | |
301 | \endverbatim | |
302 | ||
303 | \ingroup predicates | |
304 | ||
305 | \tparam UnaryPredicate A type of unary predicate function or function object. | |
306 | ||
307 | \param pred The unary predicate function or function object. | |
308 | */ | |
309 | template <typename UnaryPredicate> inline | |
310 | detail::predicates::satisfies<UnaryPredicate, false> | |
311 | satisfies(UnaryPredicate const& pred) | |
312 | { | |
313 | return detail::predicates::satisfies<UnaryPredicate, false>(pred); | |
314 | } | |
315 | ||
316 | /*! | |
317 | \brief Generate nearest() predicate. | |
318 | ||
319 | When nearest predicate is passed to the query, k-nearest neighbour search will be performed. | |
320 | \c nearest() predicate takes a \c Geometry from which distances to \c Values are calculated | |
321 | and the maximum number of \c Values that should be returned. Internally | |
322 | boost::geometry::comparable_distance() is used to perform the calculation. | |
323 | ||
324 | \par Example | |
325 | \verbatim | |
326 | bgi::query(spatial_index, bgi::nearest(pt, 5), std::back_inserter(result)); | |
327 | bgi::query(spatial_index, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result)); | |
328 | bgi::query(spatial_index, bgi::nearest(box, 5), std::back_inserter(result)); | |
329 | \endverbatim | |
330 | ||
331 | \warning | |
332 | Only one \c nearest() predicate may be used in a query. | |
333 | ||
334 | \ingroup predicates | |
335 | ||
336 | \param geometry The geometry from which distance is calculated. | |
337 | \param k The maximum number of values to return. | |
338 | */ | |
339 | template <typename Geometry> inline | |
340 | detail::predicates::nearest<Geometry> | |
341 | nearest(Geometry const& geometry, unsigned k) | |
342 | { | |
343 | return detail::predicates::nearest<Geometry>(geometry, k); | |
344 | } | |
345 | ||
346 | #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL | |
347 | ||
348 | /*! | |
349 | \brief Generate path() predicate. | |
350 | ||
351 | When path predicate is passed to the query, the returned values are k values along the path closest to | |
352 | its begin. \c path() predicate takes a \c Segment or a \c Linestring defining the path and the maximum | |
353 | number of \c Values that should be returned. | |
354 | ||
355 | \par Example | |
356 | \verbatim | |
357 | bgi::query(spatial_index, bgi::path(segment, 5), std::back_inserter(result)); | |
358 | bgi::query(spatial_index, bgi::path(linestring, 5) && bgi::intersects(box), std::back_inserter(result)); | |
359 | \endverbatim | |
360 | ||
361 | \warning | |
362 | Only one distance predicate (\c nearest() or \c path()) may be used in a query. | |
363 | ||
364 | \ingroup predicates | |
365 | ||
366 | \param linestring The path along which distance is calculated. | |
367 | \param k The maximum number of values to return. | |
368 | */ | |
369 | template <typename SegmentOrLinestring> inline | |
370 | detail::predicates::path<SegmentOrLinestring> | |
371 | path(SegmentOrLinestring const& linestring, unsigned k) | |
372 | { | |
373 | return detail::predicates::path<SegmentOrLinestring>(linestring, k); | |
374 | } | |
375 | ||
376 | #endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL | |
377 | ||
378 | namespace detail { namespace predicates { | |
379 | ||
380 | // operator! generators | |
381 | ||
382 | template <typename Fun, bool Negated> inline | |
383 | satisfies<Fun, !Negated> | |
384 | operator!(satisfies<Fun, Negated> const& p) | |
385 | { | |
386 | return satisfies<Fun, !Negated>(p); | |
387 | } | |
388 | ||
389 | template <typename Geometry, typename Tag, bool Negated> inline | |
390 | spatial_predicate<Geometry, Tag, !Negated> | |
391 | operator!(spatial_predicate<Geometry, Tag, Negated> const& p) | |
392 | { | |
393 | return spatial_predicate<Geometry, Tag, !Negated>(p.geometry); | |
394 | } | |
395 | ||
396 | // operator&& generators | |
397 | ||
398 | template <typename Pred1, typename Pred2> inline | |
20effc67 | 399 | std::tuple<Pred1, Pred2> |
7c673cae FG |
400 | operator&&(Pred1 const& p1, Pred2 const& p2) |
401 | { | |
20effc67 TL |
402 | /*typedef std::conditional_t<is_predicate<Pred1>::value, Pred1, Pred1 const&> stored1; |
403 | typedef std::conditional_t<is_predicate<Pred2>::value, Pred2, Pred2 const&> stored2;*/ | |
404 | return std::tuple<Pred1, Pred2>(p1, p2); | |
7c673cae FG |
405 | } |
406 | ||
20effc67 TL |
407 | template <typename ...Preds, typename Pred> inline |
408 | typename geometry::tuples::push_back | |
409 | < | |
410 | std::tuple<Preds...>, Pred | |
411 | >::type | |
412 | operator&&(std::tuple<Preds...> const& t, Pred const& p) | |
7c673cae | 413 | { |
20effc67 TL |
414 | //typedef std::conditional_t<is_predicate<Pred>::value, Pred, Pred const&> stored; |
415 | return geometry::tuples::push_back | |
416 | < | |
417 | std::tuple<Preds...>, Pred | |
418 | >::apply(t, p); | |
7c673cae FG |
419 | } |
420 | ||
421 | }} // namespace detail::predicates | |
422 | ||
423 | }}} // namespace boost::geometry::index | |
424 | ||
425 | #endif // BOOST_GEOMETRY_INDEX_PREDICATES_HPP |