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

source code of boost/boost/geometry/index/predicates.hpp