]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/doc/index/rtree/query.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / doc / index / rtree / query.qbk
CommitLineData
7c673cae
FG
1[/============================================================================
2 Boost.Geometry Index
3
4 Copyright (c) 2011-2013 Adam Wulkiewicz.
5
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=============================================================================/]
10
11[section Queries]
12
13Queries returns `__value__`s which meets some predicates. Currently supported are three types of predicates:
14
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.
18
19For example queries may be used to retrieve Values:
20
21* intersecting some area but not within other area,
22* are nearest to some point,
23* overlapping a box and has user-defined property.
24
25[h4 Performing a query]
26
27There are various ways to perform a query. They are presented below.
28All of them returns `__value__`s intersecting some region defined as a `__box__`.
29
30Member function call
31
32 std::vector<__value__> returned_values;
33 __box__ box_region(...);
34 rt.query(bgi::intersects(box_region), std::back_inserter(returned_values));
35
36Free function call
37
38 std::vector<__value__> returned_values;
39 __box__ box_region(...);
40 bgi::query(rt, bgi::intersects(box_region), std::back_inserter(returned_values));
41
42Range generated by `operator|`
43
44 __box__ box_region(...);
45 BOOST_FOREACH(__value__ & v, rt | bgi::adaptors::queried(bgi::intersects(box_region)))
46 ; // do something with v
47
48Query iterators returned by member functions
49
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));
53
54Query iterators returned by free functions
55
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));
59
60[h4 Spatial predicates]
61
62Queries using spatial predicates returns `__value__`s which are related somehow to some Geometry - box, polygon, etc.
63Names of spatial predicates correspond to names of __boost_geometry__ algorithms (boolean operations).
64Examples of some basic queries may be found in the tables below. The query region and result `Value`s are orange.
65
66[table
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]]]
69]
70
71[table
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]]]
74]
75
76[table
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]]]
79]
80
81Spatial predicates are generated by functions defined in `boost::geometry::index` namespace.
82
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));
90
91All spatial predicates may be negated, e.g.:
92
93 rt.query(!index::intersects(box), std::back_inserter(result));
94 // the same as
95 rt.query(index::disjoint(box), std::back_inserter(result));
96
97[h4 Nearest neighbours queries]
98
99Nearest neighbours queries returns `__value__`s which are closest to some Geometry.
100The examples of k-NN queries are presented below. 5 `__value__`s nearest to the Geometry are orange.
101
102[table
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]]]
105]
106[table
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]]]
113]
114
115To perform the knn query one must pass the nearest predicate generated by the
116`nearest()` function defined in `boost::geometry::index` namespace.
117For non-point `__indexable__`s the shortest distance is calculated using `bg::comparable_distance()` function.
118The following query returns `k` `__value__`s closest to some Point in space.
119
120 std::vector<__value__> returned_values;
121 __point__ pt(/*...*/);
122 rt.query(bgi::nearest(pt, k), std::back_inserter(returned_values));
123
124The same way different query Geometries can be used:
125
126 __box__ box(/*...*/);
127 rt.query(bgi::nearest(box, k), std::back_inserter(returned_values));
128
129 Segment seg(/*...*/);
130 rt.query(bgi::nearest(seg, k), std::back_inserter(returned_values));
131
132[h4 User-defined unary predicate]
133
134The user may pass a `UnaryPredicate` - function, function object or lambda expression taking const reference to Value and returning bool.
135This object may be passed to the query in order to check if `__value__` should be returned by the query. To do it one
136may use `index::satisfies()` function like on the example below:
137
138 bool is_red(__value__ const& v)
139 {
140 return v.is_red();
141 }
142
143 struct is_red_o
144 {
145 template <typename Value>
146 bool operator()(__value__ const& v)
147 {
148 return v.is_red();
149 }
150 }
151
152 // ...
153
154 rt.query(index::intersects(box) && index::satisfies(is_red),
155 std::back_inserter(result));
156
157 rt.query(index::intersects(box) && index::satisfies(is_red_o()),
158 std::back_inserter(result));
159
160 #ifndef BOOST_NO_CXX11_LAMBDAS
161 rt.query(index::intersects(box) && index::satisfies([](__value__ const& v) { return v.is_red(); }),
162 std::back_inserter(result));
163 #endif
164
165`satisfies()` may be negated, e.g.:
166
167 bool is_red(__value__ const& v) { return v.is_red(); }
168 bool is_not_red(__value__ const& v) { return !v.is_red(); }
169
170 // ...
171
172 rt.query(index::intersects(box) && index::satisfies(is_red),
173 std::back_inserter(result));
174 // the same as
175 rt.query(index::intersects(box) && !index::satisfies(is_not_red),
176 std::back_inserter(result));
177
178[h4 Passing a set of predicates]
179
180It's possible to use some number of predicates in one query by connecting them with `operator&&` e.g. `Pred1 && Pred2 && Pred3 && ...`.
181
182These predicates are connected by logical AND. Passing all predicates together not only makes possible
183to construct advanced queries but is also faster than separate calls because the tree is traversed only once.
184Traversing is continued and `Value`s are returned only if all predicates are met. Predicates are checked
185left-to-right so placing most restrictive predicates first should accelerate the search.
186
187 rt.query(index::intersects(box1) && !index::within(box2),
188 std::back_inserter(result));
189
190 rt.query(index::intersects(box1) && !index::within(box2) && index::overlaps(box3),
191 std::back_inserter(result));
192
193Of course it's possible to connect different types of predicates together.
194
195 index::query(rt, index::nearest(pt, k) && index::within(b), std::back_inserter(returned_values));
196
197 BOOST_FOREACH(Value & v, rt | index::adaptors::queried(index::nearest(pt, k) && index::covered_by(b)))
198 ; // do something with v
199
200[h4 Iterative queries]
201
202The query performed using query iterators may be paused and resumed if needed, e.g. when the query takes too long,
203or may be stopped at some point, when all interesting values were gathered. The query iterator is returned by
204`qbegin()` member function which requires passing predicates, like `query()` member function.
205
206 for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
207 it != tree.qend() ; ++it )
208 {
209 // do something with value
210 if ( has_enough_nearest_values() )
211 break;
212 }
213
214[note In the case of iterative k-NN queries it's guaranteed to iterate over the closest `__value__`s first. ]
215
216[warning The modification of the `rtree`, e.g. insertion or removal of `__value__`s may invalidate the iterators. ]
217
218[h4 Inserting query results into the other R-tree]
219
220There are several ways of inserting Values returned by a query to the other R-tree container.
221The most basic way is creating a temporary container for Values and insert them later.
222
223 namespace bgi = boost::geometry::index;
224 typedef std::pair<Box, int> __value__;
225 typedef bgi::rtree< __value__, bgi::linear<32, 8> > RTree;
226
227 RTree rt1;
228 /* some inserting into the tree */
229
230 std::vector<Value> result;
231 rt1.query(bgi::intersects(Box(/*...*/)), std::back_inserter(result));
232 RTree rt2(result.begin(), result.end());
233
234However there are better ways. One of these methods is mentioned in the "Creation and modification" section.
235The insert iterator may be passed directly into the query.
236
237 RTree rt3;
238 rt1.query(bgi::intersects(Box(/*...*/))), bgi::inserter(rt3));
239
240If you're a user of Boost.Range you'll appreciate the third option. You may pass the result Range directly into the
241constructor or `insert()` member function.
242
243 RTree rt4(rt1 | bgi::adaptors::queried(bgi::intersects(Box(/*...*/)))));
244
245[endsect] [/ Queries /]