query.qbk 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. [/============================================================================
  2. Boost.Geometry Index
  3. Copyright (c) 2011-2017 Adam Wulkiewicz.
  4. Use, modification and distribution is subject to the Boost Software License,
  5. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================/]
  8. [section Queries]
  9. Queries returns `__value__`s which meets some predicates. Currently supported are three types of predicates:
  10. * spatial predicates - spatial conditions that must be met by stored Value and some Geometry,
  11. * distance predicates - distance conditions that must be met by stored Value and some Geometry,
  12. * user-defined unary predicate - function, function object or lambda expression checking user-defined condition.
  13. For example queries may be used to retrieve Values:
  14. * intersecting some area but not within other area,
  15. * are nearest to some point,
  16. * overlapping a box and has user-defined property.
  17. [h4 Performing a query]
  18. There are various ways to perform a query. They are presented below.
  19. All of them returns `__value__`s intersecting some region defined as a `__box__`.
  20. Member function call
  21. std::vector<__value__> returned_values;
  22. __box__ box_region(...);
  23. rt.query(bgi::intersects(box_region), std::back_inserter(returned_values));
  24. Free function call
  25. std::vector<__value__> returned_values;
  26. __box__ box_region(...);
  27. bgi::query(rt, bgi::intersects(box_region), std::back_inserter(returned_values));
  28. Range generated by `operator|`
  29. __box__ box_region(...);
  30. BOOST_FOREACH(__value__ & v, rt | bgi::adaptors::queried(bgi::intersects(box_region)))
  31. ; // do something with v
  32. Query iterators returned by member functions
  33. std::vector<__value__> returned_values;
  34. __box__ box_region(...);
  35. std::copy(rt.qbegin(bgi::intersects(box_region)), rt.qend(), std::back_inserter(returned_values));
  36. Query iterators returned by free functions
  37. std::vector<__value__> returned_values;
  38. __box__ box_region(...);
  39. std::copy(bgi::qbegin(rt, bgi::intersects(box_region)), bgi::qend(rt), std::back_inserter(returned_values));
  40. [h4 Spatial queries]
  41. Queries using spatial predicates returns `__value__`s which are related somehow to some Geometry - box, polygon, etc.
  42. Names of spatial predicates correspond to names of __boost_geometry__ algorithms (boolean operations).
  43. Examples of some basic queries may be found in the tables below. The query region and result `Value`s are orange.
  44. [table
  45. [[intersects(Box)] [covered_by(Box)] [disjoint(Box)] [overlaps(Box)] [within(Box)]]
  46. [[[$img/index/rtree/intersects.png]] [[$img/index/rtree/within.png]] [[$img/index/rtree/disjoint.png]] [[$img/index/rtree/overlaps.png]] [[$img/index/rtree/within.png]]]
  47. ]
  48. [table
  49. [[intersects(Segment)] [intersects(Box)] [disjoint(Box)] [intersects(Box)] [disjoint(Box)]]
  50. [[[$img/index/rtree/intersects_segment.png]] [[$img/index/rtree/rtree_pt_intersects_box.png]] [[$img/index/rtree/rtree_pt_disjoint_box.png]] [[$img/index/rtree/rtree_seg_intersects_box.png]] [[$img/index/rtree/rtree_seg_disjoint_box.png]]]
  51. ]
  52. [/table
  53. [[intersects(Ring)] [intersects(Polygon)] [intersects(MultiPolygon)] [intersects(Segment)] [intersects(Linestring)]]
  54. [[[$img/index/rtree/intersects_ring.png]] [[$img/index/rtree/intersects_poly.png]] [[$img/index/rtree/intersects_mpoly.png]] [[$img/index/rtree/intersects_segment.png]] [[$img/index/rtree/intersects_linestring.png]]]
  55. /]
  56. [/table
  57. [[intersects(Box)] [disjoint(Box)] [intersects(Box)] [disjoint(Box)]]
  58. [[[$img/index/rtree/rtree_pt_intersects_box.png]] [[$img/index/rtree/rtree_pt_disjoint_box.png]] [[$img/index/rtree/rtree_seg_intersects_box.png]] [[$img/index/rtree/rtree_seg_disjoint_box.png]]]
  59. /]
  60. Spatial predicates are generated by functions defined in `boost::geometry::index` namespace.
  61. rt.query(index::contains(box), std::back_inserter(result));
  62. rt.query(index::covered_by(box), std::back_inserter(result));
  63. rt.query(index::covers(box), std::back_inserter(result));
  64. rt.query(index::disjont(box), std::back_inserter(result));
  65. rt.query(index::intersects(box), std::back_inserter(result));
  66. rt.query(index::overlaps(box), std::back_inserter(result));
  67. rt.query(index::within(box), std::back_inserter(result));
  68. All spatial predicates may be negated, e.g.:
  69. rt.query(!index::intersects(box), std::back_inserter(result));
  70. // the same as
  71. rt.query(index::disjoint(box), std::back_inserter(result));
  72. [h4 Nearest neighbours queries]
  73. Nearest neighbours queries returns `__value__`s which are closest to some Geometry.
  74. The examples of k-NN queries are presented below. 5 `__value__`s nearest to the Geometry are orange.
  75. [table
  76. [[nearest(Point, k)] [nearest(Box, k)] [nearest(Point, k)] [nearest(Box, k)]]
  77. [[[$img/index/rtree/knn_pt_box.png]] [[$img/index/rtree/knn_box_box.png]] [[$img/index/rtree/rtree_pt_knn_pt.png]] [[$img/index/rtree/rtree_pt_knn_box.png]]]
  78. ]
  79. [table
  80. [[nearest(Segment, k)]
  81. [nearest(Point, k)] [nearest(Box, k)] [nearest(Segment, k)]
  82. [nearest(Segment, k)]]
  83. [[[$img/index/rtree/knn_seg_box.png]]
  84. [[$img/index/rtree/rtree_seg_knn_pt.png]] [[$img/index/rtree/rtree_seg_knn_box.png]] [[$img/index/rtree/rtree_seg_knn_seg.png]]
  85. [[$img/index/rtree/rtree_pt_knn_seg.png]]]
  86. ]
  87. To perform the knn query one must pass the nearest predicate generated by the
  88. `nearest()` function defined in `boost::geometry::index` namespace.
  89. For non-point `__indexable__`s the shortest distance is calculated using `bg::comparable_distance()` function.
  90. The following query returns `k` `__value__`s closest to some Point in space.
  91. std::vector<__value__> returned_values;
  92. __point__ pt(/*...*/);
  93. rt.query(bgi::nearest(pt, k), std::back_inserter(returned_values));
  94. The same way different query Geometries can be used:
  95. __box__ box(/*...*/);
  96. rt.query(bgi::nearest(box, k), std::back_inserter(returned_values));
  97. Segment seg(/*...*/);
  98. rt.query(bgi::nearest(seg, k), std::back_inserter(returned_values));
  99. [note In case of k-NN queries performed with `query()` function it's not guaranteed that the returned values will be sorted according to the distance.
  100. It's different in case of k-NN queries performed with query iterator returned by `qbegin()` function which guarantees the iteration over the closest `__value__`s first. ]
  101. [h4 User-defined unary predicate]
  102. The user may pass a `UnaryPredicate` - function, function object or lambda expression taking const reference to Value and returning bool.
  103. This object may be passed to the query in order to check if `__value__` should be returned by the query. To do it one
  104. may use `index::satisfies()` function like on the example below:
  105. bool is_red(__value__ const& v)
  106. {
  107. return v.is_red();
  108. }
  109. struct is_red_o
  110. {
  111. template <typename Value>
  112. bool operator()(__value__ const& v)
  113. {
  114. return v.is_red();
  115. }
  116. }
  117. // ...
  118. rt.query(index::intersects(box) && index::satisfies(is_red),
  119. std::back_inserter(result));
  120. rt.query(index::intersects(box) && index::satisfies(is_red_o()),
  121. std::back_inserter(result));
  122. #ifndef BOOST_NO_CXX11_LAMBDAS
  123. rt.query(index::intersects(box) && index::satisfies([](__value__ const& v) { return v.is_red(); }),
  124. std::back_inserter(result));
  125. #endif
  126. `satisfies()` may be negated, e.g.:
  127. bool is_red(__value__ const& v) { return v.is_red(); }
  128. bool is_not_red(__value__ const& v) { return !v.is_red(); }
  129. // ...
  130. rt.query(index::intersects(box) && index::satisfies(is_red),
  131. std::back_inserter(result));
  132. // the same as
  133. rt.query(index::intersects(box) && !index::satisfies(is_not_red),
  134. std::back_inserter(result));
  135. [h4 Passing set of predicates]
  136. It's possible to use some number of predicates in one query by connecting them with `operator&&` e.g. `Pred1 && Pred2 && Pred3 && ...`.
  137. These predicates are connected by logical AND. Passing all predicates together not only makes possible
  138. to construct advanced queries but is also faster than separate calls because the tree is traversed only once.
  139. Traversing is continued and `Value`s are returned only if all predicates are met. Predicates are checked
  140. left-to-right so placing most restrictive predicates first should accelerate the search.
  141. rt.query(index::intersects(box1) && !index::within(box2),
  142. std::back_inserter(result));
  143. rt.query(index::intersects(box1) && !index::within(box2) && index::overlaps(box3),
  144. std::back_inserter(result));
  145. It's possible to connect different types of predicates together.
  146. index::query(rt, index::nearest(pt, k) && index::within(b), std::back_inserter(returned_values));
  147. BOOST_FOREACH(Value & v, rt | index::adaptors::queried(index::nearest(pt, k) && index::covered_by(b)))
  148. ; // do something with v
  149. [h4 Iterative queries]
  150. The query performed using query iterators may be paused and resumed if needed, e.g. when the query takes too long,
  151. or may be stopped at some point, when all interesting values were gathered. The query iterator is returned by
  152. `qbegin()` member function which requires passing predicates, like `query()` member function.
  153. for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
  154. it != tree.qend() ; ++it )
  155. {
  156. // do something with value
  157. if ( has_enough_nearest_values() )
  158. break;
  159. }
  160. [warning The modification of the `rtree`, e.g. insertion or removal of `__value__`s may invalidate the iterators. ]
  161. [h4 Inserting query results into another R-tree]
  162. There are several ways of inserting Values returned by a query into another R-tree container.
  163. The most basic way is creating a temporary container for Values and insert them later.
  164. namespace bgi = boost::geometry::index;
  165. typedef std::pair<Box, int> __value__;
  166. typedef bgi::rtree< __value__, bgi::linear<32, 8> > RTree;
  167. RTree rt1;
  168. /* some inserting into the tree */
  169. std::vector<Value> result;
  170. rt1.query(bgi::intersects(Box(/*...*/)), std::back_inserter(result));
  171. RTree rt2(result.begin(), result.end());
  172. However there are other ways. One of these methods is mentioned in the "Creation and modification" section.
  173. The insert iterator may be passed directly into the query.
  174. RTree rt3;
  175. rt1.query(bgi::intersects(Box(/*...*/))), bgi::inserter(rt3));
  176. You may also pass the resulting Range directly into the constructor or `insert()` member function using Boost.Range adaptor syntax.
  177. RTree rt4(rt1 | bgi::adaptors::queried(bgi::intersects(Box(/*...*/)))));
  178. [endsect] [/ Queries /]