]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
25 | namespace boost { namespace geometry { namespace index { | |
26 | ||
27 | /*! | |
28 | \brief Generate \c contains() predicate. | |
29 | ||
30 | Generate a predicate defining Value and Geometry relationship. | |
31 | Value will be returned by the query if <tt>bg::within(Geometry, Indexable)</tt> | |
32 | returns true. | |
33 | ||
34 | \par Example | |
35 | \verbatim | |
36 | bgi::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 | */ | |
45 | template <typename Geometry> inline | |
46 | detail::predicates::spatial_predicate<Geometry, detail::predicates::contains_tag, false> | |
47 | contains(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 | ||
60 | Generate a predicate defining Value and Geometry relationship. | |
61 | Value will be returned by the query if <tt>bg::covered_by(Indexable, Geometry)</tt> | |
62 | returns true. | |
63 | ||
64 | \par Example | |
65 | \verbatim | |
66 | bgi::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 | */ | |
75 | template <typename Geometry> inline | |
76 | detail::predicates::spatial_predicate<Geometry, detail::predicates::covered_by_tag, false> | |
77 | covered_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 | ||
90 | Generate a predicate defining Value and Geometry relationship. | |
91 | Value will be returned by the query if <tt>bg::covered_by(Geometry, Indexable)</tt> | |
92 | returns true. | |
93 | ||
94 | \par Example | |
95 | \verbatim | |
96 | bgi::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 | */ | |
105 | template <typename Geometry> inline | |
106 | detail::predicates::spatial_predicate<Geometry, detail::predicates::covers_tag, false> | |
107 | covers(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 | ||
120 | Generate a predicate defining Value and Geometry relationship. | |
121 | Value will be returned by the query if <tt>bg::disjoint(Indexable, Geometry)</tt> | |
122 | returns true. | |
123 | ||
124 | \par Example | |
125 | \verbatim | |
126 | bgi::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 | */ | |
135 | template <typename Geometry> inline | |
136 | detail::predicates::spatial_predicate<Geometry, detail::predicates::disjoint_tag, false> | |
137 | disjoint(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 | ||
150 | Generate a predicate defining Value and Geometry relationship. | |
151 | Value will be returned by the query if <tt>bg::intersects(Indexable, Geometry)</tt> | |
152 | returns true. | |
153 | ||
154 | \par Example | |
155 | \verbatim | |
156 | bgi::query(spatial_index, bgi::intersects(box), std::back_inserter(result)); | |
157 | bgi::query(spatial_index, bgi::intersects(ring), std::back_inserter(result)); | |
158 | bgi::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 | */ | |
167 | template <typename Geometry> inline | |
168 | detail::predicates::spatial_predicate<Geometry, detail::predicates::intersects_tag, false> | |
169 | intersects(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 | ||
182 | Generate a predicate defining Value and Geometry relationship. | |
183 | Value will be returned by the query if <tt>bg::overlaps(Indexable, Geometry)</tt> | |
184 | returns true. | |
185 | ||
186 | \par Example | |
187 | \verbatim | |
188 | bgi::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 | */ | |
197 | template <typename Geometry> inline | |
198 | detail::predicates::spatial_predicate<Geometry, detail::predicates::overlaps_tag, false> | |
199 | overlaps(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 | ||
214 | Generate a predicate defining Value and Geometry relationship. | |
215 | Value will be returned by the query if <tt>bg::touches(Indexable, Geometry)</tt> | |
216 | returns true. | |
217 | ||
218 | \ingroup predicates | |
219 | ||
220 | \tparam Geometry The Geometry type. | |
221 | ||
222 | \param g The Geometry object. | |
223 | */ | |
224 | template <typename Geometry> inline | |
225 | detail::predicates::spatial_predicate<Geometry, detail::predicates::touches_tag, false> | |
226 | touches(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 | ||
241 | Generate a predicate defining Value and Geometry relationship. | |
242 | Value will be returned by the query if <tt>bg::within(Indexable, Geometry)</tt> | |
243 | returns true. | |
244 | ||
245 | \par Example | |
246 | \verbatim | |
247 | bgi::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 | */ | |
256 | template <typename Geometry> inline | |
257 | detail::predicates::spatial_predicate<Geometry, detail::predicates::within_tag, false> | |
258 | within(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 | ||
271 | A wrapper around user-defined UnaryPredicate checking if Value should be returned by spatial query. | |
272 | ||
273 | \par Example | |
274 | \verbatim | |
275 | bool is_red(Value const& v) { return v.is_red(); } | |
276 | ||
277 | struct is_red_o { | |
278 | template <typename Value> bool operator()(Value const& v) { return v.is_red(); } | |
279 | } | |
280 | ||
281 | // ... | |
282 | ||
283 | rt.query(index::intersects(box) && index::satisfies(is_red), | |
284 | std::back_inserter(result)); | |
285 | ||
286 | rt.query(index::intersects(box) && index::satisfies(is_red_o()), | |
287 | std::back_inserter(result)); | |
288 | ||
289 | #ifndef BOOST_NO_CXX11_LAMBDAS | |
290 | rt.query(index::intersects(box) && index::satisfies([](Value const& v) { return v.is_red(); }), | |
291 | std::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 | */ | |
301 | template <typename UnaryPredicate> inline | |
302 | detail::predicates::satisfies<UnaryPredicate, false> | |
303 | satisfies(UnaryPredicate const& pred) | |
304 | { | |
305 | return detail::predicates::satisfies<UnaryPredicate, false>(pred); | |
306 | } | |
307 | ||
308 | /*! | |
309 | \brief Generate nearest() predicate. | |
310 | ||
311 | When 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 | |
313 | and the maximum number of \c Values that should be returned. Internally | |
314 | boost::geometry::comparable_distance() is used to perform the calculation. | |
315 | ||
316 | \par Example | |
317 | \verbatim | |
318 | bgi::query(spatial_index, bgi::nearest(pt, 5), std::back_inserter(result)); | |
319 | bgi::query(spatial_index, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result)); | |
320 | bgi::query(spatial_index, bgi::nearest(box, 5), std::back_inserter(result)); | |
321 | \endverbatim | |
322 | ||
323 | \warning | |
324 | Only 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 | */ | |
331 | template <typename Geometry> inline | |
332 | detail::predicates::nearest<Geometry> | |
333 | nearest(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 | ||
343 | When path predicate is passed to the query, the returned values are k values along the path closest to | |
344 | its begin. \c path() predicate takes a \c Segment or a \c Linestring defining the path and the maximum | |
345 | number of \c Values that should be returned. | |
346 | ||
347 | \par Example | |
348 | \verbatim | |
349 | bgi::query(spatial_index, bgi::path(segment, 5), std::back_inserter(result)); | |
350 | bgi::query(spatial_index, bgi::path(linestring, 5) && bgi::intersects(box), std::back_inserter(result)); | |
351 | \endverbatim | |
352 | ||
353 | \warning | |
354 | Only 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 | */ | |
361 | template <typename SegmentOrLinestring> inline | |
362 | detail::predicates::path<SegmentOrLinestring> | |
363 | path(SegmentOrLinestring const& linestring, unsigned k) | |
364 | { | |
365 | return detail::predicates::path<SegmentOrLinestring>(linestring, k); | |
366 | } | |
367 | ||
368 | #endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL | |
369 | ||
370 | namespace detail { namespace predicates { | |
371 | ||
372 | // operator! generators | |
373 | ||
374 | template <typename Fun, bool Negated> inline | |
375 | satisfies<Fun, !Negated> | |
376 | operator!(satisfies<Fun, Negated> const& p) | |
377 | { | |
378 | return satisfies<Fun, !Negated>(p); | |
379 | } | |
380 | ||
381 | template <typename Geometry, typename Tag, bool Negated> inline | |
382 | spatial_predicate<Geometry, Tag, !Negated> | |
383 | operator!(spatial_predicate<Geometry, Tag, Negated> const& p) | |
384 | { | |
385 | return spatial_predicate<Geometry, Tag, !Negated>(p.geometry); | |
386 | } | |
387 | ||
388 | // operator&& generators | |
389 | ||
390 | template <typename Pred1, typename Pred2> inline | |
391 | boost::tuples::cons< | |
392 | Pred1, | |
393 | boost::tuples::cons<Pred2, boost::tuples::null_type> | |
394 | > | |
395 | operator&&(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 | ||
406 | template <typename Head, typename Tail, typename Pred> inline | |
407 | typename tuples::push_back< | |
408 | boost::tuples::cons<Head, Tail>, Pred | |
409 | >::type | |
410 | operator&&(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 |