Chris@16
|
1 // Boost.Geometry Index
|
Chris@16
|
2 //
|
Chris@16
|
3 // R-tree implementation
|
Chris@16
|
4 //
|
Chris@16
|
5 // Copyright (c) 2008 Federico J. Fernandez.
|
Chris@16
|
6 // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
|
Chris@16
|
7 //
|
Chris@16
|
8 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
10 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
11
|
Chris@16
|
12 #ifndef BOOST_GEOMETRY_INDEX_RTREE_HPP
|
Chris@16
|
13 #define BOOST_GEOMETRY_INDEX_RTREE_HPP
|
Chris@16
|
14
|
Chris@16
|
15 #include <algorithm>
|
Chris@16
|
16
|
Chris@16
|
17 #include <boost/tuple/tuple.hpp>
|
Chris@16
|
18 #include <boost/move/move.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/geometry/geometry.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 #include <boost/geometry/index/detail/config_begin.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 #include <boost/geometry/index/detail/assert.hpp>
|
Chris@16
|
25 #include <boost/geometry/index/detail/exception.hpp>
|
Chris@16
|
26
|
Chris@16
|
27 #include <boost/geometry/index/detail/rtree/options.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 #include <boost/geometry/index/indexable.hpp>
|
Chris@16
|
30 #include <boost/geometry/index/equal_to.hpp>
|
Chris@16
|
31
|
Chris@16
|
32 #include <boost/geometry/index/detail/translator.hpp>
|
Chris@16
|
33
|
Chris@16
|
34 #include <boost/geometry/index/predicates.hpp>
|
Chris@16
|
35 #include <boost/geometry/index/distance_predicates.hpp>
|
Chris@16
|
36 #include <boost/geometry/index/detail/rtree/adaptors.hpp>
|
Chris@16
|
37
|
Chris@16
|
38 #include <boost/geometry/index/detail/meta.hpp>
|
Chris@16
|
39 #include <boost/geometry/index/detail/utilities.hpp>
|
Chris@16
|
40 #include <boost/geometry/index/detail/rtree/node/node.hpp>
|
Chris@16
|
41
|
Chris@16
|
42 #include <boost/geometry/index/detail/algorithms/is_valid.hpp>
|
Chris@16
|
43
|
Chris@16
|
44 #include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
|
Chris@16
|
45 #include <boost/geometry/index/detail/rtree/visitors/remove.hpp>
|
Chris@16
|
46 #include <boost/geometry/index/detail/rtree/visitors/copy.hpp>
|
Chris@16
|
47 #include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
|
Chris@16
|
48 #include <boost/geometry/index/detail/rtree/visitors/spatial_query.hpp>
|
Chris@16
|
49 #include <boost/geometry/index/detail/rtree/visitors/distance_query.hpp>
|
Chris@16
|
50 #include <boost/geometry/index/detail/rtree/visitors/count.hpp>
|
Chris@16
|
51 #include <boost/geometry/index/detail/rtree/visitors/children_box.hpp>
|
Chris@16
|
52
|
Chris@16
|
53 #include <boost/geometry/index/detail/rtree/linear/linear.hpp>
|
Chris@16
|
54 #include <boost/geometry/index/detail/rtree/quadratic/quadratic.hpp>
|
Chris@16
|
55 #include <boost/geometry/index/detail/rtree/rstar/rstar.hpp>
|
Chris@16
|
56 //#include <boost/geometry/extensions/index/detail/rtree/kmeans/kmeans.hpp>
|
Chris@16
|
57
|
Chris@16
|
58 #include <boost/geometry/index/detail/rtree/pack_create.hpp>
|
Chris@16
|
59
|
Chris@16
|
60 #include <boost/geometry/index/inserter.hpp>
|
Chris@16
|
61
|
Chris@16
|
62 #include <boost/geometry/index/detail/rtree/utilities/view.hpp>
|
Chris@16
|
63
|
Chris@16
|
64 #include <boost/geometry/index/detail/rtree/query_iterators.hpp>
|
Chris@16
|
65
|
Chris@16
|
66 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
|
Chris@16
|
67 // serialization
|
Chris@16
|
68 #include <boost/geometry/index/detail/serialization.hpp>
|
Chris@16
|
69 #endif
|
Chris@16
|
70
|
Chris@16
|
71 // TODO change the name to bounding_tree
|
Chris@16
|
72
|
Chris@16
|
73 /*!
|
Chris@16
|
74 \defgroup rtree_functions R-tree free functions (boost::geometry::index::)
|
Chris@16
|
75 */
|
Chris@16
|
76
|
Chris@16
|
77 namespace boost { namespace geometry { namespace index {
|
Chris@16
|
78
|
Chris@16
|
79 /*!
|
Chris@16
|
80 \brief The R-tree spatial index.
|
Chris@16
|
81
|
Chris@16
|
82 This is self-balancing spatial index capable to store various types of Values and balancing algorithms.
|
Chris@16
|
83
|
Chris@16
|
84 \par Parameters
|
Chris@16
|
85 The user must pass a type defining the Parameters which will
|
Chris@16
|
86 be used in rtree creation process. This type is used e.g. to specify balancing algorithm
|
Chris@16
|
87 with specific parameters like min and max number of elements in node.
|
Chris@16
|
88
|
Chris@16
|
89 \par
|
Chris@16
|
90 Predefined algorithms with compile-time parameters are:
|
Chris@16
|
91 \li <tt>boost::geometry::index::linear</tt>,
|
Chris@16
|
92 \li <tt>boost::geometry::index::quadratic</tt>,
|
Chris@16
|
93 \li <tt>boost::geometry::index::rstar</tt>.
|
Chris@16
|
94
|
Chris@16
|
95 \par
|
Chris@16
|
96 Predefined algorithms with run-time parameters are:
|
Chris@16
|
97 \li \c boost::geometry::index::dynamic_linear,
|
Chris@16
|
98 \li \c boost::geometry::index::dynamic_quadratic,
|
Chris@16
|
99 \li \c boost::geometry::index::dynamic_rstar.
|
Chris@16
|
100
|
Chris@16
|
101 \par IndexableGetter
|
Chris@16
|
102 The object of IndexableGetter type translates from Value to Indexable each time r-tree requires it. Which means that this
|
Chris@16
|
103 operation is done for each Value access. Therefore the IndexableGetter should return the Indexable by
|
Chris@16
|
104 const reference instead of a value. Default one can translate all types adapted to Point
|
Chris@16
|
105 or Box concepts (called Indexables). It also handles <tt>std::pair<Indexable, T></tt> and
|
Chris@16
|
106 <tt>boost::tuple<Indexable, ...></tt>. For example, if <tt>std::pair<Box, int></tt> is stored in the
|
Chris@16
|
107 container, the default IndexableGetter translates from <tt>std::pair<Box, int> const&</tt> to <tt>Box const&</tt>.
|
Chris@16
|
108
|
Chris@16
|
109 \par EqualTo
|
Chris@16
|
110 The object of EqualTo type compares Values and returns <tt>true</tt> if they're equal. It's similar to <tt>std::equal_to<></tt>.
|
Chris@16
|
111 The default EqualTo returns the result of <tt>boost::geometry::equals()</tt> for types adapted to some Geometry concept
|
Chris@16
|
112 defined in Boost.Geometry and the result of operator= for other types. Components of Pairs and Tuples are compared left-to-right.
|
Chris@16
|
113
|
Chris@16
|
114 \tparam Value The type of objects stored in the container.
|
Chris@16
|
115 \tparam Parameters Compile-time parameters.
|
Chris@16
|
116 \tparam IndexableGetter The function object extracting Indexable from Value.
|
Chris@16
|
117 \tparam EqualTo The function object comparing objects of type Value.
|
Chris@16
|
118 \tparam Allocator The allocator used to allocate/deallocate memory, construct/destroy nodes and Values.
|
Chris@16
|
119 */
|
Chris@16
|
120 template <
|
Chris@16
|
121 typename Value,
|
Chris@16
|
122 typename Parameters,
|
Chris@16
|
123 typename IndexableGetter = index::indexable<Value>,
|
Chris@16
|
124 typename EqualTo = index::equal_to<Value>,
|
Chris@16
|
125 typename Allocator = std::allocator<Value>
|
Chris@16
|
126 >
|
Chris@16
|
127 class rtree
|
Chris@16
|
128 {
|
Chris@16
|
129 BOOST_COPYABLE_AND_MOVABLE(rtree)
|
Chris@16
|
130
|
Chris@16
|
131 public:
|
Chris@16
|
132 /*! \brief The type of Value stored in the container. */
|
Chris@16
|
133 typedef Value value_type;
|
Chris@16
|
134 /*! \brief R-tree parameters type. */
|
Chris@16
|
135 typedef Parameters parameters_type;
|
Chris@16
|
136 /*! \brief The function object extracting Indexable from Value. */
|
Chris@16
|
137 typedef IndexableGetter indexable_getter;
|
Chris@16
|
138 /*! \brief The function object comparing objects of type Value. */
|
Chris@16
|
139 typedef EqualTo value_equal;
|
Chris@16
|
140 /*! \brief The type of allocator used by the container. */
|
Chris@16
|
141 typedef Allocator allocator_type;
|
Chris@16
|
142
|
Chris@16
|
143 // TODO: SHOULD THIS TYPE BE REMOVED?
|
Chris@16
|
144 /*! \brief The Indexable type to which Value is translated. */
|
Chris@16
|
145 typedef typename index::detail::indexable_type<
|
Chris@16
|
146 detail::translator<IndexableGetter, EqualTo>
|
Chris@16
|
147 >::type indexable_type;
|
Chris@16
|
148
|
Chris@16
|
149 /*! \brief The Box type used by the R-tree. */
|
Chris@16
|
150 typedef geometry::model::box<
|
Chris@16
|
151 geometry::model::point<
|
Chris@16
|
152 typename coordinate_type<indexable_type>::type,
|
Chris@16
|
153 dimension<indexable_type>::value,
|
Chris@16
|
154 typename coordinate_system<indexable_type>::type
|
Chris@16
|
155 >
|
Chris@16
|
156 >
|
Chris@16
|
157 bounds_type;
|
Chris@16
|
158
|
Chris@16
|
159 private:
|
Chris@16
|
160
|
Chris@16
|
161 typedef detail::translator<IndexableGetter, EqualTo> translator_type;
|
Chris@16
|
162
|
Chris@16
|
163 typedef bounds_type box_type;
|
Chris@16
|
164 typedef typename detail::rtree::options_type<Parameters>::type options_type;
|
Chris@16
|
165 typedef typename options_type::node_tag node_tag;
|
Chris@16
|
166 typedef detail::rtree::allocators<allocator_type, value_type, typename options_type::parameters_type, box_type, node_tag> allocators_type;
|
Chris@16
|
167
|
Chris@16
|
168 typedef typename detail::rtree::node<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type node;
|
Chris@16
|
169 typedef typename detail::rtree::internal_node<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type internal_node;
|
Chris@16
|
170 typedef typename detail::rtree::leaf<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type leaf;
|
Chris@16
|
171
|
Chris@16
|
172 typedef typename allocators_type::node_pointer node_pointer;
|
Chris@16
|
173 typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
Chris@16
|
174 typedef detail::rtree::node_auto_ptr<value_type, options_type, translator_type, box_type, allocators_type> node_auto_ptr;
|
Chris@16
|
175
|
Chris@16
|
176 friend class detail::rtree::utilities::view<rtree>;
|
Chris@16
|
177 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
|
Chris@16
|
178 friend class detail::rtree::private_view<rtree>;
|
Chris@16
|
179 friend class detail::rtree::const_private_view<rtree>;
|
Chris@16
|
180 #endif
|
Chris@16
|
181
|
Chris@16
|
182 public:
|
Chris@16
|
183
|
Chris@16
|
184 /*! \brief Type of reference to Value. */
|
Chris@16
|
185 typedef typename allocators_type::reference reference;
|
Chris@16
|
186 /*! \brief Type of reference to const Value. */
|
Chris@16
|
187 typedef typename allocators_type::const_reference const_reference;
|
Chris@16
|
188 /*! \brief Type of pointer to Value. */
|
Chris@16
|
189 typedef typename allocators_type::pointer pointer;
|
Chris@16
|
190 /*! \brief Type of pointer to const Value. */
|
Chris@16
|
191 typedef typename allocators_type::const_pointer const_pointer;
|
Chris@16
|
192 /*! \brief Type of difference type. */
|
Chris@16
|
193 typedef typename allocators_type::difference_type difference_type;
|
Chris@16
|
194 /*! \brief Unsigned integral type used by the container. */
|
Chris@16
|
195 typedef typename allocators_type::size_type size_type;
|
Chris@16
|
196
|
Chris@16
|
197 /*! \brief Type of const query iterator. */
|
Chris@16
|
198 typedef index::detail::rtree::iterators::query_iterator<value_type, allocators_type> const_query_iterator;
|
Chris@16
|
199
|
Chris@16
|
200 public:
|
Chris@16
|
201
|
Chris@16
|
202 /*!
|
Chris@16
|
203 \brief The constructor.
|
Chris@16
|
204
|
Chris@16
|
205 \param parameters The parameters object.
|
Chris@16
|
206 \param getter The function object extracting Indexable from Value.
|
Chris@16
|
207 \param equal The function object comparing Values.
|
Chris@16
|
208
|
Chris@16
|
209 \par Throws
|
Chris@16
|
210 If allocator default constructor throws.
|
Chris@16
|
211 */
|
Chris@16
|
212 inline explicit rtree(parameters_type const& parameters = parameters_type(),
|
Chris@16
|
213 indexable_getter const& getter = indexable_getter(),
|
Chris@16
|
214 value_equal const& equal = value_equal())
|
Chris@16
|
215 : m_members(getter, equal, parameters)
|
Chris@16
|
216 {}
|
Chris@16
|
217
|
Chris@16
|
218 /*!
|
Chris@16
|
219 \brief The constructor.
|
Chris@16
|
220
|
Chris@16
|
221 \param parameters The parameters object.
|
Chris@16
|
222 \param getter The function object extracting Indexable from Value.
|
Chris@16
|
223 \param equal The function object comparing Values.
|
Chris@16
|
224 \param allocator The allocator object.
|
Chris@16
|
225
|
Chris@16
|
226 \par Throws
|
Chris@16
|
227 If allocator copy constructor throws.
|
Chris@16
|
228 */
|
Chris@16
|
229 inline rtree(parameters_type const& parameters,
|
Chris@16
|
230 indexable_getter const& getter,
|
Chris@16
|
231 value_equal const& equal,
|
Chris@16
|
232 allocator_type const& allocator)
|
Chris@16
|
233 : m_members(getter, equal, parameters, allocator)
|
Chris@16
|
234 {}
|
Chris@16
|
235
|
Chris@16
|
236 /*!
|
Chris@16
|
237 \brief The constructor.
|
Chris@16
|
238
|
Chris@16
|
239 The tree is created using packing algorithm.
|
Chris@16
|
240
|
Chris@16
|
241 \param first The beginning of the range of Values.
|
Chris@16
|
242 \param last The end of the range of Values.
|
Chris@16
|
243 \param parameters The parameters object.
|
Chris@16
|
244 \param getter The function object extracting Indexable from Value.
|
Chris@16
|
245 \param equal The function object comparing Values.
|
Chris@16
|
246 \param allocator The allocator object.
|
Chris@16
|
247
|
Chris@16
|
248 \par Throws
|
Chris@16
|
249 \li If allocator copy constructor throws.
|
Chris@16
|
250 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
251 \li If allocation throws or returns invalid value.
|
Chris@16
|
252 */
|
Chris@16
|
253 template<typename Iterator>
|
Chris@16
|
254 inline rtree(Iterator first, Iterator last,
|
Chris@16
|
255 parameters_type const& parameters = parameters_type(),
|
Chris@16
|
256 indexable_getter const& getter = indexable_getter(),
|
Chris@16
|
257 value_equal const& equal = value_equal(),
|
Chris@16
|
258 allocator_type const& allocator = allocator_type())
|
Chris@16
|
259 : m_members(getter, equal, parameters, allocator)
|
Chris@16
|
260 {
|
Chris@16
|
261 typedef detail::rtree::pack<value_type, options_type, translator_type, box_type, allocators_type> pack;
|
Chris@16
|
262 size_type vc = 0, ll = 0;
|
Chris@16
|
263 m_members.root = pack::apply(first, last, vc, ll,
|
Chris@16
|
264 m_members.parameters(), m_members.translator(), m_members.allocators());
|
Chris@16
|
265 m_members.values_count = vc;
|
Chris@16
|
266 m_members.leafs_level = ll;
|
Chris@16
|
267 }
|
Chris@16
|
268
|
Chris@16
|
269 /*!
|
Chris@16
|
270 \brief The constructor.
|
Chris@16
|
271
|
Chris@16
|
272 The tree is created using packing algorithm.
|
Chris@16
|
273
|
Chris@16
|
274 \param rng The range of Values.
|
Chris@16
|
275 \param parameters The parameters object.
|
Chris@16
|
276 \param getter The function object extracting Indexable from Value.
|
Chris@16
|
277 \param equal The function object comparing Values.
|
Chris@16
|
278 \param allocator The allocator object.
|
Chris@16
|
279
|
Chris@16
|
280 \par Throws
|
Chris@16
|
281 \li If allocator copy constructor throws.
|
Chris@16
|
282 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
283 \li If allocation throws or returns invalid value.
|
Chris@16
|
284 */
|
Chris@16
|
285 template<typename Range>
|
Chris@16
|
286 inline explicit rtree(Range const& rng,
|
Chris@16
|
287 parameters_type const& parameters = parameters_type(),
|
Chris@16
|
288 indexable_getter const& getter = indexable_getter(),
|
Chris@16
|
289 value_equal const& equal = value_equal(),
|
Chris@16
|
290 allocator_type const& allocator = allocator_type())
|
Chris@16
|
291 : m_members(getter, equal, parameters, allocator)
|
Chris@16
|
292 {
|
Chris@16
|
293 typedef detail::rtree::pack<value_type, options_type, translator_type, box_type, allocators_type> pack;
|
Chris@16
|
294 size_type vc = 0, ll = 0;
|
Chris@16
|
295 m_members.root = pack::apply(::boost::begin(rng), ::boost::end(rng), vc, ll,
|
Chris@16
|
296 m_members.parameters(), m_members.translator(), m_members.allocators());
|
Chris@16
|
297 m_members.values_count = vc;
|
Chris@16
|
298 m_members.leafs_level = ll;
|
Chris@16
|
299 }
|
Chris@16
|
300
|
Chris@16
|
301 /*!
|
Chris@16
|
302 \brief The destructor.
|
Chris@16
|
303
|
Chris@16
|
304 \par Throws
|
Chris@16
|
305 Nothing.
|
Chris@16
|
306 */
|
Chris@16
|
307 inline ~rtree()
|
Chris@16
|
308 {
|
Chris@16
|
309 this->raw_destroy(*this);
|
Chris@16
|
310 }
|
Chris@16
|
311
|
Chris@16
|
312 /*!
|
Chris@16
|
313 \brief The copy constructor.
|
Chris@16
|
314
|
Chris@16
|
315 It uses parameters, translator and allocator from the source tree.
|
Chris@16
|
316
|
Chris@16
|
317 \param src The rtree which content will be copied.
|
Chris@16
|
318
|
Chris@16
|
319 \par Throws
|
Chris@16
|
320 \li If allocator copy constructor throws.
|
Chris@16
|
321 \li If Value copy constructor throws.
|
Chris@16
|
322 \li If allocation throws or returns invalid value.
|
Chris@16
|
323 */
|
Chris@16
|
324 inline rtree(rtree const& src)
|
Chris@16
|
325 : m_members(src.m_members.indexable_getter(),
|
Chris@16
|
326 src.m_members.equal_to(),
|
Chris@16
|
327 src.m_members.parameters(),
|
Chris@16
|
328 allocator_traits_type::select_on_container_copy_construction(src.get_allocator()))
|
Chris@16
|
329 {
|
Chris@16
|
330 this->raw_copy(src, *this, false);
|
Chris@16
|
331 }
|
Chris@16
|
332
|
Chris@16
|
333 /*!
|
Chris@16
|
334 \brief The copy constructor.
|
Chris@16
|
335
|
Chris@16
|
336 It uses Parameters and translator from the source tree.
|
Chris@16
|
337
|
Chris@16
|
338 \param src The rtree which content will be copied.
|
Chris@16
|
339 \param allocator The allocator which will be used.
|
Chris@16
|
340
|
Chris@16
|
341 \par Throws
|
Chris@16
|
342 \li If allocator copy constructor throws.
|
Chris@16
|
343 \li If Value copy constructor throws.
|
Chris@16
|
344 \li If allocation throws or returns invalid value.
|
Chris@16
|
345 */
|
Chris@16
|
346 inline rtree(rtree const& src, allocator_type const& allocator)
|
Chris@16
|
347 : m_members(src.m_members.indexable_getter(),
|
Chris@16
|
348 src.m_members.equal_to(),
|
Chris@16
|
349 src.m_members.parameters(), allocator)
|
Chris@16
|
350 {
|
Chris@16
|
351 this->raw_copy(src, *this, false);
|
Chris@16
|
352 }
|
Chris@16
|
353
|
Chris@16
|
354 /*!
|
Chris@16
|
355 \brief The moving constructor.
|
Chris@16
|
356
|
Chris@16
|
357 It uses parameters, translator and allocator from the source tree.
|
Chris@16
|
358
|
Chris@16
|
359 \param src The rtree which content will be moved.
|
Chris@16
|
360
|
Chris@16
|
361 \par Throws
|
Chris@16
|
362 Nothing.
|
Chris@16
|
363 */
|
Chris@16
|
364 inline rtree(BOOST_RV_REF(rtree) src)
|
Chris@16
|
365 : m_members(src.m_members.indexable_getter(),
|
Chris@16
|
366 src.m_members.equal_to(),
|
Chris@16
|
367 src.m_members.parameters(),
|
Chris@16
|
368 boost::move(src.m_members.allocators()))
|
Chris@16
|
369 {
|
Chris@16
|
370 boost::swap(m_members.values_count, src.m_members.values_count);
|
Chris@16
|
371 boost::swap(m_members.leafs_level, src.m_members.leafs_level);
|
Chris@16
|
372 boost::swap(m_members.root, src.m_members.root);
|
Chris@16
|
373 }
|
Chris@16
|
374
|
Chris@16
|
375 /*!
|
Chris@16
|
376 \brief The moving constructor.
|
Chris@16
|
377
|
Chris@16
|
378 It uses parameters and translator from the source tree.
|
Chris@16
|
379
|
Chris@16
|
380 \param src The rtree which content will be moved.
|
Chris@16
|
381 \param allocator The allocator.
|
Chris@16
|
382
|
Chris@16
|
383 \par Throws
|
Chris@16
|
384 \li If allocator copy constructor throws.
|
Chris@16
|
385 \li If Value copy constructor throws (only if allocators aren't equal).
|
Chris@16
|
386 \li If allocation throws or returns invalid value (only if allocators aren't equal).
|
Chris@16
|
387 */
|
Chris@16
|
388 inline rtree(BOOST_RV_REF(rtree) src, allocator_type const& allocator)
|
Chris@16
|
389 : m_members(src.m_members.indexable_getter(),
|
Chris@16
|
390 src.m_members.equal_to(),
|
Chris@16
|
391 src.m_members.parameters(),
|
Chris@16
|
392 allocator)
|
Chris@16
|
393 {
|
Chris@16
|
394 if ( src.m_members.allocators() == allocator )
|
Chris@16
|
395 {
|
Chris@16
|
396 boost::swap(m_members.values_count, src.m_members.values_count);
|
Chris@16
|
397 boost::swap(m_members.leafs_level, src.m_members.leafs_level);
|
Chris@16
|
398 boost::swap(m_members.root, src.m_members.root);
|
Chris@16
|
399 }
|
Chris@16
|
400 else
|
Chris@16
|
401 {
|
Chris@16
|
402 this->raw_copy(src, *this, false);
|
Chris@16
|
403 }
|
Chris@16
|
404 }
|
Chris@16
|
405
|
Chris@16
|
406 /*!
|
Chris@16
|
407 \brief The assignment operator.
|
Chris@16
|
408
|
Chris@16
|
409 It uses parameters and translator from the source tree.
|
Chris@16
|
410
|
Chris@16
|
411 \param src The rtree which content will be copied.
|
Chris@16
|
412
|
Chris@16
|
413 \par Throws
|
Chris@16
|
414 \li If Value copy constructor throws.
|
Chris@16
|
415 \li If allocation throws.
|
Chris@16
|
416 \li If allocation throws or returns invalid value.
|
Chris@16
|
417 */
|
Chris@16
|
418 inline rtree & operator=(BOOST_COPY_ASSIGN_REF(rtree) src)
|
Chris@16
|
419 {
|
Chris@16
|
420 if ( &src != this )
|
Chris@16
|
421 {
|
Chris@16
|
422 allocators_type & this_allocs = m_members.allocators();
|
Chris@16
|
423 allocators_type const& src_allocs = src.m_members.allocators();
|
Chris@16
|
424
|
Chris@16
|
425 // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
|
Chris@16
|
426 // (allocators stored as base classes of members_holder)
|
Chris@16
|
427 // copying them changes values_count, in this case it doesn't cause errors since data must be copied
|
Chris@16
|
428
|
Chris@16
|
429 typedef boost::mpl::bool_<
|
Chris@16
|
430 allocator_traits_type::propagate_on_container_copy_assignment::value
|
Chris@16
|
431 > propagate;
|
Chris@16
|
432
|
Chris@16
|
433 if ( propagate::value && !(this_allocs == src_allocs) )
|
Chris@16
|
434 this->raw_destroy(*this);
|
Chris@16
|
435 detail::assign_cond(this_allocs, src_allocs, propagate());
|
Chris@16
|
436
|
Chris@16
|
437 // It uses m_allocators
|
Chris@16
|
438 this->raw_copy(src, *this, true);
|
Chris@16
|
439 }
|
Chris@16
|
440
|
Chris@16
|
441 return *this;
|
Chris@16
|
442 }
|
Chris@16
|
443
|
Chris@16
|
444 /*!
|
Chris@16
|
445 \brief The moving assignment.
|
Chris@16
|
446
|
Chris@16
|
447 It uses parameters and translator from the source tree.
|
Chris@16
|
448
|
Chris@16
|
449 \param src The rtree which content will be moved.
|
Chris@16
|
450
|
Chris@16
|
451 \par Throws
|
Chris@16
|
452 Only if allocators aren't equal.
|
Chris@16
|
453 \li If Value copy constructor throws.
|
Chris@16
|
454 \li If allocation throws or returns invalid value.
|
Chris@16
|
455 */
|
Chris@16
|
456 inline rtree & operator=(BOOST_RV_REF(rtree) src)
|
Chris@16
|
457 {
|
Chris@16
|
458 if ( &src != this )
|
Chris@16
|
459 {
|
Chris@16
|
460 allocators_type & this_allocs = m_members.allocators();
|
Chris@16
|
461 allocators_type & src_allocs = src.m_members.allocators();
|
Chris@16
|
462
|
Chris@16
|
463 if ( this_allocs == src_allocs )
|
Chris@16
|
464 {
|
Chris@16
|
465 this->raw_destroy(*this);
|
Chris@16
|
466
|
Chris@16
|
467 m_members.indexable_getter() = src.m_members.indexable_getter();
|
Chris@16
|
468 m_members.equal_to() = src.m_members.equal_to();
|
Chris@16
|
469 m_members.parameters() = src.m_members.parameters();
|
Chris@16
|
470
|
Chris@16
|
471 boost::swap(m_members.values_count, src.m_members.values_count);
|
Chris@16
|
472 boost::swap(m_members.leafs_level, src.m_members.leafs_level);
|
Chris@16
|
473 boost::swap(m_members.root, src.m_members.root);
|
Chris@16
|
474
|
Chris@16
|
475 // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
|
Chris@16
|
476 // (allocators stored as base classes of members_holder)
|
Chris@16
|
477 // moving them changes values_count
|
Chris@16
|
478
|
Chris@16
|
479 typedef boost::mpl::bool_<
|
Chris@16
|
480 allocator_traits_type::propagate_on_container_move_assignment::value
|
Chris@16
|
481 > propagate;
|
Chris@16
|
482 detail::move_cond(this_allocs, src_allocs, propagate());
|
Chris@16
|
483 }
|
Chris@16
|
484 else
|
Chris@16
|
485 {
|
Chris@16
|
486 // TODO - shouldn't here propagate_on_container_copy_assignment be checked like in operator=(const&)?
|
Chris@16
|
487
|
Chris@16
|
488 // It uses m_allocators
|
Chris@16
|
489 this->raw_copy(src, *this, true);
|
Chris@16
|
490 }
|
Chris@16
|
491 }
|
Chris@16
|
492
|
Chris@16
|
493 return *this;
|
Chris@16
|
494 }
|
Chris@16
|
495
|
Chris@16
|
496 /*!
|
Chris@16
|
497 \brief Swaps contents of two rtrees.
|
Chris@16
|
498
|
Chris@16
|
499 Parameters, translator and allocators are swapped as well.
|
Chris@16
|
500
|
Chris@16
|
501 \param other The rtree which content will be swapped with this rtree content.
|
Chris@16
|
502
|
Chris@16
|
503 \par Throws
|
Chris@16
|
504 If allocators swap throws.
|
Chris@16
|
505 */
|
Chris@16
|
506 void swap(rtree & other)
|
Chris@16
|
507 {
|
Chris@16
|
508 boost::swap(m_members.indexable_getter(), other.m_members.indexable_getter());
|
Chris@16
|
509 boost::swap(m_members.equal_to(), other.m_members.equal_to());
|
Chris@16
|
510 boost::swap(m_members.parameters(), other.m_members.parameters());
|
Chris@16
|
511
|
Chris@16
|
512 // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
|
Chris@16
|
513 // (allocators stored as base classes of members_holder)
|
Chris@16
|
514 // swapping them changes values_count
|
Chris@16
|
515
|
Chris@16
|
516 typedef boost::mpl::bool_<
|
Chris@16
|
517 allocator_traits_type::propagate_on_container_swap::value
|
Chris@16
|
518 > propagate;
|
Chris@16
|
519 detail::swap_cond(m_members.allocators(), other.m_members.allocators(), propagate());
|
Chris@16
|
520
|
Chris@16
|
521 boost::swap(m_members.values_count, other.m_members.values_count);
|
Chris@16
|
522 boost::swap(m_members.leafs_level, other.m_members.leafs_level);
|
Chris@16
|
523 boost::swap(m_members.root, other.m_members.root);
|
Chris@16
|
524 }
|
Chris@16
|
525
|
Chris@16
|
526 /*!
|
Chris@16
|
527 \brief Insert a value to the index.
|
Chris@16
|
528
|
Chris@16
|
529 \param value The value which will be stored in the container.
|
Chris@16
|
530
|
Chris@16
|
531 \par Throws
|
Chris@16
|
532 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
533 \li If allocation throws or returns invalid value.
|
Chris@16
|
534
|
Chris@16
|
535 \warning
|
Chris@16
|
536 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
537 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
538 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
539 some of them may return invalid data.
|
Chris@16
|
540 */
|
Chris@16
|
541 inline void insert(value_type const& value)
|
Chris@16
|
542 {
|
Chris@16
|
543 if ( !m_members.root )
|
Chris@16
|
544 this->raw_create();
|
Chris@16
|
545
|
Chris@16
|
546 this->raw_insert(value);
|
Chris@16
|
547 }
|
Chris@16
|
548
|
Chris@16
|
549 /*!
|
Chris@16
|
550 \brief Insert a range of values to the index.
|
Chris@16
|
551
|
Chris@16
|
552 \param first The beginning of the range of values.
|
Chris@16
|
553 \param last The end of the range of values.
|
Chris@16
|
554
|
Chris@16
|
555 \par Throws
|
Chris@16
|
556 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
557 \li If allocation throws or returns invalid value.
|
Chris@16
|
558
|
Chris@16
|
559 \warning
|
Chris@16
|
560 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
561 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
562 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
563 some of them may return invalid data.
|
Chris@16
|
564 */
|
Chris@16
|
565 template <typename Iterator>
|
Chris@16
|
566 inline void insert(Iterator first, Iterator last)
|
Chris@16
|
567 {
|
Chris@16
|
568 if ( !m_members.root )
|
Chris@16
|
569 this->raw_create();
|
Chris@16
|
570
|
Chris@16
|
571 for ( ; first != last ; ++first )
|
Chris@16
|
572 this->raw_insert(*first);
|
Chris@16
|
573 }
|
Chris@16
|
574
|
Chris@16
|
575 /*!
|
Chris@16
|
576 \brief Insert a range of values to the index.
|
Chris@16
|
577
|
Chris@16
|
578 \param rng The range of values.
|
Chris@16
|
579
|
Chris@16
|
580 \par Throws
|
Chris@16
|
581 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
582 \li If allocation throws or returns invalid value.
|
Chris@16
|
583
|
Chris@16
|
584 \warning
|
Chris@16
|
585 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
586 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
587 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
588 some of them may return invalid data.
|
Chris@16
|
589 */
|
Chris@16
|
590 template <typename Range>
|
Chris@16
|
591 inline void insert(Range const& rng)
|
Chris@16
|
592 {
|
Chris@16
|
593 BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range));
|
Chris@16
|
594
|
Chris@16
|
595 if ( !m_members.root )
|
Chris@16
|
596 this->raw_create();
|
Chris@16
|
597
|
Chris@16
|
598 typedef typename boost::range_const_iterator<Range>::type It;
|
Chris@16
|
599 for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
|
Chris@16
|
600 this->raw_insert(*it);
|
Chris@16
|
601 }
|
Chris@16
|
602
|
Chris@16
|
603 /*!
|
Chris@16
|
604 \brief Remove a value from the container.
|
Chris@16
|
605
|
Chris@16
|
606 In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
607 this method removes only one value from the container.
|
Chris@16
|
608
|
Chris@16
|
609 \param value The value which will be removed from the container.
|
Chris@16
|
610
|
Chris@16
|
611 \return 1 if the value was removed, 0 otherwise.
|
Chris@16
|
612
|
Chris@16
|
613 \par Throws
|
Chris@16
|
614 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
615 \li If allocation throws or returns invalid value.
|
Chris@16
|
616
|
Chris@16
|
617 \warning
|
Chris@16
|
618 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
619 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
620 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
621 some of them may return invalid data.
|
Chris@16
|
622 */
|
Chris@16
|
623 inline size_type remove(value_type const& value)
|
Chris@16
|
624 {
|
Chris@16
|
625 return this->raw_remove(value);
|
Chris@16
|
626 }
|
Chris@16
|
627
|
Chris@16
|
628 /*!
|
Chris@16
|
629 \brief Remove a range of values from the container.
|
Chris@16
|
630
|
Chris@16
|
631 In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
632 it doesn't take iterators pointing to values stored in this container. It removes values equal
|
Chris@16
|
633 to these passed as a range. Furthermore this method removes only one value for each one passed
|
Chris@16
|
634 in the range, not all equal values.
|
Chris@16
|
635
|
Chris@16
|
636 \param first The beginning of the range of values.
|
Chris@16
|
637 \param last The end of the range of values.
|
Chris@16
|
638
|
Chris@16
|
639 \return The number of removed values.
|
Chris@16
|
640
|
Chris@16
|
641 \par Throws
|
Chris@16
|
642 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
643 \li If allocation throws or returns invalid value.
|
Chris@16
|
644
|
Chris@16
|
645 \warning
|
Chris@16
|
646 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
647 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
648 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
649 some of them may return invalid data.
|
Chris@16
|
650 */
|
Chris@16
|
651 template <typename Iterator>
|
Chris@16
|
652 inline size_type remove(Iterator first, Iterator last)
|
Chris@16
|
653 {
|
Chris@16
|
654 size_type result = 0;
|
Chris@16
|
655 for ( ; first != last ; ++first )
|
Chris@16
|
656 result += this->raw_remove(*first);
|
Chris@16
|
657 return result;
|
Chris@16
|
658 }
|
Chris@16
|
659
|
Chris@16
|
660 /*!
|
Chris@16
|
661 \brief Remove a range of values from the container.
|
Chris@16
|
662
|
Chris@16
|
663 In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
664 it removes values equal to these passed as a range. Furthermore, this method removes only
|
Chris@16
|
665 one value for each one passed in the range, not all equal values.
|
Chris@16
|
666
|
Chris@16
|
667 \param rng The range of values.
|
Chris@16
|
668
|
Chris@16
|
669 \return The number of removed values.
|
Chris@16
|
670
|
Chris@16
|
671 \par Throws
|
Chris@16
|
672 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
673 \li If allocation throws or returns invalid value.
|
Chris@16
|
674
|
Chris@16
|
675 \warning
|
Chris@16
|
676 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
677 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
678 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
679 some of them may return invalid data.
|
Chris@16
|
680 */
|
Chris@16
|
681 template <typename Range>
|
Chris@16
|
682 inline size_type remove(Range const& rng)
|
Chris@16
|
683 {
|
Chris@16
|
684 BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range));
|
Chris@16
|
685
|
Chris@16
|
686 size_type result = 0;
|
Chris@16
|
687 typedef typename boost::range_const_iterator<Range>::type It;
|
Chris@16
|
688 for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
|
Chris@16
|
689 result += this->raw_remove(*it);
|
Chris@16
|
690 return result;
|
Chris@16
|
691 }
|
Chris@16
|
692
|
Chris@16
|
693 /*!
|
Chris@16
|
694 \brief Finds values meeting passed predicates e.g. nearest to some Point and/or intersecting some Box.
|
Chris@16
|
695
|
Chris@16
|
696 This query function performs spatial and k-nearest neighbor searches. It allows to pass a set of predicates.
|
Chris@16
|
697 Values will be returned only if all predicates are met.
|
Chris@16
|
698
|
Chris@16
|
699 <b>Spatial predicates</b>
|
Chris@16
|
700
|
Chris@16
|
701 Spatial predicates may be generated by one of the functions listed below:
|
Chris@16
|
702 \li \c boost::geometry::index::contains(),
|
Chris@16
|
703 \li \c boost::geometry::index::covered_by(),
|
Chris@16
|
704 \li \c boost::geometry::index::covers(),
|
Chris@16
|
705 \li \c boost::geometry::index::disjoint(),
|
Chris@16
|
706 \li \c boost::geometry::index::intersects(),
|
Chris@16
|
707 \li \c boost::geometry::index::overlaps(),
|
Chris@16
|
708 \li \c boost::geometry::index::within(),
|
Chris@16
|
709
|
Chris@16
|
710 It is possible to negate spatial predicates:
|
Chris@16
|
711 \li <tt>! boost::geometry::index::contains()</tt>,
|
Chris@16
|
712 \li <tt>! boost::geometry::index::covered_by()</tt>,
|
Chris@16
|
713 \li <tt>! boost::geometry::index::covers()</tt>,
|
Chris@16
|
714 \li <tt>! boost::geometry::index::disjoint()</tt>,
|
Chris@16
|
715 \li <tt>! boost::geometry::index::intersects()</tt>,
|
Chris@16
|
716 \li <tt>! boost::geometry::index::overlaps()</tt>,
|
Chris@16
|
717 \li <tt>! boost::geometry::index::within()</tt>
|
Chris@16
|
718
|
Chris@16
|
719 <b>Satisfies predicate</b>
|
Chris@16
|
720
|
Chris@16
|
721 This is a special kind of predicate which allows to pass a user-defined function or function object which checks
|
Chris@16
|
722 if Value should be returned by the query. It's generated by:
|
Chris@16
|
723 \li \c boost::geometry::index::satisfies().
|
Chris@16
|
724
|
Chris@16
|
725 <b>Nearest predicate</b>
|
Chris@16
|
726
|
Chris@16
|
727 If the nearest predicate is passed a k-nearest neighbor search will be performed. This query will result
|
Chris@16
|
728 in returning k values to the output iterator. Only one nearest predicate may be passed to the query.
|
Chris@16
|
729 It may be generated by:
|
Chris@16
|
730 \li \c boost::geometry::index::nearest().
|
Chris@16
|
731
|
Chris@16
|
732 <b>Connecting predicates</b>
|
Chris@16
|
733
|
Chris@16
|
734 Predicates may be passed together connected with \c operator&&().
|
Chris@16
|
735
|
Chris@16
|
736 \par Example
|
Chris@16
|
737 \verbatim
|
Chris@16
|
738 // return elements intersecting box
|
Chris@16
|
739 tree.query(bgi::intersects(box), std::back_inserter(result));
|
Chris@16
|
740 // return elements intersecting poly but not within box
|
Chris@16
|
741 tree.query(bgi::intersects(poly) && !bgi::within(box), std::back_inserter(result));
|
Chris@16
|
742 // return elements overlapping box and meeting my_fun unary predicate
|
Chris@16
|
743 tree.query(bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
|
Chris@16
|
744 // return 5 elements nearest to pt and elements are intersecting box
|
Chris@16
|
745 tree.query(bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
|
Chris@16
|
746 \endverbatim
|
Chris@16
|
747
|
Chris@16
|
748 \par Throws
|
Chris@16
|
749 If Value copy constructor or copy assignment throws.
|
Chris@16
|
750 If predicates copy throws.
|
Chris@16
|
751
|
Chris@16
|
752 \warning
|
Chris@16
|
753 Only one \c nearest() perdicate may be passed to the query. Passing more of them results in compile-time error.
|
Chris@16
|
754
|
Chris@16
|
755 \param predicates Predicates.
|
Chris@16
|
756 \param out_it The output iterator, e.g. generated by std::back_inserter().
|
Chris@16
|
757
|
Chris@16
|
758 \return The number of values found.
|
Chris@16
|
759 */
|
Chris@16
|
760 template <typename Predicates, typename OutIter>
|
Chris@16
|
761 size_type query(Predicates const& predicates, OutIter out_it) const
|
Chris@16
|
762 {
|
Chris@16
|
763 if ( !m_members.root )
|
Chris@16
|
764 return 0;
|
Chris@16
|
765
|
Chris@16
|
766 static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
|
Chris@16
|
767 static const bool is_distance_predicate = 0 < distance_predicates_count;
|
Chris@16
|
768 BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
|
Chris@16
|
769
|
Chris@16
|
770 return query_dispatch(predicates, out_it, boost::mpl::bool_<is_distance_predicate>());
|
Chris@16
|
771 }
|
Chris@16
|
772
|
Chris@16
|
773 /*!
|
Chris@16
|
774 \brief Returns the query iterator pointing at the begin of the query range.
|
Chris@16
|
775
|
Chris@16
|
776 This method returns the iterator which may be used to perform iterative queries. For the information
|
Chris@16
|
777 about the predicates which may be passed to this method see query().
|
Chris@16
|
778
|
Chris@16
|
779 \par Example
|
Chris@16
|
780 \verbatim
|
Chris@16
|
781 for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
|
Chris@16
|
782 it != tree.qend() ; ++it )
|
Chris@16
|
783 {
|
Chris@16
|
784 // do something with value
|
Chris@16
|
785 if ( has_enough_nearest_values() )
|
Chris@16
|
786 break;
|
Chris@16
|
787 }
|
Chris@16
|
788 \endverbatim
|
Chris@16
|
789
|
Chris@16
|
790 \par Throws
|
Chris@16
|
791 If predicates copy throws.
|
Chris@16
|
792 If allocation throws.
|
Chris@16
|
793
|
Chris@16
|
794 \param predicates Predicates.
|
Chris@16
|
795
|
Chris@16
|
796 \return The iterator pointing at the begin of the query range.
|
Chris@16
|
797 */
|
Chris@16
|
798 template <typename Predicates>
|
Chris@16
|
799 const_query_iterator qbegin(Predicates const& predicates) const
|
Chris@16
|
800 {
|
Chris@16
|
801 return const_query_iterator(qbegin_(predicates));
|
Chris@16
|
802 }
|
Chris@16
|
803
|
Chris@16
|
804 /*!
|
Chris@16
|
805 \brief Returns the query iterator pointing at the end of the query range.
|
Chris@16
|
806
|
Chris@16
|
807 This method returns the iterator which may be used to check if the query has ended.
|
Chris@16
|
808
|
Chris@16
|
809 \par Example
|
Chris@16
|
810 \verbatim
|
Chris@16
|
811 for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
|
Chris@16
|
812 it != tree.qend() ; ++it )
|
Chris@16
|
813 {
|
Chris@16
|
814 // do something with value
|
Chris@16
|
815 if ( has_enough_nearest_values() )
|
Chris@16
|
816 break;
|
Chris@16
|
817 }
|
Chris@16
|
818 \endverbatim
|
Chris@16
|
819
|
Chris@16
|
820 \par Throws
|
Chris@16
|
821 Nothing
|
Chris@16
|
822
|
Chris@16
|
823 \return The iterator pointing at the end of the query range.
|
Chris@16
|
824 */
|
Chris@16
|
825 const_query_iterator qend() const
|
Chris@16
|
826 {
|
Chris@16
|
827 return const_query_iterator();
|
Chris@16
|
828 }
|
Chris@16
|
829
|
Chris@16
|
830 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
|
Chris@16
|
831 private:
|
Chris@16
|
832 #endif
|
Chris@16
|
833 /*!
|
Chris@16
|
834 \brief Returns the query iterator pointing at the begin of the query range.
|
Chris@16
|
835
|
Chris@16
|
836 This method returns the iterator which may be used to perform iterative queries. For the information
|
Chris@16
|
837 about the predicates which may be passed to this method see query().
|
Chris@16
|
838
|
Chris@16
|
839 The type of the returned iterator depends on the type of passed Predicates but the iterator of this type
|
Chris@16
|
840 may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator
|
Chris@16
|
841 returned by this method you may get the type e.g. by using C++11 decltype or Boost.Typeof library.
|
Chris@16
|
842 This iterator may be compared with iterators returned by both versions of qend() method.
|
Chris@16
|
843
|
Chris@16
|
844 \par Example
|
Chris@16
|
845 \verbatim
|
Chris@16
|
846 // Store the result in the container using std::copy() - it requires both iterators of the same type
|
Chris@16
|
847 std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
|
Chris@16
|
848
|
Chris@16
|
849 // Store the result in the container using std::copy() and type-erased iterators
|
Chris@16
|
850 Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
|
Chris@16
|
851 Rtree::const_query_iterator last = tree.qend();
|
Chris@16
|
852 std::copy(first, last, std::back_inserter(result));
|
Chris@16
|
853
|
Chris@16
|
854 // Boost.Typeof
|
Chris@16
|
855 typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
|
Chris@16
|
856 for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
|
Chris@16
|
857 {
|
Chris@16
|
858 // do something with value
|
Chris@16
|
859 if ( has_enough_nearest_values() )
|
Chris@16
|
860 break;
|
Chris@16
|
861 }
|
Chris@16
|
862 \endverbatim
|
Chris@16
|
863
|
Chris@16
|
864 \par Throws
|
Chris@16
|
865 If predicates copy throws.
|
Chris@16
|
866 If allocation throws.
|
Chris@16
|
867
|
Chris@16
|
868 \param predicates Predicates.
|
Chris@16
|
869
|
Chris@16
|
870 \return The iterator pointing at the begin of the query range.
|
Chris@16
|
871 */
|
Chris@16
|
872 template <typename Predicates>
|
Chris@16
|
873 typename boost::mpl::if_c<
|
Chris@16
|
874 detail::predicates_count_distance<Predicates>::value == 0,
|
Chris@16
|
875 detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
|
Chris@16
|
876 detail::rtree::iterators::distance_query_iterator<
|
Chris@16
|
877 value_type, options_type, translator_type, box_type, allocators_type, Predicates,
|
Chris@16
|
878 detail::predicates_find_distance<Predicates>::value
|
Chris@16
|
879 >
|
Chris@16
|
880 >::type
|
Chris@16
|
881 qbegin_(Predicates const& predicates) const
|
Chris@16
|
882 {
|
Chris@16
|
883 static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
|
Chris@16
|
884 BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
|
Chris@16
|
885
|
Chris@16
|
886 typedef typename boost::mpl::if_c<
|
Chris@16
|
887 detail::predicates_count_distance<Predicates>::value == 0,
|
Chris@16
|
888 detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
|
Chris@16
|
889 detail::rtree::iterators::distance_query_iterator<
|
Chris@16
|
890 value_type, options_type, translator_type, box_type, allocators_type, Predicates,
|
Chris@16
|
891 detail::predicates_find_distance<Predicates>::value
|
Chris@16
|
892 >
|
Chris@16
|
893 >::type iterator_type;
|
Chris@16
|
894
|
Chris@16
|
895 if ( !m_members.root )
|
Chris@16
|
896 return iterator_type(m_members.translator(), predicates);
|
Chris@16
|
897
|
Chris@16
|
898 return iterator_type(m_members.root, m_members.translator(), predicates);
|
Chris@16
|
899 }
|
Chris@16
|
900
|
Chris@16
|
901 /*!
|
Chris@16
|
902 \brief Returns the query iterator pointing at the end of the query range.
|
Chris@16
|
903
|
Chris@16
|
904 This method returns the iterator which may be used to perform iterative queries. For the information
|
Chris@16
|
905 about the predicates which may be passed to this method see query().
|
Chris@16
|
906
|
Chris@16
|
907 The type of the returned iterator depends on the type of passed Predicates but the iterator of this type
|
Chris@16
|
908 may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator
|
Chris@16
|
909 returned by this method you may get the type e.g. by using C++11 decltype or Boost.Typeof library.
|
Chris@16
|
910
|
Chris@16
|
911 The type of the iterator returned by this method is the same as the one returned by qbegin() to which
|
Chris@16
|
912 the same predicates were passed.
|
Chris@16
|
913
|
Chris@16
|
914 \par Example
|
Chris@16
|
915 \verbatim
|
Chris@16
|
916 // Store the result in the container using std::copy() - it requires both iterators of the same type
|
Chris@16
|
917 std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
|
Chris@16
|
918 \endverbatim
|
Chris@16
|
919
|
Chris@16
|
920 \par Throws
|
Chris@16
|
921 If predicates copy throws.
|
Chris@16
|
922
|
Chris@16
|
923 \param predicates Predicates.
|
Chris@16
|
924
|
Chris@16
|
925 \return The iterator pointing at the end of the query range.
|
Chris@16
|
926 */
|
Chris@16
|
927 template <typename Predicates>
|
Chris@16
|
928 typename boost::mpl::if_c<
|
Chris@16
|
929 detail::predicates_count_distance<Predicates>::value == 0,
|
Chris@16
|
930 detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
|
Chris@16
|
931 detail::rtree::iterators::distance_query_iterator<
|
Chris@16
|
932 value_type, options_type, translator_type, box_type, allocators_type, Predicates,
|
Chris@16
|
933 detail::predicates_find_distance<Predicates>::value
|
Chris@16
|
934 >
|
Chris@16
|
935 >::type
|
Chris@16
|
936 qend_(Predicates const& predicates) const
|
Chris@16
|
937 {
|
Chris@16
|
938 static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
|
Chris@16
|
939 BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
|
Chris@16
|
940
|
Chris@16
|
941 typedef typename boost::mpl::if_c<
|
Chris@16
|
942 detail::predicates_count_distance<Predicates>::value == 0,
|
Chris@16
|
943 detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
|
Chris@16
|
944 detail::rtree::iterators::distance_query_iterator<
|
Chris@16
|
945 value_type, options_type, translator_type, box_type, allocators_type, Predicates,
|
Chris@16
|
946 detail::predicates_find_distance<Predicates>::value
|
Chris@16
|
947 >
|
Chris@16
|
948 >::type iterator_type;
|
Chris@16
|
949
|
Chris@16
|
950 return iterator_type(m_members.translator(), predicates);
|
Chris@16
|
951 }
|
Chris@16
|
952
|
Chris@16
|
953 /*!
|
Chris@16
|
954 \brief Returns the query iterator pointing at the end of the query range.
|
Chris@16
|
955
|
Chris@16
|
956 This method returns the iterator which may be compared with the iterator returned by qbegin() in order to
|
Chris@16
|
957 check if the query has ended.
|
Chris@16
|
958
|
Chris@16
|
959 The type of the returned iterator is different than the type returned by qbegin() but the iterator of this type
|
Chris@16
|
960 may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator returned by this
|
Chris@16
|
961 method, which most certainly will be faster than the type-erased iterator, you may get the type
|
Chris@16
|
962 e.g. by using C++11 decltype or Boost.Typeof library.
|
Chris@16
|
963
|
Chris@16
|
964 The type of the iterator returned by this method is dfferent than the type returned by qbegin().
|
Chris@16
|
965
|
Chris@16
|
966 \par Example
|
Chris@16
|
967 \verbatim
|
Chris@16
|
968 // Store the result in the container using std::copy() and type-erased iterators
|
Chris@16
|
969 Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
|
Chris@16
|
970 Rtree::const_query_iterator last = tree.qend();
|
Chris@16
|
971 std::copy(first, last, std::back_inserter(result));
|
Chris@16
|
972
|
Chris@16
|
973 // Boost.Typeof
|
Chris@16
|
974 typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
|
Chris@16
|
975 for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
|
Chris@16
|
976 {
|
Chris@16
|
977 // do something with value
|
Chris@16
|
978 if ( has_enough_nearest_values() )
|
Chris@16
|
979 break;
|
Chris@16
|
980 }
|
Chris@16
|
981 \endverbatim
|
Chris@16
|
982
|
Chris@16
|
983 \par Throws
|
Chris@16
|
984 Nothing
|
Chris@16
|
985
|
Chris@16
|
986 \return The iterator pointing at the end of the query range.
|
Chris@16
|
987 */
|
Chris@16
|
988 detail::rtree::iterators::end_query_iterator<value_type, allocators_type>
|
Chris@16
|
989 qend_() const
|
Chris@16
|
990 {
|
Chris@16
|
991 return detail::rtree::iterators::end_query_iterator<value_type, allocators_type>();
|
Chris@16
|
992 }
|
Chris@16
|
993
|
Chris@16
|
994 public:
|
Chris@16
|
995
|
Chris@16
|
996 /*!
|
Chris@16
|
997 \brief Returns the number of stored values.
|
Chris@16
|
998
|
Chris@16
|
999 \return The number of stored values.
|
Chris@16
|
1000
|
Chris@16
|
1001 \par Throws
|
Chris@16
|
1002 Nothing.
|
Chris@16
|
1003 */
|
Chris@16
|
1004 inline size_type size() const
|
Chris@16
|
1005 {
|
Chris@16
|
1006 return m_members.values_count;
|
Chris@16
|
1007 }
|
Chris@16
|
1008
|
Chris@16
|
1009 /*!
|
Chris@16
|
1010 \brief Query if the container is empty.
|
Chris@16
|
1011
|
Chris@16
|
1012 \return true if the container is empty.
|
Chris@16
|
1013
|
Chris@16
|
1014 \par Throws
|
Chris@16
|
1015 Nothing.
|
Chris@16
|
1016 */
|
Chris@16
|
1017 inline bool empty() const
|
Chris@16
|
1018 {
|
Chris@16
|
1019 return 0 == m_members.values_count;
|
Chris@16
|
1020 }
|
Chris@16
|
1021
|
Chris@16
|
1022 /*!
|
Chris@16
|
1023 \brief Removes all values stored in the container.
|
Chris@16
|
1024
|
Chris@16
|
1025 \par Throws
|
Chris@16
|
1026 Nothing.
|
Chris@16
|
1027 */
|
Chris@16
|
1028 inline void clear()
|
Chris@16
|
1029 {
|
Chris@16
|
1030 this->raw_destroy(*this);
|
Chris@16
|
1031 }
|
Chris@16
|
1032
|
Chris@16
|
1033 /*!
|
Chris@16
|
1034 \brief Returns the box able to contain all values stored in the container.
|
Chris@16
|
1035
|
Chris@16
|
1036 Returns the box able to contain all values stored in the container.
|
Chris@16
|
1037 If the container is empty the result of \c geometry::assign_inverse() is returned.
|
Chris@16
|
1038
|
Chris@16
|
1039 \return The box able to contain all values stored in the container or an invalid box if
|
Chris@16
|
1040 there are no values in the container.
|
Chris@16
|
1041
|
Chris@16
|
1042 \par Throws
|
Chris@16
|
1043 Nothing.
|
Chris@16
|
1044 */
|
Chris@16
|
1045 inline bounds_type bounds() const
|
Chris@16
|
1046 {
|
Chris@16
|
1047 bounds_type result;
|
Chris@16
|
1048 if ( !m_members.root )
|
Chris@16
|
1049 {
|
Chris@16
|
1050 geometry::assign_inverse(result);
|
Chris@16
|
1051 return result;
|
Chris@16
|
1052 }
|
Chris@16
|
1053
|
Chris@16
|
1054 detail::rtree::visitors::children_box<value_type, options_type, translator_type, box_type, allocators_type>
|
Chris@16
|
1055 box_v(result, m_members.translator());
|
Chris@16
|
1056 detail::rtree::apply_visitor(box_v, *m_members.root);
|
Chris@16
|
1057
|
Chris@16
|
1058 return result;
|
Chris@16
|
1059 }
|
Chris@16
|
1060
|
Chris@16
|
1061 /*!
|
Chris@16
|
1062 \brief Count Values or Indexables stored in the container.
|
Chris@16
|
1063
|
Chris@16
|
1064 For indexable_type it returns the number of values which indexables equals the parameter.
|
Chris@16
|
1065 For value_type it returns the number of values which equals the parameter.
|
Chris@16
|
1066
|
Chris@16
|
1067 \param vori The value or indexable which will be counted.
|
Chris@16
|
1068
|
Chris@16
|
1069 \return The number of values found.
|
Chris@16
|
1070
|
Chris@16
|
1071 \par Throws
|
Chris@16
|
1072 Nothing.
|
Chris@16
|
1073 */
|
Chris@16
|
1074 template <typename ValueOrIndexable>
|
Chris@16
|
1075 size_type count(ValueOrIndexable const& vori) const
|
Chris@16
|
1076 {
|
Chris@16
|
1077 if ( !m_members.root )
|
Chris@16
|
1078 return 0;
|
Chris@16
|
1079
|
Chris@16
|
1080 detail::rtree::visitors::count<ValueOrIndexable, value_type, options_type, translator_type, box_type, allocators_type>
|
Chris@16
|
1081 count_v(vori, m_members.translator());
|
Chris@16
|
1082
|
Chris@16
|
1083 detail::rtree::apply_visitor(count_v, *m_members.root);
|
Chris@16
|
1084
|
Chris@16
|
1085 return count_v.found_count;
|
Chris@16
|
1086 }
|
Chris@16
|
1087
|
Chris@16
|
1088 /*!
|
Chris@16
|
1089 \brief Returns parameters.
|
Chris@16
|
1090
|
Chris@16
|
1091 \return The parameters object.
|
Chris@16
|
1092
|
Chris@16
|
1093 \par Throws
|
Chris@16
|
1094 Nothing.
|
Chris@16
|
1095 */
|
Chris@16
|
1096 inline parameters_type parameters() const
|
Chris@16
|
1097 {
|
Chris@16
|
1098 return m_members.parameters();
|
Chris@16
|
1099 }
|
Chris@16
|
1100
|
Chris@16
|
1101 /*!
|
Chris@16
|
1102 \brief Returns function retrieving Indexable from Value.
|
Chris@16
|
1103
|
Chris@16
|
1104 \return The indexable_getter object.
|
Chris@16
|
1105
|
Chris@16
|
1106 \par Throws
|
Chris@16
|
1107 Nothing.
|
Chris@16
|
1108 */
|
Chris@16
|
1109 indexable_getter indexable_get() const
|
Chris@16
|
1110 {
|
Chris@16
|
1111 return m_members.indexable_getter();
|
Chris@16
|
1112 }
|
Chris@16
|
1113
|
Chris@16
|
1114 /*!
|
Chris@16
|
1115 \brief Returns function comparing Values
|
Chris@16
|
1116
|
Chris@16
|
1117 \return The value_equal function.
|
Chris@16
|
1118
|
Chris@16
|
1119 \par Throws
|
Chris@16
|
1120 Nothing.
|
Chris@16
|
1121 */
|
Chris@16
|
1122 value_equal value_eq() const
|
Chris@16
|
1123 {
|
Chris@16
|
1124 return m_members.equal_to();
|
Chris@16
|
1125 }
|
Chris@16
|
1126
|
Chris@16
|
1127 /*!
|
Chris@16
|
1128 \brief Returns allocator used by the rtree.
|
Chris@16
|
1129
|
Chris@16
|
1130 \return The allocator.
|
Chris@16
|
1131
|
Chris@16
|
1132 \par Throws
|
Chris@16
|
1133 If allocator copy constructor throws.
|
Chris@16
|
1134 */
|
Chris@16
|
1135 allocator_type get_allocator() const
|
Chris@16
|
1136 {
|
Chris@16
|
1137 return m_members.allocators().allocator();
|
Chris@16
|
1138 }
|
Chris@16
|
1139
|
Chris@16
|
1140 private:
|
Chris@16
|
1141
|
Chris@16
|
1142 /*!
|
Chris@16
|
1143 \brief Returns the translator object.
|
Chris@16
|
1144
|
Chris@16
|
1145 \return The translator object.
|
Chris@16
|
1146
|
Chris@16
|
1147 \par Throws
|
Chris@16
|
1148 Nothing.
|
Chris@16
|
1149 */
|
Chris@16
|
1150 inline translator_type translator() const
|
Chris@16
|
1151 {
|
Chris@16
|
1152 return m_members.translator();
|
Chris@16
|
1153 }
|
Chris@16
|
1154
|
Chris@16
|
1155 /*!
|
Chris@16
|
1156 \brief Apply a visitor to the nodes structure in order to perform some operator.
|
Chris@16
|
1157
|
Chris@16
|
1158 This function is not a part of the 'official' interface. However it makes
|
Chris@16
|
1159 possible e.g. to pass a visitor drawing the tree structure.
|
Chris@16
|
1160
|
Chris@16
|
1161 \param visitor The visitor object.
|
Chris@16
|
1162
|
Chris@16
|
1163 \par Throws
|
Chris@16
|
1164 If Visitor::operator() throws.
|
Chris@16
|
1165 */
|
Chris@16
|
1166 template <typename Visitor>
|
Chris@16
|
1167 inline void apply_visitor(Visitor & visitor) const
|
Chris@16
|
1168 {
|
Chris@16
|
1169 if ( m_members.root )
|
Chris@16
|
1170 detail::rtree::apply_visitor(visitor, *m_members.root);
|
Chris@16
|
1171 }
|
Chris@16
|
1172
|
Chris@16
|
1173 /*!
|
Chris@16
|
1174 \brief Returns the depth of the R-tree.
|
Chris@16
|
1175
|
Chris@16
|
1176 This function is not a part of the 'official' interface.
|
Chris@16
|
1177
|
Chris@16
|
1178 \return The depth of the R-tree.
|
Chris@16
|
1179
|
Chris@16
|
1180 \par Throws
|
Chris@16
|
1181 Nothing.
|
Chris@16
|
1182 */
|
Chris@16
|
1183 inline size_type depth() const
|
Chris@16
|
1184 {
|
Chris@16
|
1185 return m_members.leafs_level;
|
Chris@16
|
1186 }
|
Chris@16
|
1187
|
Chris@16
|
1188 private:
|
Chris@16
|
1189
|
Chris@16
|
1190 /*!
|
Chris@16
|
1191 \pre Root node must exist - m_root != 0.
|
Chris@16
|
1192
|
Chris@16
|
1193 \brief Insert a value to the index.
|
Chris@16
|
1194
|
Chris@16
|
1195 \param value The value which will be stored in the container.
|
Chris@16
|
1196
|
Chris@16
|
1197 \par Exception-safety
|
Chris@16
|
1198 basic
|
Chris@16
|
1199 */
|
Chris@16
|
1200 inline void raw_insert(value_type const& value)
|
Chris@16
|
1201 {
|
Chris@16
|
1202 BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
|
Chris@16
|
1203 BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(m_members.translator()(value)), "Indexable is invalid");
|
Chris@16
|
1204
|
Chris@16
|
1205 detail::rtree::visitors::insert<
|
Chris@16
|
1206 value_type,
|
Chris@16
|
1207 value_type, options_type, translator_type, box_type, allocators_type,
|
Chris@16
|
1208 typename options_type::insert_tag
|
Chris@16
|
1209 > insert_v(m_members.root, m_members.leafs_level, value,
|
Chris@16
|
1210 m_members.parameters(), m_members.translator(), m_members.allocators());
|
Chris@16
|
1211
|
Chris@16
|
1212 detail::rtree::apply_visitor(insert_v, *m_members.root);
|
Chris@16
|
1213
|
Chris@16
|
1214 // TODO
|
Chris@16
|
1215 // Think about this: If exception is thrown, may the root be removed?
|
Chris@16
|
1216 // Or it is just cleared?
|
Chris@16
|
1217
|
Chris@16
|
1218 // TODO
|
Chris@16
|
1219 // If exception is thrown, m_values_count may be invalid
|
Chris@16
|
1220 ++m_members.values_count;
|
Chris@16
|
1221 }
|
Chris@16
|
1222
|
Chris@16
|
1223 /*!
|
Chris@16
|
1224 \brief Remove the value from the container.
|
Chris@16
|
1225
|
Chris@16
|
1226 \param value The value which will be removed from the container.
|
Chris@16
|
1227
|
Chris@16
|
1228 \par Exception-safety
|
Chris@16
|
1229 basic
|
Chris@16
|
1230 */
|
Chris@16
|
1231 inline size_type raw_remove(value_type const& value)
|
Chris@16
|
1232 {
|
Chris@16
|
1233 // TODO: awulkiew - assert for correct value (indexable) ?
|
Chris@16
|
1234 BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
|
Chris@16
|
1235
|
Chris@16
|
1236 detail::rtree::visitors::remove<
|
Chris@16
|
1237 value_type, options_type, translator_type, box_type, allocators_type
|
Chris@16
|
1238 > remove_v(m_members.root, m_members.leafs_level, value,
|
Chris@16
|
1239 m_members.parameters(), m_members.translator(), m_members.allocators());
|
Chris@16
|
1240
|
Chris@16
|
1241 detail::rtree::apply_visitor(remove_v, *m_members.root);
|
Chris@16
|
1242
|
Chris@16
|
1243 // If exception is thrown, m_values_count may be invalid
|
Chris@16
|
1244
|
Chris@16
|
1245 if ( remove_v.is_value_removed() )
|
Chris@16
|
1246 {
|
Chris@16
|
1247 BOOST_GEOMETRY_INDEX_ASSERT(0 < m_members.values_count, "unexpected state");
|
Chris@16
|
1248
|
Chris@16
|
1249 --m_members.values_count;
|
Chris@16
|
1250
|
Chris@16
|
1251 return 1;
|
Chris@16
|
1252 }
|
Chris@16
|
1253
|
Chris@16
|
1254 return 0;
|
Chris@16
|
1255 }
|
Chris@16
|
1256
|
Chris@16
|
1257 /*!
|
Chris@16
|
1258 \brief Create an empty R-tree i.e. new empty root node and clear other attributes.
|
Chris@16
|
1259
|
Chris@16
|
1260 \par Exception-safety
|
Chris@16
|
1261 strong
|
Chris@16
|
1262 */
|
Chris@16
|
1263 inline void raw_create()
|
Chris@16
|
1264 {
|
Chris@16
|
1265 BOOST_GEOMETRY_INDEX_ASSERT(0 == m_members.root, "the tree is already created");
|
Chris@16
|
1266
|
Chris@16
|
1267 m_members.root = detail::rtree::create_node<allocators_type, leaf>::apply(m_members.allocators()); // MAY THROW (N: alloc)
|
Chris@16
|
1268 m_members.values_count = 0;
|
Chris@16
|
1269 m_members.leafs_level = 0;
|
Chris@16
|
1270 }
|
Chris@16
|
1271
|
Chris@16
|
1272 /*!
|
Chris@16
|
1273 \brief Destroy the R-tree i.e. all nodes and clear attributes.
|
Chris@16
|
1274
|
Chris@16
|
1275 \param t The container which is going to be destroyed.
|
Chris@16
|
1276
|
Chris@16
|
1277 \par Exception-safety
|
Chris@16
|
1278 nothrow
|
Chris@16
|
1279 */
|
Chris@16
|
1280 inline void raw_destroy(rtree & t)
|
Chris@16
|
1281 {
|
Chris@16
|
1282 if ( t.m_members.root )
|
Chris@16
|
1283 {
|
Chris@16
|
1284 detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
|
Chris@16
|
1285 del_v(t.m_members.root, t.m_members.allocators());
|
Chris@16
|
1286 detail::rtree::apply_visitor(del_v, *t.m_members.root);
|
Chris@16
|
1287
|
Chris@16
|
1288 t.m_members.root = 0;
|
Chris@16
|
1289 }
|
Chris@16
|
1290 t.m_members.values_count = 0;
|
Chris@16
|
1291 t.m_members.leafs_level = 0;
|
Chris@16
|
1292 }
|
Chris@16
|
1293
|
Chris@16
|
1294 /*!
|
Chris@16
|
1295 \brief Copy the R-tree i.e. whole nodes structure, values and other attributes.
|
Chris@16
|
1296 It uses destination's allocators to create the new structure.
|
Chris@16
|
1297
|
Chris@16
|
1298 \param src The source R-tree.
|
Chris@16
|
1299 \param dst The destination R-tree.
|
Chris@16
|
1300 \param copy_tr_and_params If true, translator and parameters will also be copied.
|
Chris@16
|
1301
|
Chris@16
|
1302 \par Exception-safety
|
Chris@16
|
1303 strong
|
Chris@16
|
1304 */
|
Chris@16
|
1305 inline void raw_copy(rtree const& src, rtree & dst, bool copy_tr_and_params) const
|
Chris@16
|
1306 {
|
Chris@16
|
1307 detail::rtree::visitors::copy<value_type, options_type, translator_type, box_type, allocators_type>
|
Chris@16
|
1308 copy_v(dst.m_members.allocators());
|
Chris@16
|
1309
|
Chris@16
|
1310 if ( src.m_members.root )
|
Chris@16
|
1311 detail::rtree::apply_visitor(copy_v, *src.m_members.root); // MAY THROW (V, E: alloc, copy, N: alloc)
|
Chris@16
|
1312
|
Chris@16
|
1313 if ( copy_tr_and_params )
|
Chris@16
|
1314 {
|
Chris@16
|
1315 dst.m_members.indexable_getter() = src.m_members.indexable_getter();
|
Chris@16
|
1316 dst.m_members.equal_to() = src.m_members.equal_to();
|
Chris@16
|
1317 dst.m_members.parameters() = src.m_members.parameters();
|
Chris@16
|
1318 }
|
Chris@16
|
1319
|
Chris@16
|
1320 // TODO use node_auto_ptr
|
Chris@16
|
1321 if ( dst.m_members.root )
|
Chris@16
|
1322 {
|
Chris@16
|
1323 detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
|
Chris@16
|
1324 del_v(dst.m_members.root, dst.m_members.allocators());
|
Chris@16
|
1325 detail::rtree::apply_visitor(del_v, *dst.m_members.root);
|
Chris@16
|
1326 dst.m_members.root = 0;
|
Chris@16
|
1327 }
|
Chris@16
|
1328
|
Chris@16
|
1329 dst.m_members.root = copy_v.result;
|
Chris@16
|
1330 dst.m_members.values_count = src.m_members.values_count;
|
Chris@16
|
1331 dst.m_members.leafs_level = src.m_members.leafs_level;
|
Chris@16
|
1332 }
|
Chris@16
|
1333
|
Chris@16
|
1334 /*!
|
Chris@16
|
1335 \brief Return values meeting predicates.
|
Chris@16
|
1336
|
Chris@16
|
1337 \par Exception-safety
|
Chris@16
|
1338 strong
|
Chris@16
|
1339 */
|
Chris@16
|
1340 template <typename Predicates, typename OutIter>
|
Chris@16
|
1341 size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<false> const& /*is_distance_predicate*/) const
|
Chris@16
|
1342 {
|
Chris@16
|
1343 detail::rtree::visitors::spatial_query<value_type, options_type, translator_type, box_type, allocators_type, Predicates, OutIter>
|
Chris@16
|
1344 find_v(m_members.translator(), predicates, out_it);
|
Chris@16
|
1345
|
Chris@16
|
1346 detail::rtree::apply_visitor(find_v, *m_members.root);
|
Chris@16
|
1347
|
Chris@16
|
1348 return find_v.found_count;
|
Chris@16
|
1349 }
|
Chris@16
|
1350
|
Chris@16
|
1351 /*!
|
Chris@16
|
1352 \brief Perform nearest neighbour search.
|
Chris@16
|
1353
|
Chris@16
|
1354 \par Exception-safety
|
Chris@16
|
1355 strong
|
Chris@16
|
1356 */
|
Chris@16
|
1357 template <typename Predicates, typename OutIter>
|
Chris@16
|
1358 size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<true> const& /*is_distance_predicate*/) const
|
Chris@16
|
1359 {
|
Chris@16
|
1360 static const unsigned distance_predicate_index = detail::predicates_find_distance<Predicates>::value;
|
Chris@16
|
1361 detail::rtree::visitors::distance_query<
|
Chris@16
|
1362 value_type,
|
Chris@16
|
1363 options_type,
|
Chris@16
|
1364 translator_type,
|
Chris@16
|
1365 box_type,
|
Chris@16
|
1366 allocators_type,
|
Chris@16
|
1367 Predicates,
|
Chris@16
|
1368 distance_predicate_index,
|
Chris@16
|
1369 OutIter
|
Chris@16
|
1370 > distance_v(m_members.parameters(), m_members.translator(), predicates, out_it);
|
Chris@16
|
1371
|
Chris@16
|
1372 detail::rtree::apply_visitor(distance_v, *m_members.root);
|
Chris@16
|
1373
|
Chris@16
|
1374 return distance_v.finish();
|
Chris@16
|
1375 }
|
Chris@16
|
1376
|
Chris@16
|
1377 struct members_holder
|
Chris@16
|
1378 : public translator_type
|
Chris@16
|
1379 , public Parameters
|
Chris@16
|
1380 , public allocators_type
|
Chris@16
|
1381 {
|
Chris@16
|
1382 private:
|
Chris@16
|
1383 members_holder(members_holder const&);
|
Chris@16
|
1384 members_holder & operator=(members_holder const&);
|
Chris@16
|
1385
|
Chris@16
|
1386 public:
|
Chris@16
|
1387 template <typename IndGet, typename ValEq, typename Alloc>
|
Chris@16
|
1388 members_holder(IndGet const& ind_get,
|
Chris@16
|
1389 ValEq const& val_eq,
|
Chris@16
|
1390 Parameters const& parameters,
|
Chris@16
|
1391 BOOST_FWD_REF(Alloc) alloc)
|
Chris@16
|
1392 : translator_type(ind_get, val_eq)
|
Chris@16
|
1393 , Parameters(parameters)
|
Chris@16
|
1394 , allocators_type(boost::forward<Alloc>(alloc))
|
Chris@16
|
1395 , values_count(0)
|
Chris@16
|
1396 , leafs_level(0)
|
Chris@16
|
1397 , root(0)
|
Chris@16
|
1398 {}
|
Chris@16
|
1399
|
Chris@16
|
1400 template <typename IndGet, typename ValEq>
|
Chris@16
|
1401 members_holder(IndGet const& ind_get,
|
Chris@16
|
1402 ValEq const& val_eq,
|
Chris@16
|
1403 Parameters const& parameters)
|
Chris@16
|
1404 : translator_type(ind_get, val_eq)
|
Chris@16
|
1405 , Parameters(parameters)
|
Chris@16
|
1406 , allocators_type()
|
Chris@16
|
1407 , values_count(0)
|
Chris@16
|
1408 , leafs_level(0)
|
Chris@16
|
1409 , root(0)
|
Chris@16
|
1410 {}
|
Chris@16
|
1411
|
Chris@16
|
1412 translator_type const& translator() const { return *this; }
|
Chris@16
|
1413
|
Chris@16
|
1414 IndexableGetter const& indexable_getter() const { return *this; }
|
Chris@16
|
1415 IndexableGetter & indexable_getter() { return *this; }
|
Chris@16
|
1416 EqualTo const& equal_to() const { return *this; }
|
Chris@16
|
1417 EqualTo & equal_to() { return *this; }
|
Chris@16
|
1418 Parameters const& parameters() const { return *this; }
|
Chris@16
|
1419 Parameters & parameters() { return *this; }
|
Chris@16
|
1420 allocators_type const& allocators() const { return *this; }
|
Chris@16
|
1421 allocators_type & allocators() { return *this; }
|
Chris@16
|
1422
|
Chris@16
|
1423 size_type values_count;
|
Chris@16
|
1424 size_type leafs_level;
|
Chris@16
|
1425 node_pointer root;
|
Chris@16
|
1426 };
|
Chris@16
|
1427
|
Chris@16
|
1428 members_holder m_members;
|
Chris@16
|
1429 };
|
Chris@16
|
1430
|
Chris@16
|
1431 /*!
|
Chris@16
|
1432 \brief Insert a value to the index.
|
Chris@16
|
1433
|
Chris@16
|
1434 It calls <tt>rtree::insert(value_type const&)</tt>.
|
Chris@16
|
1435
|
Chris@16
|
1436 \ingroup rtree_functions
|
Chris@16
|
1437
|
Chris@16
|
1438 \param tree The spatial index.
|
Chris@16
|
1439 \param v The value which will be stored in the index.
|
Chris@16
|
1440 */
|
Chris@16
|
1441 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1442 inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Value const& v)
|
Chris@16
|
1443 {
|
Chris@16
|
1444 tree.insert(v);
|
Chris@16
|
1445 }
|
Chris@16
|
1446
|
Chris@16
|
1447 /*!
|
Chris@16
|
1448 \brief Insert a range of values to the index.
|
Chris@16
|
1449
|
Chris@16
|
1450 It calls <tt>rtree::insert(Iterator, Iterator)</tt>.
|
Chris@16
|
1451
|
Chris@16
|
1452 \ingroup rtree_functions
|
Chris@16
|
1453
|
Chris@16
|
1454 \param tree The spatial index.
|
Chris@16
|
1455 \param first The beginning of the range of values.
|
Chris@16
|
1456 \param last The end of the range of values.
|
Chris@16
|
1457 */
|
Chris@16
|
1458 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Iterator>
|
Chris@16
|
1459 inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Iterator first, Iterator last)
|
Chris@16
|
1460 {
|
Chris@16
|
1461 tree.insert(first, last);
|
Chris@16
|
1462 }
|
Chris@16
|
1463
|
Chris@16
|
1464 /*!
|
Chris@16
|
1465 \brief Insert a range of values to the index.
|
Chris@16
|
1466
|
Chris@16
|
1467 It calls <tt>rtree::insert(Range const&)</tt>.
|
Chris@16
|
1468
|
Chris@16
|
1469 \ingroup rtree_functions
|
Chris@16
|
1470
|
Chris@16
|
1471 \param tree The spatial index.
|
Chris@16
|
1472 \param rng The range of values.
|
Chris@16
|
1473 */
|
Chris@16
|
1474 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Range>
|
Chris@16
|
1475 inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Range const& rng)
|
Chris@16
|
1476 {
|
Chris@16
|
1477 tree.insert(rng);
|
Chris@16
|
1478 }
|
Chris@16
|
1479
|
Chris@16
|
1480 /*!
|
Chris@16
|
1481 \brief Remove a value from the container.
|
Chris@16
|
1482
|
Chris@16
|
1483 Remove a value from the container. In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
1484 this function removes only one value from the container.
|
Chris@16
|
1485
|
Chris@16
|
1486 It calls <tt>rtree::remove(value_type const&)</tt>.
|
Chris@16
|
1487
|
Chris@16
|
1488 \ingroup rtree_functions
|
Chris@16
|
1489
|
Chris@16
|
1490 \param tree The spatial index.
|
Chris@16
|
1491 \param v The value which will be removed from the index.
|
Chris@16
|
1492
|
Chris@16
|
1493 \return 1 if value was removed, 0 otherwise.
|
Chris@16
|
1494 */
|
Chris@16
|
1495 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1496 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
|
Chris@16
|
1497 remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Value const& v)
|
Chris@16
|
1498 {
|
Chris@16
|
1499 return tree.remove(v);
|
Chris@16
|
1500 }
|
Chris@16
|
1501
|
Chris@16
|
1502 /*!
|
Chris@16
|
1503 \brief Remove a range of values from the container.
|
Chris@16
|
1504
|
Chris@16
|
1505 Remove a range of values from the container. In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
1506 it doesn't take iterators pointing to values stored in this container. It removes values equal
|
Chris@16
|
1507 to these passed as a range. Furthermore this function removes only one value for each one passed
|
Chris@16
|
1508 in the range, not all equal values.
|
Chris@16
|
1509
|
Chris@16
|
1510 It calls <tt>rtree::remove(Iterator, Iterator)</tt>.
|
Chris@16
|
1511
|
Chris@16
|
1512 \ingroup rtree_functions
|
Chris@16
|
1513
|
Chris@16
|
1514 \param tree The spatial index.
|
Chris@16
|
1515 \param first The beginning of the range of values.
|
Chris@16
|
1516 \param last The end of the range of values.
|
Chris@16
|
1517
|
Chris@16
|
1518 \return The number of removed values.
|
Chris@16
|
1519 */
|
Chris@16
|
1520 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Iterator>
|
Chris@16
|
1521 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
|
Chris@16
|
1522 remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Iterator first, Iterator last)
|
Chris@16
|
1523 {
|
Chris@16
|
1524 return tree.remove(first, last);
|
Chris@16
|
1525 }
|
Chris@16
|
1526
|
Chris@16
|
1527 /*!
|
Chris@16
|
1528 \brief Remove a range of values from the container.
|
Chris@16
|
1529
|
Chris@16
|
1530 Remove a range of values from the container. In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
1531 it removes values equal to these passed as a range. Furthermore this method removes only
|
Chris@16
|
1532 one value for each one passed in the range, not all equal values.
|
Chris@16
|
1533
|
Chris@16
|
1534 It calls <tt>rtree::remove(Range const&)</tt>.
|
Chris@16
|
1535
|
Chris@16
|
1536 \ingroup rtree_functions
|
Chris@16
|
1537
|
Chris@16
|
1538 \param tree The spatial index.
|
Chris@16
|
1539 \param rng The range of values.
|
Chris@16
|
1540
|
Chris@16
|
1541 \return The number of removed values.
|
Chris@16
|
1542 */
|
Chris@16
|
1543 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Range>
|
Chris@16
|
1544 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
|
Chris@16
|
1545 remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Range const& rng)
|
Chris@16
|
1546 {
|
Chris@16
|
1547 return tree.remove(rng);
|
Chris@16
|
1548 }
|
Chris@16
|
1549
|
Chris@16
|
1550 /*!
|
Chris@16
|
1551 \brief Finds values meeting passed predicates e.g. nearest to some Point and/or intersecting some Box.
|
Chris@16
|
1552
|
Chris@16
|
1553 This query function performs spatial and k-nearest neighbor searches. It allows to pass a set of predicates.
|
Chris@16
|
1554 Values will be returned only if all predicates are met.
|
Chris@16
|
1555
|
Chris@16
|
1556 <b>Spatial predicates</b>
|
Chris@16
|
1557
|
Chris@16
|
1558 Spatial predicates may be generated by one of the functions listed below:
|
Chris@16
|
1559 \li \c boost::geometry::index::contains(),
|
Chris@16
|
1560 \li \c boost::geometry::index::covered_by(),
|
Chris@16
|
1561 \li \c boost::geometry::index::covers(),
|
Chris@16
|
1562 \li \c boost::geometry::index::disjoint(),
|
Chris@16
|
1563 \li \c boost::geometry::index::intersects(),
|
Chris@16
|
1564 \li \c boost::geometry::index::overlaps(),
|
Chris@16
|
1565 \li \c boost::geometry::index::within(),
|
Chris@16
|
1566
|
Chris@16
|
1567 It is possible to negate spatial predicates:
|
Chris@16
|
1568 \li <tt>! boost::geometry::index::contains()</tt>,
|
Chris@16
|
1569 \li <tt>! boost::geometry::index::covered_by()</tt>,
|
Chris@16
|
1570 \li <tt>! boost::geometry::index::covers()</tt>,
|
Chris@16
|
1571 \li <tt>! boost::geometry::index::disjoint()</tt>,
|
Chris@16
|
1572 \li <tt>! boost::geometry::index::intersects()</tt>,
|
Chris@16
|
1573 \li <tt>! boost::geometry::index::overlaps()</tt>,
|
Chris@16
|
1574 \li <tt>! boost::geometry::index::within()</tt>
|
Chris@16
|
1575
|
Chris@16
|
1576 <b>Satisfies predicate</b>
|
Chris@16
|
1577
|
Chris@16
|
1578 This is a special kind of predicate which allows to pass a user-defined function or function object which checks
|
Chris@16
|
1579 if Value should be returned by the query. It's generated by:
|
Chris@16
|
1580 \li \c boost::geometry::index::satisfies().
|
Chris@16
|
1581
|
Chris@16
|
1582 <b>Nearest predicate</b>
|
Chris@16
|
1583
|
Chris@16
|
1584 If the nearest predicate is passed a k-nearest neighbor search will be performed. This query will result
|
Chris@16
|
1585 in returning k values to the output iterator. Only one nearest predicate may be passed to the query.
|
Chris@16
|
1586 It may be generated by:
|
Chris@16
|
1587 \li \c boost::geometry::index::nearest().
|
Chris@16
|
1588
|
Chris@16
|
1589 <b>Connecting predicates</b>
|
Chris@16
|
1590
|
Chris@16
|
1591 Predicates may be passed together connected with \c operator&&().
|
Chris@16
|
1592
|
Chris@16
|
1593 \par Example
|
Chris@16
|
1594 \verbatim
|
Chris@16
|
1595 // return elements intersecting box
|
Chris@16
|
1596 bgi::query(tree, bgi::intersects(box), std::back_inserter(result));
|
Chris@16
|
1597 // return elements intersecting poly but not within box
|
Chris@16
|
1598 bgi::query(tree, bgi::intersects(poly) && !bgi::within(box), std::back_inserter(result));
|
Chris@16
|
1599 // return elements overlapping box and meeting my_fun value predicate
|
Chris@16
|
1600 bgi::query(tree, bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
|
Chris@16
|
1601 // return 5 elements nearest to pt and elements are intersecting box
|
Chris@16
|
1602 bgi::query(tree, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
|
Chris@16
|
1603 \endverbatim
|
Chris@16
|
1604
|
Chris@16
|
1605 \par Throws
|
Chris@16
|
1606 If Value copy constructor or copy assignment throws.
|
Chris@16
|
1607
|
Chris@16
|
1608 \warning
|
Chris@16
|
1609 Only one \c nearest() perdicate may be passed to the query. Passing more of them results in compile-time error.
|
Chris@16
|
1610
|
Chris@16
|
1611 \ingroup rtree_functions
|
Chris@16
|
1612
|
Chris@16
|
1613 \param tree The rtree.
|
Chris@16
|
1614 \param predicates Predicates.
|
Chris@16
|
1615 \param out_it The output iterator, e.g. generated by std::back_inserter().
|
Chris@16
|
1616
|
Chris@16
|
1617 \return The number of values found.
|
Chris@16
|
1618 */
|
Chris@16
|
1619 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
|
Chris@16
|
1620 typename Predicates, typename OutIter> inline
|
Chris@16
|
1621 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
|
Chris@16
|
1622 query(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree,
|
Chris@16
|
1623 Predicates const& predicates,
|
Chris@16
|
1624 OutIter out_it)
|
Chris@16
|
1625 {
|
Chris@16
|
1626 return tree.query(predicates, out_it);
|
Chris@16
|
1627 }
|
Chris@16
|
1628
|
Chris@16
|
1629 /*!
|
Chris@16
|
1630 \brief Returns the query iterator pointing at the begin of the query range.
|
Chris@16
|
1631
|
Chris@16
|
1632 This method returns the iterator which may be used to perform iterative queries. For the information
|
Chris@16
|
1633 about the predicates which may be passed to this method see query().
|
Chris@16
|
1634
|
Chris@16
|
1635 \par Example
|
Chris@16
|
1636 \verbatim
|
Chris@16
|
1637
|
Chris@16
|
1638 for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
|
Chris@16
|
1639 it != qend(tree) ; ++it )
|
Chris@16
|
1640 {
|
Chris@16
|
1641 // do something with value
|
Chris@16
|
1642 if ( has_enough_nearest_values() )
|
Chris@16
|
1643 break;
|
Chris@16
|
1644 }
|
Chris@16
|
1645 \endverbatim
|
Chris@16
|
1646
|
Chris@16
|
1647 \par Throws
|
Chris@16
|
1648 If predicates copy throws.
|
Chris@16
|
1649 If allocation throws.
|
Chris@16
|
1650
|
Chris@16
|
1651 \ingroup rtree_functions
|
Chris@16
|
1652
|
Chris@16
|
1653 \param tree The rtree.
|
Chris@16
|
1654 \param predicates Predicates.
|
Chris@16
|
1655
|
Chris@16
|
1656 \return The iterator pointing at the begin of the query range.
|
Chris@16
|
1657 */
|
Chris@16
|
1658 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
|
Chris@16
|
1659 typename Predicates> inline
|
Chris@16
|
1660 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_query_iterator
|
Chris@16
|
1661 qbegin(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree,
|
Chris@16
|
1662 Predicates const& predicates)
|
Chris@16
|
1663 {
|
Chris@16
|
1664 return tree.qbegin(predicates);
|
Chris@16
|
1665 }
|
Chris@16
|
1666
|
Chris@16
|
1667 /*!
|
Chris@16
|
1668 \brief Returns the query iterator pointing at the end of the query range.
|
Chris@16
|
1669
|
Chris@16
|
1670 This method returns the iterator which may be used to check if the query has ended.
|
Chris@16
|
1671
|
Chris@16
|
1672 \par Example
|
Chris@16
|
1673 \verbatim
|
Chris@16
|
1674
|
Chris@16
|
1675 for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
|
Chris@16
|
1676 it != qend(tree) ; ++it )
|
Chris@16
|
1677 {
|
Chris@16
|
1678 // do something with value
|
Chris@16
|
1679 if ( has_enough_nearest_values() )
|
Chris@16
|
1680 break;
|
Chris@16
|
1681 }
|
Chris@16
|
1682 \endverbatim
|
Chris@16
|
1683
|
Chris@16
|
1684 \par Throws
|
Chris@16
|
1685 Nothing
|
Chris@16
|
1686
|
Chris@16
|
1687 \ingroup rtree_functions
|
Chris@16
|
1688
|
Chris@16
|
1689 \return The iterator pointing at the end of the query range.
|
Chris@16
|
1690 */
|
Chris@16
|
1691 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
|
Chris@16
|
1692 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_query_iterator
|
Chris@16
|
1693 qend(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
|
Chris@16
|
1694 {
|
Chris@16
|
1695 return tree.qend();
|
Chris@16
|
1696 }
|
Chris@16
|
1697
|
Chris@16
|
1698 /*!
|
Chris@16
|
1699 \brief Remove all values from the index.
|
Chris@16
|
1700
|
Chris@16
|
1701 It calls \c rtree::clear().
|
Chris@16
|
1702
|
Chris@16
|
1703 \ingroup rtree_functions
|
Chris@16
|
1704
|
Chris@16
|
1705 \param tree The spatial index.
|
Chris@16
|
1706 */
|
Chris@16
|
1707 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1708 inline void clear(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree)
|
Chris@16
|
1709 {
|
Chris@16
|
1710 return tree.clear();
|
Chris@16
|
1711 }
|
Chris@16
|
1712
|
Chris@16
|
1713 /*!
|
Chris@16
|
1714 \brief Get the number of values stored in the index.
|
Chris@16
|
1715
|
Chris@16
|
1716 It calls \c rtree::size().
|
Chris@16
|
1717
|
Chris@16
|
1718 \ingroup rtree_functions
|
Chris@16
|
1719
|
Chris@16
|
1720 \param tree The spatial index.
|
Chris@16
|
1721
|
Chris@16
|
1722 \return The number of values stored in the index.
|
Chris@16
|
1723 */
|
Chris@16
|
1724 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1725 inline size_t size(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
|
Chris@16
|
1726 {
|
Chris@16
|
1727 return tree.size();
|
Chris@16
|
1728 }
|
Chris@16
|
1729
|
Chris@16
|
1730 /*!
|
Chris@16
|
1731 \brief Query if there are no values stored in the index.
|
Chris@16
|
1732
|
Chris@16
|
1733 It calls \c rtree::empty().
|
Chris@16
|
1734
|
Chris@16
|
1735 \ingroup rtree_functions
|
Chris@16
|
1736
|
Chris@16
|
1737 \param tree The spatial index.
|
Chris@16
|
1738
|
Chris@16
|
1739 \return true if there are no values in the index.
|
Chris@16
|
1740 */
|
Chris@16
|
1741 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1742 inline bool empty(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
|
Chris@16
|
1743 {
|
Chris@16
|
1744 return tree.bounds();
|
Chris@16
|
1745 }
|
Chris@16
|
1746
|
Chris@16
|
1747 /*!
|
Chris@16
|
1748 \brief Get the box containing all stored values or an invalid box if the index has no values.
|
Chris@16
|
1749
|
Chris@16
|
1750 It calls \c rtree::envelope().
|
Chris@16
|
1751
|
Chris@16
|
1752 \ingroup rtree_functions
|
Chris@16
|
1753
|
Chris@16
|
1754 \param tree The spatial index.
|
Chris@16
|
1755
|
Chris@16
|
1756 \return The box containing all stored values or an invalid box.
|
Chris@16
|
1757 */
|
Chris@16
|
1758 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1759 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::bounds_type
|
Chris@16
|
1760 bounds(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
|
Chris@16
|
1761 {
|
Chris@16
|
1762 return tree.bounds();
|
Chris@16
|
1763 }
|
Chris@16
|
1764
|
Chris@16
|
1765 /*!
|
Chris@16
|
1766 \brief Exchanges the contents of the container with those of other.
|
Chris@16
|
1767
|
Chris@16
|
1768 It calls \c rtree::swap().
|
Chris@16
|
1769
|
Chris@16
|
1770 \ingroup rtree_functions
|
Chris@16
|
1771
|
Chris@16
|
1772 \param l The first rtree.
|
Chris@16
|
1773 \param r The second rtree.
|
Chris@16
|
1774 */
|
Chris@16
|
1775 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1776 inline void swap(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & l,
|
Chris@16
|
1777 rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & r)
|
Chris@16
|
1778 {
|
Chris@16
|
1779 return l.swap(r);
|
Chris@16
|
1780 }
|
Chris@16
|
1781
|
Chris@16
|
1782 }}} // namespace boost::geometry::index
|
Chris@16
|
1783
|
Chris@16
|
1784 #include <boost/geometry/index/detail/config_end.hpp>
|
Chris@16
|
1785
|
Chris@16
|
1786 #endif // BOOST_GEOMETRY_INDEX_RTREE_HPP
|