predicates.hpp 12 KB

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