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