1 [/============================================================================
4 Copyright (c) 2011-2017 Adam Wulkiewicz.
6 Use, modification and distribution is subject to the Boost Software License,
7 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================/]
13 Queries returns `__value__`s which meets some predicates. Currently supported are three types of predicates:
15 * spatial predicates - spatial conditions that must be met by stored Value and some Geometry,
16 * distance predicates - distance conditions that must be met by stored Value and some Geometry,
17 * user-defined unary predicate - function, function object or lambda expression checking user-defined condition.
19 For example queries may be used to retrieve Values:
21 * intersecting some area but not within other area,
22 * are nearest to some point,
23 * overlapping a box and has user-defined property.
25 [h4 Performing a query]
27 There are various ways to perform a query. They are presented below.
28 All of them returns `__value__`s intersecting some region defined as a `__box__`.
32 std::vector<__value__> returned_values;
33 __box__ box_region(...);
34 rt.query(bgi::intersects(box_region), std::back_inserter(returned_values));
38 std::vector<__value__> returned_values;
39 __box__ box_region(...);
40 bgi::query(rt, bgi::intersects(box_region), std::back_inserter(returned_values));
42 Range generated by `operator|`
44 __box__ box_region(...);
45 BOOST_FOREACH(__value__ & v, rt | bgi::adaptors::queried(bgi::intersects(box_region)))
46 ; // do something with v
48 Query iterators returned by member functions
50 std::vector<__value__> returned_values;
51 __box__ box_region(...);
52 std::copy(rt.qbegin(bgi::intersects(box_region)), rt.qend(), std::back_inserter(returned_values));
54 Query iterators returned by free functions
56 std::vector<__value__> returned_values;
57 __box__ box_region(...);
58 std::copy(bgi::qbegin(rt, bgi::intersects(box_region)), bgi::qend(rt), std::back_inserter(returned_values));
62 Queries using spatial predicates returns `__value__`s which are related somehow to some Geometry - box, polygon, etc.
63 Names of spatial predicates correspond to names of __boost_geometry__ algorithms (boolean operations).
64 Examples of some basic queries may be found in the tables below. The query region and result `Value`s are orange.
67 [[intersects(Box)] [covered_by(Box)] [disjoint(Box)] [overlaps(Box)] [within(Box)]]
68 [[[$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]]]
72 [[intersects(Ring)] [intersects(Polygon)] [intersects(MultiPolygon)] [intersects(Segment)] [intersects(Linestring)]]
73 [[[$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]]]
77 [[intersects(Box)] [disjoint(Box)] [intersects(Box)] [disjoint(Box)]]
78 [[[$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]]]
81 Spatial predicates are generated by functions defined in `boost::geometry::index` namespace.
83 rt.query(index::contains(box), std::back_inserter(result));
84 rt.query(index::covered_by(box), std::back_inserter(result));
85 rt.query(index::covers(box), std::back_inserter(result));
86 rt.query(index::disjont(box), std::back_inserter(result));
87 rt.query(index::intersects(box), std::back_inserter(result));
88 rt.query(index::overlaps(box), std::back_inserter(result));
89 rt.query(index::within(box), std::back_inserter(result));
91 All spatial predicates may be negated, e.g.:
93 rt.query(!index::intersects(box), std::back_inserter(result));
95 rt.query(index::disjoint(box), std::back_inserter(result));
97 [h4 Nearest neighbours queries]
99 Nearest neighbours queries returns `__value__`s which are closest to some Geometry.
100 The examples of k-NN queries are presented below. 5 `__value__`s nearest to the Geometry are orange.
103 [[nearest(Point, k)] [nearest(Box, k)] [nearest(Point, k)] [nearest(Box, k)]]
104 [[[$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]]]
107 [[nearest(Segment, k)]
108 [nearest(Point, k)] [nearest(Box, k)] [nearest(Segment, k)]
109 [nearest(Segment, k)]]
110 [[[$img/index/rtree/knn_seg_box.png]]
111 [[$img/index/rtree/rtree_seg_knn_pt.png]] [[$img/index/rtree/rtree_seg_knn_box.png]] [[$img/index/rtree/rtree_seg_knn_seg.png]]
112 [[$img/index/rtree/rtree_pt_knn_seg.png]]]
115 To perform the knn query one must pass the nearest predicate generated by the
116 `nearest()` function defined in `boost::geometry::index` namespace.
117 For non-point `__indexable__`s the shortest distance is calculated using `bg::comparable_distance()` function.
118 The following query returns `k` `__value__`s closest to some Point in space.
120 std::vector<__value__> returned_values;
121 __point__ pt(/*...*/);
122 rt.query(bgi::nearest(pt, k), std::back_inserter(returned_values));
124 The same way different query Geometries can be used:
126 __box__ box(/*...*/);
127 rt.query(bgi::nearest(box, k), std::back_inserter(returned_values));
129 Segment seg(/*...*/);
130 rt.query(bgi::nearest(seg, k), std::back_inserter(returned_values));
132 [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.
133 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. ]
135 [h4 User-defined unary predicate]
137 The user may pass a `UnaryPredicate` - function, function object or lambda expression taking const reference to Value and returning bool.
138 This object may be passed to the query in order to check if `__value__` should be returned by the query. To do it one
139 may use `index::satisfies()` function like on the example below:
141 bool is_red(__value__ const& v)
148 template <typename Value>
149 bool operator()(__value__ const& v)
157 rt.query(index::intersects(box) && index::satisfies(is_red),
158 std::back_inserter(result));
160 rt.query(index::intersects(box) && index::satisfies(is_red_o()),
161 std::back_inserter(result));
163 #ifndef BOOST_NO_CXX11_LAMBDAS
164 rt.query(index::intersects(box) && index::satisfies([](__value__ const& v) { return v.is_red(); }),
165 std::back_inserter(result));
168 `satisfies()` may be negated, e.g.:
170 bool is_red(__value__ const& v) { return v.is_red(); }
171 bool is_not_red(__value__ const& v) { return !v.is_red(); }
175 rt.query(index::intersects(box) && index::satisfies(is_red),
176 std::back_inserter(result));
178 rt.query(index::intersects(box) && !index::satisfies(is_not_red),
179 std::back_inserter(result));
181 [h4 Passing set of predicates]
183 It's possible to use some number of predicates in one query by connecting them with `operator&&` e.g. `Pred1 && Pred2 && Pred3 && ...`.
185 These predicates are connected by logical AND. Passing all predicates together not only makes possible
186 to construct advanced queries but is also faster than separate calls because the tree is traversed only once.
187 Traversing is continued and `Value`s are returned only if all predicates are met. Predicates are checked
188 left-to-right so placing most restrictive predicates first should accelerate the search.
190 rt.query(index::intersects(box1) && !index::within(box2),
191 std::back_inserter(result));
193 rt.query(index::intersects(box1) && !index::within(box2) && index::overlaps(box3),
194 std::back_inserter(result));
196 It's possible to connect different types of predicates together.
198 index::query(rt, index::nearest(pt, k) && index::within(b), std::back_inserter(returned_values));
200 BOOST_FOREACH(Value & v, rt | index::adaptors::queried(index::nearest(pt, k) && index::covered_by(b)))
201 ; // do something with v
203 [h4 Iterative queries]
205 The query performed using query iterators may be paused and resumed if needed, e.g. when the query takes too long,
206 or may be stopped at some point, when all interesting values were gathered. The query iterator is returned by
207 `qbegin()` member function which requires passing predicates, like `query()` member function.
209 for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
210 it != tree.qend() ; ++it )
212 // do something with value
213 if ( has_enough_nearest_values() )
217 [warning The modification of the `rtree`, e.g. insertion or removal of `__value__`s may invalidate the iterators. ]
219 [h4 Inserting query results into another R-tree]
221 There are several ways of inserting Values returned by a query into another R-tree container.
222 The most basic way is creating a temporary container for Values and insert them later.
224 namespace bgi = boost::geometry::index;
225 typedef std::pair<Box, int> __value__;
226 typedef bgi::rtree< __value__, bgi::linear<32, 8> > RTree;
229 /* some inserting into the tree */
231 std::vector<Value> result;
232 rt1.query(bgi::intersects(Box(/*...*/)), std::back_inserter(result));
233 RTree rt2(result.begin(), result.end());
235 However there are other ways. One of these methods is mentioned in the "Creation and modification" section.
236 The insert iterator may be passed directly into the query.
239 rt1.query(bgi::intersects(Box(/*...*/))), bgi::inserter(rt3));
241 You may also pass the resulting Range directly into the constructor or `insert()` member function using Boost.Range adaptor syntax.
243 RTree rt4(rt1 | bgi::adaptors::queried(bgi::intersects(Box(/*...*/)))));
245 [endsect] [/ Queries /]