predicates.hpp 12 KB

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