Boost.Geometry.Index
 All Classes Functions Typedefs Groups
rtree.hpp
1 // Boost.Geometry Index
2 //
3 // R-tree implementation
4 //
5 // Copyright (c) 2008 Federico J. Fernandez.
6 // Copyright (c) 2011-2015 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 // STD
16 #include <algorithm>
17 
18 // Boost
19 #include <boost/tuple/tuple.hpp>
20 #include <boost/move/move.hpp>
21 
22 // Boost.Geometry
23 #include <boost/geometry/algorithms/detail/comparable_distance/interface.hpp>
24 #include <boost/geometry/algorithms/centroid.hpp>
25 #include <boost/geometry/algorithms/covered_by.hpp>
26 #include <boost/geometry/algorithms/disjoint.hpp>
27 #include <boost/geometry/algorithms/equals.hpp>
28 #include <boost/geometry/algorithms/intersects.hpp>
29 #include <boost/geometry/algorithms/overlaps.hpp>
30 #include <boost/geometry/algorithms/touches.hpp>
31 #include <boost/geometry/algorithms/within.hpp>
32 
33 #include <boost/geometry/geometries/point.hpp>
34 #include <boost/geometry/geometries/box.hpp>
35 
36 #include <boost/geometry/strategies/strategies.hpp>
37 
38 // Boost.Geometry.Index
39 #include <boost/geometry/index/detail/config_begin.hpp>
40 
41 #include <boost/geometry/index/detail/assert.hpp>
42 #include <boost/geometry/index/detail/exception.hpp>
43 
44 #include <boost/geometry/index/detail/rtree/options.hpp>
45 
46 #include <boost/geometry/index/indexable.hpp>
47 #include <boost/geometry/index/equal_to.hpp>
48 
49 #include <boost/geometry/index/detail/translator.hpp>
50 
51 #include <boost/geometry/index/predicates.hpp>
52 #include <boost/geometry/index/distance_predicates.hpp>
53 #include <boost/geometry/index/detail/rtree/adaptors.hpp>
54 
55 #include <boost/geometry/index/detail/meta.hpp>
56 #include <boost/geometry/index/detail/utilities.hpp>
57 #include <boost/geometry/index/detail/rtree/node/node.hpp>
58 
59 #include <boost/geometry/index/detail/algorithms/is_valid.hpp>
60 
61 #include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
62 #include <boost/geometry/index/detail/rtree/visitors/iterator.hpp>
63 #include <boost/geometry/index/detail/rtree/visitors/remove.hpp>
64 #include <boost/geometry/index/detail/rtree/visitors/copy.hpp>
65 #include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
66 #include <boost/geometry/index/detail/rtree/visitors/spatial_query.hpp>
67 #include <boost/geometry/index/detail/rtree/visitors/distance_query.hpp>
68 #include <boost/geometry/index/detail/rtree/visitors/count.hpp>
69 #include <boost/geometry/index/detail/rtree/visitors/children_box.hpp>
70 
71 #include <boost/geometry/index/detail/rtree/linear/linear.hpp>
72 #include <boost/geometry/index/detail/rtree/quadratic/quadratic.hpp>
73 #include <boost/geometry/index/detail/rtree/rstar/rstar.hpp>
74 //#include <boost/geometry/extensions/index/detail/rtree/kmeans/kmeans.hpp>
75 
76 #include <boost/geometry/index/detail/rtree/pack_create.hpp>
77 
78 #include <boost/geometry/index/inserter.hpp>
79 
80 #include <boost/geometry/index/detail/rtree/utilities/view.hpp>
81 
82 #include <boost/geometry/index/detail/rtree/iterators.hpp>
83 #include <boost/geometry/index/detail/rtree/query_iterators.hpp>
84 
85 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
86 // serialization
87 #include <boost/geometry/index/detail/serialization.hpp>
88 #endif
89 
90 // TODO change the name to bounding_tree
91 
96 namespace boost { namespace geometry { namespace index {
97 
148 template <
149  typename Value,
150  typename Parameters,
151  typename IndexableGetter = index::indexable<Value>,
152  typename EqualTo = index::equal_to<Value>,
153  typename Allocator = std::allocator<Value>
154 >
155 class rtree
156 {
157  BOOST_COPYABLE_AND_MOVABLE(rtree)
158 
159 public:
161  typedef Value value_type;
163  typedef Parameters parameters_type;
165  typedef IndexableGetter indexable_getter;
167  typedef EqualTo value_equal;
169  typedef Allocator allocator_type;
170 
171  // TODO: SHOULD THIS TYPE BE REMOVED?
173  typedef typename index::detail::indexable_type<
174  detail::translator<IndexableGetter, EqualTo>
175  >::type indexable_type;
176 
178  typedef geometry::model::box<
179  geometry::model::point<
180  typename coordinate_type<indexable_type>::type,
181  dimension<indexable_type>::value,
182  typename coordinate_system<indexable_type>::type
183  >
184  >
186 
187 private:
188 
189  typedef detail::translator<IndexableGetter, EqualTo> translator_type;
190 
191  typedef bounds_type box_type;
192  typedef typename detail::rtree::options_type<Parameters>::type options_type;
193  typedef typename options_type::node_tag node_tag;
194  typedef detail::rtree::allocators<allocator_type, value_type, typename options_type::parameters_type, box_type, node_tag> allocators_type;
195 
196  typedef typename detail::rtree::node<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type node;
197  typedef typename detail::rtree::internal_node<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type internal_node;
198  typedef typename detail::rtree::leaf<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type leaf;
199 
200  typedef typename allocators_type::node_pointer node_pointer;
201  typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
202  typedef detail::rtree::subtree_destroyer<value_type, options_type, translator_type, box_type, allocators_type> subtree_destroyer;
203 
204  friend class detail::rtree::utilities::view<rtree>;
205 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
206  friend class detail::rtree::private_view<rtree>;
207  friend class detail::rtree::const_private_view<rtree>;
208 #endif
209 
210 public:
211 
213  typedef typename allocators_type::reference reference;
215  typedef typename allocators_type::const_reference const_reference;
217  typedef typename allocators_type::pointer pointer;
219  typedef typename allocators_type::const_pointer const_pointer;
221  typedef typename allocators_type::difference_type difference_type;
223  typedef typename allocators_type::size_type size_type;
224 
226  typedef index::detail::rtree::iterators::iterator
227  <
228  value_type, options_type, translator_type, box_type, allocators_type
230 
232  typedef index::detail::rtree::iterators::query_iterator
233  <
234  value_type, allocators_type
236 
237 public:
238 
249  inline explicit rtree(parameters_type const& parameters = parameters_type(),
250  indexable_getter const& getter = indexable_getter(),
251  value_equal const& equal = value_equal())
252  : m_members(getter, equal, parameters)
253  {}
254 
267  indexable_getter const& getter,
268  value_equal const& equal,
269  allocator_type const& allocator)
270  : m_members(getter, equal, parameters, allocator)
271  {}
272 
290  template<typename Iterator>
291  inline rtree(Iterator first, Iterator last,
293  indexable_getter const& getter = indexable_getter(),
294  value_equal const& equal = value_equal(),
295  allocator_type const& allocator = allocator_type())
296  : m_members(getter, equal, parameters, allocator)
297  {
298  typedef detail::rtree::pack<value_type, options_type, translator_type, box_type, allocators_type> pack;
299  size_type vc = 0, ll = 0;
300  m_members.root = pack::apply(first, last, vc, ll,
301  m_members.parameters(), m_members.translator(), m_members.allocators());
302  m_members.values_count = vc;
303  m_members.leafs_level = ll;
304  }
305 
322  template<typename Range>
323  inline explicit rtree(Range const& rng,
325  indexable_getter const& getter = indexable_getter(),
326  value_equal const& equal = value_equal(),
327  allocator_type const& allocator = allocator_type())
328  : m_members(getter, equal, parameters, allocator)
329  {
330  typedef detail::rtree::pack<value_type, options_type, translator_type, box_type, allocators_type> pack;
331  size_type vc = 0, ll = 0;
332  m_members.root = pack::apply(::boost::begin(rng), ::boost::end(rng), vc, ll,
333  m_members.parameters(), m_members.translator(), m_members.allocators());
334  m_members.values_count = vc;
335  m_members.leafs_level = ll;
336  }
337 
344  inline ~rtree()
345  {
346  this->raw_destroy(*this);
347  }
348 
361  inline rtree(rtree const& src)
362  : m_members(src.m_members.indexable_getter(),
363  src.m_members.equal_to(),
364  src.m_members.parameters(),
365  allocator_traits_type::select_on_container_copy_construction(src.get_allocator()))
366  {
367  this->raw_copy(src, *this, false);
368  }
369 
383  inline rtree(rtree const& src, allocator_type const& allocator)
384  : m_members(src.m_members.indexable_getter(),
385  src.m_members.equal_to(),
386  src.m_members.parameters(), allocator)
387  {
388  this->raw_copy(src, *this, false);
389  }
390 
401  inline rtree(BOOST_RV_REF(rtree) src)
402  : m_members(src.m_members.indexable_getter(),
403  src.m_members.equal_to(),
404  src.m_members.parameters(),
405  boost::move(src.m_members.allocators()))
406  {
407  boost::swap(m_members.values_count, src.m_members.values_count);
408  boost::swap(m_members.leafs_level, src.m_members.leafs_level);
409  boost::swap(m_members.root, src.m_members.root);
410  }
411 
425  inline rtree(BOOST_RV_REF(rtree) src, allocator_type const& allocator)
426  : m_members(src.m_members.indexable_getter(),
427  src.m_members.equal_to(),
428  src.m_members.parameters(),
429  allocator)
430  {
431  if ( src.m_members.allocators() == allocator )
432  {
433  boost::swap(m_members.values_count, src.m_members.values_count);
434  boost::swap(m_members.leafs_level, src.m_members.leafs_level);
435  boost::swap(m_members.root, src.m_members.root);
436  }
437  else
438  {
439  this->raw_copy(src, *this, false);
440  }
441  }
442 
455  inline rtree & operator=(BOOST_COPY_ASSIGN_REF(rtree) src)
456  {
457  if ( &src != this )
458  {
459  allocators_type & this_allocs = m_members.allocators();
460  allocators_type const& src_allocs = src.m_members.allocators();
461 
462  // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
463  // (allocators stored as base classes of members_holder)
464  // copying them changes values_count, in this case it doesn't cause errors since data must be copied
465 
466  typedef boost::mpl::bool_<
467  allocator_traits_type::propagate_on_container_copy_assignment::value
468  > propagate;
469 
470  if ( propagate::value && !(this_allocs == src_allocs) )
471  this->raw_destroy(*this);
472  detail::assign_cond(this_allocs, src_allocs, propagate());
473 
474  // It uses m_allocators
475  this->raw_copy(src, *this, true);
476  }
477 
478  return *this;
479  }
480 
493  inline rtree & operator=(BOOST_RV_REF(rtree) src)
494  {
495  if ( &src != this )
496  {
497  allocators_type & this_allocs = m_members.allocators();
498  allocators_type & src_allocs = src.m_members.allocators();
499 
500  if ( this_allocs == src_allocs )
501  {
502  this->raw_destroy(*this);
503 
504  m_members.indexable_getter() = src.m_members.indexable_getter();
505  m_members.equal_to() = src.m_members.equal_to();
506  m_members.parameters() = src.m_members.parameters();
507 
508  boost::swap(m_members.values_count, src.m_members.values_count);
509  boost::swap(m_members.leafs_level, src.m_members.leafs_level);
510  boost::swap(m_members.root, src.m_members.root);
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  // moving them changes values_count
515 
516  typedef boost::mpl::bool_<
517  allocator_traits_type::propagate_on_container_move_assignment::value
518  > propagate;
519  detail::move_cond(this_allocs, src_allocs, propagate());
520  }
521  else
522  {
523 // TODO - shouldn't here propagate_on_container_copy_assignment be checked like in operator=(const&)?
524 
525  // It uses m_allocators
526  this->raw_copy(src, *this, true);
527  }
528  }
529 
530  return *this;
531  }
532 
543  void swap(rtree & other)
544  {
545  boost::swap(m_members.indexable_getter(), other.m_members.indexable_getter());
546  boost::swap(m_members.equal_to(), other.m_members.equal_to());
547  boost::swap(m_members.parameters(), other.m_members.parameters());
548 
549  // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
550  // (allocators stored as base classes of members_holder)
551  // swapping them changes values_count
552 
553  typedef boost::mpl::bool_<
554  allocator_traits_type::propagate_on_container_swap::value
555  > propagate;
556  detail::swap_cond(m_members.allocators(), other.m_members.allocators(), propagate());
557 
558  boost::swap(m_members.values_count, other.m_members.values_count);
559  boost::swap(m_members.leafs_level, other.m_members.leafs_level);
560  boost::swap(m_members.root, other.m_members.root);
561  }
562 
578  inline void insert(value_type const& value)
579  {
580  if ( !m_members.root )
581  this->raw_create();
582 
583  this->raw_insert(value);
584  }
585 
602  template <typename Iterator>
603  inline void insert(Iterator first, Iterator last)
604  {
605  if ( !m_members.root )
606  this->raw_create();
607 
608  for ( ; first != last ; ++first )
609  this->raw_insert(*first);
610  }
611 
627  template <typename ConvertibleOrRange>
628  inline void insert(ConvertibleOrRange const& conv_or_rng)
629  {
630  if ( !m_members.root )
631  this->raw_create();
632 
633  typedef boost::mpl::bool_
634  <
635  boost::is_convertible<ConvertibleOrRange, value_type>::value
636  > is_conv_t;
637 
638  this->insert_dispatch(conv_or_rng, is_conv_t());
639  }
640 
661  inline size_type remove(value_type const& value)
662  {
663  if ( !m_members.root )
664  return 0;
665 
666  return this->raw_remove(value);
667  }
668 
692  template <typename Iterator>
693  inline size_type remove(Iterator first, Iterator last)
694  {
695  size_type result = 0;
696 
697  if ( !m_members.root )
698  return result;
699 
700  for ( ; first != last ; ++first )
701  result += this->raw_remove(*first);
702  return result;
703  }
704 
726  template <typename ConvertibleOrRange>
727  inline size_type remove(ConvertibleOrRange const& conv_or_rng)
728  {
729  if ( !m_members.root )
730  return 0;
731 
732  typedef boost::mpl::bool_
733  <
734  boost::is_convertible<ConvertibleOrRange, value_type>::value
735  > is_conv_t;
736 
737  return this->remove_dispatch(conv_or_rng, is_conv_t());
738  }
739 
828  template <typename Predicates, typename OutIter>
829  size_type query(Predicates const& predicates, OutIter out_it) const
830  {
831  if ( !m_members.root )
832  return 0;
833 
834  static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
835  static const bool is_distance_predicate = 0 < distance_predicates_count;
836  BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
837 
838  return query_dispatch(predicates, out_it, boost::mpl::bool_<is_distance_predicate>());
839  }
840 
883  template <typename Predicates>
884  const_query_iterator qbegin(Predicates const& predicates) const
885  {
886  return const_query_iterator(qbegin_(predicates));
887  }
888 
928  {
929  return const_query_iterator();
930  }
931 
932 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
933 private:
934 #endif
935 
988  template <typename Predicates>
989  typename boost::mpl::if_c<
990  detail::predicates_count_distance<Predicates>::value == 0,
991  detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
992  detail::rtree::iterators::distance_query_iterator<
993  value_type, options_type, translator_type, box_type, allocators_type, Predicates,
994  detail::predicates_find_distance<Predicates>::value
995  >
996  >::type
997  qbegin_(Predicates const& predicates) const
998  {
999  static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
1000  BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
1001 
1002  typedef typename boost::mpl::if_c<
1003  detail::predicates_count_distance<Predicates>::value == 0,
1004  detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
1005  detail::rtree::iterators::distance_query_iterator<
1006  value_type, options_type, translator_type, box_type, allocators_type, Predicates,
1007  detail::predicates_find_distance<Predicates>::value
1008  >
1009  >::type iterator_type;
1010 
1011  if ( !m_members.root )
1012  return iterator_type(m_members.translator(), predicates);
1013 
1014  return iterator_type(m_members.root, m_members.translator(), predicates);
1015  }
1016 
1049  template <typename Predicates>
1050  typename boost::mpl::if_c<
1051  detail::predicates_count_distance<Predicates>::value == 0,
1052  detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
1053  detail::rtree::iterators::distance_query_iterator<
1054  value_type, options_type, translator_type, box_type, allocators_type, Predicates,
1055  detail::predicates_find_distance<Predicates>::value
1056  >
1057  >::type
1058  qend_(Predicates const& predicates) const
1059  {
1060  static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
1061  BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
1062 
1063  typedef typename boost::mpl::if_c<
1064  detail::predicates_count_distance<Predicates>::value == 0,
1065  detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
1066  detail::rtree::iterators::distance_query_iterator<
1067  value_type, options_type, translator_type, box_type, allocators_type, Predicates,
1068  detail::predicates_find_distance<Predicates>::value
1069  >
1070  >::type iterator_type;
1071 
1072  return iterator_type(m_members.translator(), predicates);
1073  }
1074 
1124  detail::rtree::iterators::end_query_iterator<value_type, allocators_type>
1125  qend_() const
1126  {
1127  return detail::rtree::iterators::end_query_iterator<value_type, allocators_type>();
1128  }
1129 
1130 public:
1131 
1172  {
1173  if ( !m_members.root )
1174  return const_iterator();
1175 
1176  return const_iterator(m_members.root);
1177  }
1178 
1210  {
1211  return const_iterator();
1212  }
1213 
1222  inline size_type size() const
1223  {
1224  return m_members.values_count;
1225  }
1226 
1235  inline bool empty() const
1236  {
1237  return 0 == m_members.values_count;
1238  }
1239 
1246  inline void clear()
1247  {
1248  this->raw_destroy(*this);
1249  }
1250 
1263  inline bounds_type bounds() const
1264  {
1265  bounds_type result;
1266  // in order to suppress the uninitialized variable warnings
1267  geometry::assign_inverse(result);
1268 
1269  if ( m_members.root )
1270  {
1271  detail::rtree::visitors::children_box<value_type, options_type, translator_type, box_type, allocators_type>
1272  box_v(result, m_members.translator());
1273  detail::rtree::apply_visitor(box_v, *m_members.root);
1274  }
1275 
1276  return result;
1277  }
1278 
1292  template <typename ValueOrIndexable>
1293  size_type count(ValueOrIndexable const& vori) const
1294  {
1295  if ( !m_members.root )
1296  return 0;
1297 
1298  // the input should be convertible to Value or Indexable type
1299 
1300  enum { as_val = 0, as_ind, dont_know };
1301  typedef boost::mpl::int_
1302  <
1303  boost::is_same<ValueOrIndexable, value_type>::value ?
1304  as_val :
1305  boost::is_same<ValueOrIndexable, indexable_type>::value ?
1306  as_ind :
1307  boost::is_convertible<ValueOrIndexable, indexable_type>::value ?
1308  as_ind :
1309  boost::is_convertible<ValueOrIndexable, value_type>::value ?
1310  as_val :
1311  dont_know
1312  > variant;
1313 
1314  BOOST_MPL_ASSERT_MSG((variant::value != dont_know),
1315  PASSED_OBJECT_NOT_CONVERTIBLE_TO_VALUE_NOR_INDEXABLE_TYPE,
1316  (ValueOrIndexable));
1317 
1318  typedef typename boost::mpl::if_c
1319  <
1320  variant::value == as_val,
1321  value_type,
1323  >::type value_or_indexable;
1324 
1325  // NOTE: If an object of convertible but not the same type is passed
1326  // into the function, here a temporary will be created.
1327  return this->template raw_count<value_or_indexable>(vori);
1328  }
1329 
1339  {
1340  return m_members.parameters();
1341  }
1342 
1352  {
1353  return m_members.indexable_getter();
1354  }
1355 
1365  {
1366  return m_members.equal_to();
1367  }
1368 
1378  {
1379  return m_members.allocators().allocator();
1380  }
1381 
1382 private:
1383 
1392  inline translator_type translator() const
1393  {
1394  return m_members.translator();
1395  }
1396 
1408  template <typename Visitor>
1409  inline void apply_visitor(Visitor & visitor) const
1410  {
1411  if ( m_members.root )
1412  detail::rtree::apply_visitor(visitor, *m_members.root);
1413  }
1414 
1425  inline size_type depth() const
1426  {
1427  return m_members.leafs_level;
1428  }
1429 
1430 private:
1431 
1442  inline void raw_insert(value_type const& value)
1443  {
1444  BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
1445  // CONSIDER: alternative - ignore invalid indexable or throw an exception
1446  BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(m_members.translator()(value)), "Indexable is invalid");
1447 
1449  value_type,
1450  value_type, options_type, translator_type, box_type, allocators_type,
1451  typename options_type::insert_tag
1452  > insert_v(m_members.root, m_members.leafs_level, value,
1453  m_members.parameters(), m_members.translator(), m_members.allocators());
1454 
1455  detail::rtree::apply_visitor(insert_v, *m_members.root);
1456 
1457 // TODO
1458 // Think about this: If exception is thrown, may the root be removed?
1459 // Or it is just cleared?
1460 
1461 // TODO
1462 // If exception is thrown, m_values_count may be invalid
1463  ++m_members.values_count;
1464  }
1465 
1474  inline size_type raw_remove(value_type const& value)
1475  {
1476  // TODO: awulkiew - assert for correct value (indexable) ?
1477  BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
1478 
1480  value_type, options_type, translator_type, box_type, allocators_type
1481  > remove_v(m_members.root, m_members.leafs_level, value,
1482  m_members.parameters(), m_members.translator(), m_members.allocators());
1483 
1484  detail::rtree::apply_visitor(remove_v, *m_members.root);
1485 
1486  // If exception is thrown, m_values_count may be invalid
1487 
1488  if ( remove_v.is_value_removed() )
1489  {
1490  BOOST_GEOMETRY_INDEX_ASSERT(0 < m_members.values_count, "unexpected state");
1491 
1492  --m_members.values_count;
1493 
1494  return 1;
1495  }
1496 
1497  return 0;
1498  }
1499 
1506  inline void raw_create()
1507  {
1508  BOOST_GEOMETRY_INDEX_ASSERT(0 == m_members.root, "the tree is already created");
1509 
1510  m_members.root = detail::rtree::create_node<allocators_type, leaf>::apply(m_members.allocators()); // MAY THROW (N: alloc)
1511  m_members.values_count = 0;
1512  m_members.leafs_level = 0;
1513  }
1514 
1523  inline void raw_destroy(rtree & t)
1524  {
1525  if ( t.m_members.root )
1526  {
1527  detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
1528  del_v(t.m_members.root, t.m_members.allocators());
1529  detail::rtree::apply_visitor(del_v, *t.m_members.root);
1530 
1531  t.m_members.root = 0;
1532  }
1533  t.m_members.values_count = 0;
1534  t.m_members.leafs_level = 0;
1535  }
1536 
1548  inline void raw_copy(rtree const& src, rtree & dst, bool copy_tr_and_params) const
1549  {
1550  detail::rtree::visitors::copy<value_type, options_type, translator_type, box_type, allocators_type>
1551  copy_v(dst.m_members.allocators());
1552 
1553  if ( src.m_members.root )
1554  detail::rtree::apply_visitor(copy_v, *src.m_members.root); // MAY THROW (V, E: alloc, copy, N: alloc)
1555 
1556  if ( copy_tr_and_params )
1557  {
1558  dst.m_members.indexable_getter() = src.m_members.indexable_getter();
1559  dst.m_members.equal_to() = src.m_members.equal_to();
1560  dst.m_members.parameters() = src.m_members.parameters();
1561  }
1562 
1563  // TODO use subtree_destroyer
1564  if ( dst.m_members.root )
1565  {
1566  detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
1567  del_v(dst.m_members.root, dst.m_members.allocators());
1568  detail::rtree::apply_visitor(del_v, *dst.m_members.root);
1569  dst.m_members.root = 0;
1570  }
1571 
1572  dst.m_members.root = copy_v.result;
1573  dst.m_members.values_count = src.m_members.values_count;
1574  dst.m_members.leafs_level = src.m_members.leafs_level;
1575  }
1576 
1585  template <typename ValueConvertible>
1586  inline void insert_dispatch(ValueConvertible const& val_conv,
1587  boost::mpl::bool_<true> const& /*is_convertible*/)
1588  {
1589  this->raw_insert(val_conv);
1590  }
1591 
1600  template <typename Range>
1601  inline void insert_dispatch(Range const& rng,
1602  boost::mpl::bool_<false> const& /*is_convertible*/)
1603  {
1604  BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value),
1605  PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE,
1606  (Range));
1607 
1608  typedef typename boost::range_const_iterator<Range>::type It;
1609  for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
1610  this->raw_insert(*it);
1611  }
1612 
1621  template <typename ValueConvertible>
1622  inline size_type remove_dispatch(ValueConvertible const& val_conv,
1623  boost::mpl::bool_<true> const& /*is_convertible*/)
1624  {
1625  return this->raw_remove(val_conv);
1626  }
1627 
1636  template <typename Range>
1637  inline size_type remove_dispatch(Range const& rng,
1638  boost::mpl::bool_<false> const& /*is_convertible*/)
1639  {
1640  BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value),
1641  PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE,
1642  (Range));
1643 
1644  size_type result = 0;
1645  typedef typename boost::range_const_iterator<Range>::type It;
1646  for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
1647  result += this->raw_remove(*it);
1648  return result;
1649  }
1650 
1657  template <typename Predicates, typename OutIter>
1658  size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<false> const& /*is_distance_predicate*/) const
1659  {
1660  detail::rtree::visitors::spatial_query<value_type, options_type, translator_type, box_type, allocators_type, Predicates, OutIter>
1661  find_v(m_members.translator(), predicates, out_it);
1662 
1663  detail::rtree::apply_visitor(find_v, *m_members.root);
1664 
1665  return find_v.found_count;
1666  }
1667 
1674  template <typename Predicates, typename OutIter>
1675  size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<true> const& /*is_distance_predicate*/) const
1676  {
1677  BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
1678 
1679  static const unsigned distance_predicate_index = detail::predicates_find_distance<Predicates>::value;
1680  detail::rtree::visitors::distance_query<
1681  value_type,
1682  options_type,
1683  translator_type,
1684  box_type,
1685  allocators_type,
1686  Predicates,
1687  distance_predicate_index,
1688  OutIter
1689  > distance_v(m_members.parameters(), m_members.translator(), predicates, out_it);
1690 
1691  detail::rtree::apply_visitor(distance_v, *m_members.root);
1692 
1693  return distance_v.finish();
1694  }
1695 
1702  template <typename ValueOrIndexable>
1703  size_type raw_count(ValueOrIndexable const& vori) const
1704  {
1705  BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
1706 
1707  detail::rtree::visitors::count
1708  <
1709  ValueOrIndexable,
1710  value_type,
1711  options_type,
1712  translator_type,
1713  box_type,
1714  allocators_type
1715  > count_v(vori, m_members.translator());
1716 
1717  detail::rtree::apply_visitor(count_v, *m_members.root);
1718 
1719  return count_v.found_count;
1720  }
1721 
1722  struct members_holder
1723  : public translator_type
1724  , public Parameters
1725  , public allocators_type
1726  {
1727  private:
1728  members_holder(members_holder const&);
1729  members_holder & operator=(members_holder const&);
1730 
1731  public:
1732  template <typename IndGet, typename ValEq, typename Alloc>
1733  members_holder(IndGet const& ind_get,
1734  ValEq const& val_eq,
1735  Parameters const& parameters,
1736  BOOST_FWD_REF(Alloc) alloc)
1737  : translator_type(ind_get, val_eq)
1738  , Parameters(parameters)
1739  , allocators_type(boost::forward<Alloc>(alloc))
1740  , values_count(0)
1741  , leafs_level(0)
1742  , root(0)
1743  {}
1744 
1745  template <typename IndGet, typename ValEq>
1746  members_holder(IndGet const& ind_get,
1747  ValEq const& val_eq,
1748  Parameters const& parameters)
1749  : translator_type(ind_get, val_eq)
1750  , Parameters(parameters)
1751  , allocators_type()
1752  , values_count(0)
1753  , leafs_level(0)
1754  , root(0)
1755  {}
1756 
1757  translator_type const& translator() const { return *this; }
1758 
1759  IndexableGetter const& indexable_getter() const { return *this; }
1760  IndexableGetter & indexable_getter() { return *this; }
1761  EqualTo const& equal_to() const { return *this; }
1762  EqualTo & equal_to() { return *this; }
1763  Parameters const& parameters() const { return *this; }
1764  Parameters & parameters() { return *this; }
1765  allocators_type const& allocators() const { return *this; }
1766  allocators_type & allocators() { return *this; }
1767 
1768  size_type values_count;
1769  size_type leafs_level;
1770  node_pointer root;
1771  };
1772 
1773  members_holder m_members;
1774 };
1775 
1786 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
1788  Value const& v)
1789 {
1790  tree.insert(v);
1791 }
1792 
1804 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
1805  typename Iterator>
1807  Iterator first, Iterator last)
1808 {
1809  tree.insert(first, last);
1810 }
1811 
1822 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
1823  typename ConvertibleOrRange>
1825  ConvertibleOrRange const& conv_or_rng)
1826 {
1827  tree.insert(conv_or_rng);
1828 }
1829 
1845 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
1846 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
1848  Value const& v)
1849 {
1850  return tree.remove(v);
1851 }
1852 
1871 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
1872  typename Iterator>
1873 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
1875  Iterator first, Iterator last)
1876 {
1877  return tree.remove(first, last);
1878 }
1879 
1897 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
1898  typename ConvertibleOrRange>
1899 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
1901  ConvertibleOrRange const& conv_or_rng)
1902 {
1903  return tree.remove(conv_or_rng);
1904 }
1905 
1979 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
1980  typename Predicates, typename OutIter> inline
1981 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
1983  Predicates const& predicates,
1984  OutIter out_it)
1985 {
1986  return tree.query(predicates, out_it);
1987 }
1988 
2017 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
2018  typename Predicates> inline
2019 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_query_iterator
2021  Predicates const& predicates)
2022 {
2023  return tree.qbegin(predicates);
2024 }
2025 
2049 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
2050 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_query_iterator
2052 {
2053  return tree.qend();
2054 }
2055 
2082 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
2083 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_iterator
2085 {
2086  return tree.begin();
2087 }
2088 
2115 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
2116 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_iterator
2118 {
2119  return tree.end();
2120 }
2121 
2131 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
2133 {
2134  return tree.clear();
2135 }
2136 
2148 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
2150 {
2151  return tree.size();
2152 }
2153 
2165 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
2167 {
2168  return tree.bounds();
2169 }
2170 
2182 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
2183 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::bounds_type
2185 {
2186  return tree.bounds();
2187 }
2188 
2199 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
2202 {
2203  return l.swap(r);
2204 }
2205 
2206 }}} // namespace boost::geometry::index
2207 
2208 // Boost.Range adaptation
2209 namespace boost {
2210 
2211 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
2212 struct range_mutable_iterator
2213  <
2214  boost::geometry::index::rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>
2215  >
2216 {
2217  typedef typename boost::geometry::index::rtree
2218  <
2219  Value, Parameters, IndexableGetter, EqualTo, Allocator
2220  >::const_iterator type;
2221 };
2222 
2223 } // namespace boost
2224 
2225 // TODO: don't include the implementation at the end of the file
2226 #include <boost/geometry/algorithms/detail/comparable_distance/implementation.hpp>
2227 
2228 #include <boost/geometry/index/detail/config_end.hpp>
2229 
2230 #endif // BOOST_GEOMETRY_INDEX_RTREE_HPP
size_type count(ValueOrIndexable const &vori) const
Count Values or Indexables stored in the container.
Definition: rtree.hpp:1293
rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator >::const_iterator end(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > const &tree)
Returns the iterator pointing at the end of the rtree values range.
Definition: rtree.hpp:2117
const_iterator begin() const
Returns the iterator pointing at the begin of the rtree values range.
Definition: rtree.hpp:1171
rtree(rtree &&src)
The moving constructor.
Definition: rtree.hpp:401
void swap(rtree &other)
Swaps contents of two rtrees.
Definition: rtree.hpp:543
void insert(Iterator first, Iterator last)
Insert a range of values to the index.
Definition: rtree.hpp:603
Value value_type
The type of Value stored in the container.
Definition: rtree.hpp:161
allocator_type get_allocator() const
Returns allocator used by the rtree.
Definition: rtree.hpp:1377
allocators_type::difference_type difference_type
Type of difference type.
Definition: rtree.hpp:221
indexable_getter indexable_get() const
Returns function retrieving Indexable from Value.
Definition: rtree.hpp:1351
rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator >::const_iterator begin(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > const &tree)
Returns the iterator pointing at the begin of the rtree values range.
Definition: rtree.hpp:2084
rtree(parameters_type const &parameters, indexable_getter const &getter, value_equal const &equal, allocator_type const &allocator)
The constructor.
Definition: rtree.hpp:266
allocators_type::pointer pointer
Type of pointer to Value.
Definition: rtree.hpp:217
parameters_type parameters() const
Returns parameters.
Definition: rtree.hpp:1338
rtree & operator=(rtree const &src)
The assignment operator.
Definition: rtree.hpp:455
allocators_type::reference reference
Type of reference to Value.
Definition: rtree.hpp:213
const_iterator end() const
Returns the iterator pointing at the end of the rtree values range.
Definition: rtree.hpp:1209
rtree & operator=(rtree &&src)
The moving assignment.
Definition: rtree.hpp:493
size_type size() const
Returns the number of stored values.
Definition: rtree.hpp:1222
allocators_type::size_type size_type
Unsigned integral type used by the container.
Definition: rtree.hpp:223
bool empty(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > const &tree)
Query if there are no values stored in the index.
Definition: rtree.hpp:2166
rtree(parameters_type const &parameters=parameters_type(), indexable_getter const &getter=indexable_getter(), value_equal const &equal=value_equal())
The constructor.
Definition: rtree.hpp:249
rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator >::size_type query(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > const &tree, Predicates const &predicates, OutIter out_it)
Finds values meeting passed predicates e.g. nearest to some Point and/or intersecting some Box...
Definition: rtree.hpp:1982
const_query_iterator qbegin(Predicates const &predicates) const
Returns a query iterator pointing at the begin of the query range.
Definition: rtree.hpp:884
index::detail::rtree::iterators::query_iterator< value_type, allocators_type > const_query_iterator
Type of const query iterator, category ForwardIterator.
Definition: rtree.hpp:235
void insert(value_type const &value)
Insert a value to the index.
Definition: rtree.hpp:578
rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator >::const_query_iterator qend(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > const &tree)
Returns the query iterator pointing at the end of the query range.
Definition: rtree.hpp:2051
IndexableGetter indexable_getter
The function object extracting Indexable from Value.
Definition: rtree.hpp:165
index::detail::rtree::iterators::iterator< value_type, options_type, translator_type, box_type, allocators_type > const_iterator
Type of const iterator, category ForwardIterator.
Definition: rtree.hpp:229
rtree(Iterator first, Iterator last, parameters_type const &parameters=parameters_type(), indexable_getter const &getter=indexable_getter(), value_equal const &equal=value_equal(), allocator_type const &allocator=allocator_type())
The constructor.
Definition: rtree.hpp:291
allocators_type::const_pointer const_pointer
Type of pointer to const Value.
Definition: rtree.hpp:219
geometry::model::box< geometry::model::point< typename coordinate_type< indexable_type >::type, dimension< indexable_type >::value, typename coordinate_system< indexable_type >::type > > bounds_type
The Box type used by the R-tree.
Definition: rtree.hpp:185
index::detail::indexable_type< detail::translator< IndexableGetter, EqualTo > >::type indexable_type
The Indexable type to which Value is translated.
Definition: rtree.hpp:175
~rtree()
The destructor.
Definition: rtree.hpp:344
rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator >::bounds_type bounds(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > const &tree)
Get the box containing all stored values or an invalid box if the index has no values.
Definition: rtree.hpp:2184
rtree(rtree &&src, allocator_type const &allocator)
The moving constructor.
Definition: rtree.hpp:425
bounds_type bounds() const
Returns the box able to contain all values stored in the container.
Definition: rtree.hpp:1263
value_equal value_eq() const
Returns function comparing Values.
Definition: rtree.hpp:1364
rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator >::const_query_iterator qbegin(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > const &tree, Predicates const &predicates)
Returns the query iterator pointing at the begin of the query range.
Definition: rtree.hpp:2020
void clear()
Removes all values stored in the container.
Definition: rtree.hpp:1246
void swap(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > &l, rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > &r)
Exchanges the contents of the container with those of other.
Definition: rtree.hpp:2200
The function object comparing Values.
Definition: equal_to.hpp:237
EqualTo value_equal
The function object comparing objects of type Value.
Definition: rtree.hpp:167
size_t size(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > const &tree)
Get the number of values stored in the index.
Definition: rtree.hpp:2149
Allocator allocator_type
The type of allocator used by the container.
Definition: rtree.hpp:169
bool empty() const
Query if the container is empty.
Definition: rtree.hpp:1235
void clear(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > &tree)
Remove all values from the index.
Definition: rtree.hpp:2132
const_query_iterator qend() const
Returns a query iterator pointing at the end of the query range.
Definition: rtree.hpp:927
allocators_type::const_reference const_reference
Type of reference to const Value.
Definition: rtree.hpp:215
rtree(rtree const &src)
The copy constructor.
Definition: rtree.hpp:361
size_type query(Predicates const &predicates, OutIter out_it) const
Finds values meeting passed predicates e.g. nearest to some Point and/or intersecting some Box...
Definition: rtree.hpp:829
rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator >::size_type remove(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > &tree, ConvertibleOrRange const &conv_or_rng)
Remove a value corresponding to an object convertible to it or a range of values from the container...
Definition: rtree.hpp:1900
rtree(rtree const &src, allocator_type const &allocator)
The copy constructor.
Definition: rtree.hpp:383
The R-tree spatial index.
Definition: rtree.hpp:155
void insert(rtree< Value, Parameters, IndexableGetter, EqualTo, Allocator > &tree, ConvertibleOrRange const &conv_or_rng)
Insert a value created using convertible object or a range of values to the index.
Definition: rtree.hpp:1824
rtree(Range const &rng, parameters_type const &parameters=parameters_type(), indexable_getter const &getter=indexable_getter(), value_equal const &equal=value_equal(), allocator_type const &allocator=allocator_type())
The constructor.
Definition: rtree.hpp:323
Parameters parameters_type
R-tree parameters type.
Definition: rtree.hpp:163
void insert(ConvertibleOrRange const &conv_or_rng)
Insert a value created using convertible object or a range of values to the index.
Definition: rtree.hpp:628