predicates.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. // Boost.Geometry Index
  2. //
  3. // Spatial query predicates
  4. //
  5. // Copyright (c) 2011-2013 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. #ifndef BOOST_GEOMETRY_INDEX_PREDICATES_HPP
  11. #define BOOST_GEOMETRY_INDEX_PREDICATES_HPP
  12. #include <utility>
  13. #include <boost/tuple/tuple.hpp>
  14. #include <boost/mpl/assert.hpp>
  15. #include <boost/geometry/index/detail/predicates.hpp>
  16. #include <boost/geometry/index/detail/tuples.hpp>
  17. /*!
  18. \defgroup predicates Predicates (boost::geometry::index::)
  19. */
  20. namespace boost { namespace geometry { namespace index {
  21. /*!
  22. \brief Generate \c contains() predicate.
  23. Generate a predicate defining Value and Geometry relationship.
  24. Value will be returned by the query if <tt>bg::within(Geometry, Indexable)</tt>
  25. returns true.
  26. \par Example
  27. \verbatim
  28. bgi::query(spatial_index, bgi::contains(box), std::back_inserter(result));
  29. \endverbatim
  30. \ingroup predicates
  31. \tparam Geometry The Geometry type.
  32. \param g The Geometry object.
  33. */
  34. template <typename Geometry> inline
  35. detail::spatial_predicate<Geometry, detail::contains_tag, false>
  36. contains(Geometry const& g)
  37. {
  38. return detail::spatial_predicate<Geometry, detail::contains_tag, false>(g);
  39. }
  40. /*!
  41. \brief Generate \c covered_by() predicate.
  42. Generate a predicate defining Value and Geometry relationship.
  43. Value will be returned by the query if <tt>bg::covered_by(Indexable, Geometry)</tt>
  44. returns true.
  45. \par Example
  46. \verbatim
  47. bgi::query(spatial_index, bgi::covered_by(box), std::back_inserter(result));
  48. \endverbatim
  49. \ingroup predicates
  50. \tparam Geometry The Geometry type.
  51. \param g The Geometry object.
  52. */
  53. template <typename Geometry> inline
  54. detail::spatial_predicate<Geometry, detail::covered_by_tag, false>
  55. covered_by(Geometry const& g)
  56. {
  57. return detail::spatial_predicate<Geometry, detail::covered_by_tag, false>(g);
  58. }
  59. /*!
  60. \brief Generate \c covers() predicate.
  61. Generate a predicate defining Value and Geometry relationship.
  62. Value will be returned by the query if <tt>bg::covered_by(Geometry, Indexable)</tt>
  63. returns true.
  64. \par Example
  65. \verbatim
  66. bgi::query(spatial_index, bgi::covers(box), std::back_inserter(result));
  67. \endverbatim
  68. \ingroup predicates
  69. \tparam Geometry The Geometry type.
  70. \param g The Geometry object.
  71. */
  72. template <typename Geometry> inline
  73. detail::spatial_predicate<Geometry, detail::covers_tag, false>
  74. covers(Geometry const& g)
  75. {
  76. return detail::spatial_predicate<Geometry, detail::covers_tag, false>(g);
  77. }
  78. /*!
  79. \brief Generate \c disjoint() predicate.
  80. Generate a predicate defining Value and Geometry relationship.
  81. Value will be returned by the query if <tt>bg::disjoint(Indexable, Geometry)</tt>
  82. returns true.
  83. \par Example
  84. \verbatim
  85. bgi::query(spatial_index, bgi::disjoint(box), std::back_inserter(result));
  86. \endverbatim
  87. \ingroup predicates
  88. \tparam Geometry The Geometry type.
  89. \param g The Geometry object.
  90. */
  91. template <typename Geometry> inline
  92. detail::spatial_predicate<Geometry, detail::disjoint_tag, false>
  93. disjoint(Geometry const& g)
  94. {
  95. return detail::spatial_predicate<Geometry, detail::disjoint_tag, false>(g);
  96. }
  97. /*!
  98. \brief Generate \c intersects() predicate.
  99. Generate a predicate defining Value and Geometry relationship.
  100. Value will be returned by the query if <tt>bg::intersects(Indexable, Geometry)</tt>
  101. returns true.
  102. \par Example
  103. \verbatim
  104. bgi::query(spatial_index, bgi::intersects(box), std::back_inserter(result));
  105. bgi::query(spatial_index, bgi::intersects(ring), std::back_inserter(result));
  106. bgi::query(spatial_index, bgi::intersects(polygon), std::back_inserter(result));
  107. \endverbatim
  108. \ingroup predicates
  109. \tparam Geometry The Geometry type.
  110. \param g The Geometry object.
  111. */
  112. template <typename Geometry> inline
  113. detail::spatial_predicate<Geometry, detail::intersects_tag, false>
  114. intersects(Geometry const& g)
  115. {
  116. return detail::spatial_predicate<Geometry, detail::intersects_tag, false>(g);
  117. }
  118. /*!
  119. \brief Generate \c overlaps() predicate.
  120. Generate a predicate defining Value and Geometry relationship.
  121. Value will be returned by the query if <tt>bg::overlaps(Indexable, Geometry)</tt>
  122. returns true.
  123. \par Example
  124. \verbatim
  125. bgi::query(spatial_index, bgi::overlaps(box), std::back_inserter(result));
  126. \endverbatim
  127. \ingroup predicates
  128. \tparam Geometry The Geometry type.
  129. \param g The Geometry object.
  130. */
  131. template <typename Geometry> inline
  132. detail::spatial_predicate<Geometry, detail::overlaps_tag, false>
  133. overlaps(Geometry const& g)
  134. {
  135. return detail::spatial_predicate<Geometry, detail::overlaps_tag, false>(g);
  136. }
  137. #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
  138. /*!
  139. \brief Generate \c touches() predicate.
  140. Generate a predicate defining Value and Geometry relationship.
  141. Value will be returned by the query if <tt>bg::touches(Indexable, Geometry)</tt>
  142. returns true.
  143. \ingroup predicates
  144. \tparam Geometry The Geometry type.
  145. \param g The Geometry object.
  146. */
  147. template <typename Geometry> inline
  148. detail::spatial_predicate<Geometry, detail::touches_tag, false>
  149. touches(Geometry const& g)
  150. {
  151. return detail::spatial_predicate<Geometry, detail::touches_tag, false>(g);
  152. }
  153. #endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
  154. /*!
  155. \brief Generate \c within() predicate.
  156. Generate a predicate defining Value and Geometry relationship.
  157. Value will be returned by the query if <tt>bg::within(Indexable, Geometry)</tt>
  158. returns true.
  159. \par Example
  160. \verbatim
  161. bgi::query(spatial_index, bgi::within(box), std::back_inserter(result));
  162. \endverbatim
  163. \ingroup predicates
  164. \tparam Geometry The Geometry type.
  165. \param g The Geometry object.
  166. */
  167. template <typename Geometry> inline
  168. detail::spatial_predicate<Geometry, detail::within_tag, false>
  169. within(Geometry const& g)
  170. {
  171. return detail::spatial_predicate<Geometry, detail::within_tag, false>(g);
  172. }
  173. /*!
  174. \brief Generate satisfies() predicate.
  175. A wrapper around user-defined UnaryPredicate checking if Value should be returned by spatial query.
  176. \par Example
  177. \verbatim
  178. bool is_red(Value const& v) { return v.is_red(); }
  179. struct is_red_o {
  180. template <typename Value> bool operator()(Value const& v) { return v.is_red(); }
  181. }
  182. // ...
  183. rt.query(index::intersects(box) && index::satisfies(is_red),
  184. std::back_inserter(result));
  185. rt.query(index::intersects(box) && index::satisfies(is_red_o()),
  186. std::back_inserter(result));
  187. #ifndef BOOST_NO_CXX11_LAMBDAS
  188. rt.query(index::intersects(box) && index::satisfies([](Value const& v) { return v.is_red(); }),
  189. std::back_inserter(result));
  190. #endif
  191. \endverbatim
  192. \ingroup predicates
  193. \tparam UnaryPredicate A type of unary predicate function or function object.
  194. \param pred The unary predicate function or function object.
  195. */
  196. template <typename UnaryPredicate> inline
  197. detail::satisfies<UnaryPredicate, false>
  198. satisfies(UnaryPredicate const& pred)
  199. {
  200. return detail::satisfies<UnaryPredicate, false>(pred);
  201. }
  202. /*!
  203. \brief Generate nearest() predicate.
  204. When nearest predicate is passed to the query, k-nearest neighbour search will be performed.
  205. \c nearest() predicate takes a \c Point from which distance to \c Values is calculated
  206. and the maximum number of \c Values that should be returned.
  207. \par Example
  208. \verbatim
  209. bgi::query(spatial_index, bgi::nearest(pt, 5), std::back_inserter(result));
  210. bgi::query(spatial_index, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
  211. \endverbatim
  212. \warning
  213. Only one \c nearest() predicate may be used in a query.
  214. \ingroup predicates
  215. \param point The point from which distance is calculated.
  216. \param k The maximum number of values to return.
  217. */
  218. template <typename Point> inline
  219. detail::nearest<Point>
  220. nearest(Point const& point, unsigned k)
  221. {
  222. return detail::nearest<Point>(point, k);
  223. }
  224. #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
  225. /*!
  226. \brief Generate path() predicate.
  227. When path predicate is passed to the query, the returned values are k values along the path closest to
  228. its begin. \c path() predicate takes a \c Segment or a \c Linestring defining the path and the maximum
  229. number of \c Values that should be returned.
  230. \par Example
  231. \verbatim
  232. bgi::query(spatial_index, bgi::path(segment, 5), std::back_inserter(result));
  233. bgi::query(spatial_index, bgi::path(linestring, 5) && bgi::intersects(box), std::back_inserter(result));
  234. \endverbatim
  235. \warning
  236. Only one distance predicate (\c nearest() or \c path()) may be used in a query.
  237. \ingroup predicates
  238. \param linestring The path along which distance is calculated.
  239. \param k The maximum number of values to return.
  240. */
  241. template <typename SegmentOrLinestring> inline
  242. detail::path<SegmentOrLinestring>
  243. path(SegmentOrLinestring const& linestring, unsigned k)
  244. {
  245. return detail::path<SegmentOrLinestring>(linestring, k);
  246. }
  247. #endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
  248. namespace detail {
  249. // operator! generators
  250. template <typename Fun, bool Negated> inline
  251. satisfies<Fun, !Negated>
  252. operator!(satisfies<Fun, Negated> const& p)
  253. {
  254. return satisfies<Fun, !Negated>(p);
  255. }
  256. template <typename Geometry, typename Tag, bool Negated> inline
  257. spatial_predicate<Geometry, Tag, !Negated>
  258. operator!(spatial_predicate<Geometry, Tag, Negated> const& p)
  259. {
  260. return spatial_predicate<Geometry, Tag, !Negated>(p.geometry);
  261. }
  262. // operator&& generators
  263. template <typename Pred1, typename Pred2> inline
  264. boost::tuples::cons<
  265. Pred1,
  266. boost::tuples::cons<Pred2, boost::tuples::null_type>
  267. >
  268. operator&&(Pred1 const& p1, Pred2 const& p2)
  269. {
  270. /*typedef typename boost::mpl::if_c<is_predicate<Pred1>::value, Pred1, Pred1 const&>::type stored1;
  271. typedef typename boost::mpl::if_c<is_predicate<Pred2>::value, Pred2, Pred2 const&>::type stored2;*/
  272. namespace bt = boost::tuples;
  273. return
  274. bt::cons< Pred1, bt::cons<Pred2, bt::null_type> >
  275. ( p1, bt::cons<Pred2, bt::null_type>(p2, bt::null_type()) );
  276. }
  277. template <typename Head, typename Tail, typename Pred> inline
  278. typename tuples::push_back_impl<
  279. boost::tuples::cons<Head, Tail>,
  280. Pred,
  281. 0,
  282. boost::tuples::length<boost::tuples::cons<Head, Tail> >::value
  283. >::type
  284. operator&&(boost::tuples::cons<Head, Tail> const& t, Pred const& p)
  285. {
  286. //typedef typename boost::mpl::if_c<is_predicate<Pred>::value, Pred, Pred const&>::type stored;
  287. namespace bt = boost::tuples;
  288. return
  289. tuples::push_back_impl<
  290. bt::cons<Head, Tail>, Pred, 0, bt::length< bt::cons<Head, Tail> >::value
  291. >::apply(t, p);
  292. }
  293. } // namespace detail
  294. }}} // namespace boost::geometry::index
  295. #endif // BOOST_GEOMETRY_INDEX_PREDICATES_HPP