predicates.hpp 12 KB

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