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