vgl_rtree.h
Go to the documentation of this file.
1 // This is core/vgl/algo/vgl_rtree.h
2 #ifndef vgl_rtree_h_
3 #define vgl_rtree_h_
4 //:
5 // \file
6 // \author fsm
7 // \brief Templated rtree class and associated classes and functions
8 //--------------------------------------------------------------------------------
9 
10 #include <vector>
11 #ifdef _MSC_VER
12 # include <vcl_msvc_warnings.h>
13 #endif
14 // forward declare all classes.
15 template <class V, class B, class C> class vgl_rtree_probe;
16 template <class V, class B, class C> class vgl_rtree_node;
17 template <class V, class B, class C> class vgl_rtree_iterator_base;
18 template <class V, class B, class C> class vgl_rtree_iterator;
19 template <class V, class B, class C> class vgl_rtree_const_iterator;
20 template <class V, class B, class C> class vgl_rtree;
21 
22 //: Function predicate object for querying the tree.
23 template <class V, class B, class C>
24 class vgl_rtree_probe
25 {
26  public:
27  virtual ~vgl_rtree_probe() = default;
28  //: return true if the probe "meets" the given object.
29  virtual bool meets(V const &v) const { B b; C::init(b, v); return meets(b); }
30  virtual bool meets(B const &b) const =0;
31 };
32 
33 //: max. number of Vs stored in a node.
34 // should be a template argument?
35 #define vgl_rtree_MAX_VERTICES (8)
36 
37 //: max. number of children of a given node.
38 // should be a template argument?
39 #define vgl_rtree_MAX_CHILDREN (8)
40 
41 //: Represent a node in the rtree.
42 template <class V, class B, class C>
43 class vgl_rtree_node
44 {
45  public:
47 
48  // contains bound on all Vs in this node and below.
49  B bounds;
50 
51  // pointer to parent. 0 if none.
52  node *parent;
53 
54 
55  // number of vertex elements in this node and its children.
56  unsigned total_vts;
57 
58  // number of vertex elements in this node.
59  unsigned local_vts;
60 
61  // the elements are stored in this array.
63 
64 
65  // 1 + number of nodes below this one.
66  unsigned total_chs;
67 
68  // number of children of this node.
69  unsigned local_chs;
70 
71  // pointers to children are stored in this array.
73 
74  // -------------------- methods
75 
76  vgl_rtree_node(node *parent, V const &v);
78 
79  // get all Vs which meet the given region.
80  void get(B const &region, std::vector<V> &) const;
81 
82  // get all Vs whose bounds meet the given probe.
83  void get(vgl_rtree_probe<V, B, C> const &region, std::vector<V> &) const;
84 
85  // get all Vs.
86  void get_all(std::vector<V> &vs) const;
87 
88  // find node containing a V equal to the given one.
89  bool find(V const &v, node **n, int *i) const;
90  bool find(B const &b, V const &v, node **n, int *i) const;
91 
92  // add another V to the tree. return node it was added to.
93  node *add(V const &v);
94 
95  // remove ith vertex from node.
96  void erase(unsigned int i);
97 
98  void print() const;
99 
100  private:
101  friend class vgl_rtree_iterator_base<V, B, C>;
102 
103  // the following methods are not used by the vgl_rtree.
104  unsigned int find_index_in_parent() const;
105  void compute_bounds();
106  void update_total_vts(int diff);
107  void update_total_chs(int diff);
108  void update_vertex_count(int diff);
109  void update_child_count (int diff);
110 };
111 
112 //--------------------------------------------------------------------------------
113 
114 //: Base class for both rtree iterators.
115 template <class V, class B, class C>
117 {
118  public:
121  unsigned int i;
123  vgl_rtree_iterator_base(node *root) : current(root), i(0) { }
124  vgl_rtree_iterator_base() : current(nullptr), i(0) { }
125 
126  void operator_pp();
127  void operator_mm();
128 };
129 
130 template <class V, class B, class C>
133 
134 template <class V, class B, class C>
135 inline bool operator!=(vgl_rtree_iterator_base<V, B, C> const &a,
137 { return !( a == b ); }
138 
139 //: Iterator for rtree.
140 template <class V, class B, class C>
141 class vgl_rtree_iterator : public vgl_rtree_iterator_base<V, B, C>
142 {
143  public:
148  vgl_rtree_iterator(node *root) : base(root) { }
149  vgl_rtree_iterator() = default;
151  V &operator*() const { return base::current->vts[base::i]; }
153  self &operator++() { base::operator_pp(); return *this; }
154  self &operator--() { base::operator_mm(); return *this; }
156  self operator++(int) { self tmp = *this; base::operator_pp(); return tmp; }
157  self operator--(int) { self tmp = *this; base::operator_mm(); return tmp; }
158 };
159 
160 //: const_iterator for rtree.
161 template <class V, class B, class C>
163 {
164  public:
169  vgl_rtree_const_iterator(node *root) : base(root) { }
171  vgl_rtree_const_iterator() = default;
173  V const &operator*() const { return base::current->vts[base::i]; }
175  self &operator++() { base::operator_pp(); return *this; }
176  self &operator--() { base::operator_mm(); return *this; }
178  self operator++(int) { self tmp = *this; base::operator_pp(); return tmp; }
179  self operator--(int) { self tmp = *this; base::operator_mm(); return tmp; }
180 };
181 
182 //--------------------------------------------------------------------------------
183 
184 //: Templated rtree class.
185 // The rtree is templated over the element
186 // type V, the type B of the bounding region used (e.g.
187 // axis-aligned bounding boxes are common but there are other
188 // possibilities such as boxes which are axis-aligned ones or even
189 // bounding ellipsoids) and a type C which is used as a namespace
190 // for some functionality needed by the rtree.
191 //
192 // The rtree is a container of Vs which may contain multiple
193 // copies of the same element. The container for client use is
194 // called vgl_rtree<V, B, C> and is defined at the bottom of the
195 // file.
196 //
197 // Note that the iterators are bidirectional but only forward
198 // advancement has been implement so far (it's tedious work).
199 // Moreover, beware that changing an element through an iterator
200 // will not update the rtree, so may lead to the data structure
201 // being corrupted.
202 //
203 // - V : element type
204 // - B : bounds type
205 // - C : mystery type
206 //
207 // The C-device makes it possible to have an rtree of Vs using Bs
208 // without having to modify the class definitions of V or B. It
209 // may be better to have C's signatures non-static and store a C
210 // on every tree node, but I don't know about this.
211 //
212 // It is assumed that the cost of copying (e.g. by assignment) Vs
213 // and Bs is not too high. In any case, I suggest you inline and
214 // optimize heavily when compiling this source file.
215 //
216 // V must have the following signatures:
217 // \code
218 // V::V();
219 // V::V(V const &);
220 // V::operator==(V const &) or operator==(V const &, V const &);
221 // \endcode
222 //
223 // B must have the following signatures :
224 // \code
225 // B::B();
226 // B::B(const &);
227 // B::operator==(V const &) or operator==(B const &, B const &);
228 // \endcode
229 //
230 // C must have the following (static method) signatures :
231 // \code
232 // void C::init (B &, V const &);
233 // void C::update(B &, V const &);
234 // void C::update(B &, B const &);
235 // bool C::meet (B const &, V const &);
236 // bool C::meet (B const &, B const &);
237 // float C::volume(B const &);
238 // \endcode
239 //
240 // The volume() method is used by the rtree to make decisions
241 // about where to put new elements.
242 template <class V, class B, class C>
243 class vgl_rtree
244 {
245  public:
246  vgl_rtree() : root(nullptr) { }
247  ~vgl_rtree() {
248  if (root)
249  delete root;
250  root = nullptr;
251  }
252 
253  //
255 
256  //: iterators
260  iterator begin() { return root ? iterator(root) : iterator(); }
261  const_iterator begin() const { return root ? const_iterator(root) : const_iterator(); }
263  iterator end() { return iterator(); }
264  const_iterator end() const { return const_iterator(); }
265 
266  //: add an element to the rtree.
267  void add(V const &v) {
268  if (root)
269  root->add(v);
270  else
271  root = new node(nullptr/*parent*/, v);
272  }
273 
274  //: remove one element from the rtree.
275  void remove(V const &v) {
276  if (root) {
277  B tmp;
278  C::init(tmp, v);
279  node *n;
280  int i;
281  if (root->find(tmp, v, &n, &i))
282  n->erase(i);
283 
284  if (root->total_vts == 0) {
285  delete root;
286  root = nullptr;
287  }
288  }
289  }
290 
291  //: return true iff the rtree contains an element equal to v.
292  bool contains(V const &v) const {
293  node *n;
294  int i;
295  return root ? root->find(v, &n, &i) : false;
296  }
297 #if 0
298  iterator find(V const &v);
299  const_iterator find(V const &v) const;
300 #endif
301 
302  //: erase the element pointed to by the iterator.
303  // may invalidate \e all iterators into the rtree.
304  void erase(iterator i) {
305  i.current->erase(i.i);
306  if (root->total_vts == 0) {
307  delete root;
308  root = nullptr;
309  }
310  }
311 
312  //: get elements in the given region.
313  void get(B const &region, std::vector<V> &vs) const {
314  if (root)
315  root->get(region, vs);
316  }
317 
318  //: get elements which meet the given probe.
319  void get(vgl_rtree_probe<V, B, C> const &region, std::vector<V> &vs) const {
320  if (root)
321  root->get(region, vs);
322  }
323 
324  //: get all elements in the tree.
325  void get_all(std::vector<V> &vs) const {
326  if (root)
327  root->get_all(vs);
328  }
329 
330  //: return true iff the tree has no elements.
331  bool empty() const {
332  return root ? root->total_vts==0 : true;
333  }
334 
335  //: return number of elements stored in the tree.
336  unsigned size() const {
337  return root ? root->total_vts : 0;
338  }
339 
340  //: return number of nodes used by the tree.
341  unsigned nodes() const {
342  return root ? root->total_chs : 0;
343  }
344 
345  // for internal use only.
347  node *secret_get_root() const { return root; } // for debugging purposes.
349  void print() const {
350  root->print();
351  }
352 
353  private:
354  node *root;
355  // disallow assignment
356  vgl_rtree<V, B, C>& operator=(vgl_rtree<V, B, C> const &) { return *this; }
357  vgl_rtree(vgl_rtree<V, B, C> const &) { }
358 };
360 #define VGL_RTREE_INSTANTIATE(V, B, C) extern "you must include vgl_rtree.hxx first"
361 
362 #endif // vgl_rtree_h_
void get_all(std::vector< V > &vs) const
Definition: vgl_rtree.hxx:324
vgl_rtree_probe< V, B, C > probe
Definition: vgl_rtree.h:253
node * add(V const &v)
Definition: vgl_rtree.hxx:125
void update_total_vts(int diff)
Definition: vgl_rtree.hxx:44
vgl_rtree_node< V, B, C > node
Definition: vgl_rtree.h:45
virtual ~vgl_rtree_probe()=default
void remove(V const &v)
remove one element from the rtree.
Definition: vgl_rtree.h:274
unsigned int find_index_in_parent() const
Definition: vgl_rtree.hxx:247
#define vgl_rtree_MAX_VERTICES
max. number of Vs stored in a node.
Definition: vgl_rtree.h:34
void print() const
Definition: vgl_rtree.hxx:108
vgl_rtree_const_iterator(vgl_rtree_iterator< V, B, C > const &that)
Definition: vgl_rtree.h:169
void get(B const &region, std::vector< V > &vs) const
get elements in the given region.
Definition: vgl_rtree.h:312
unsigned size() const
return number of elements stored in the tree.
Definition: vgl_rtree.h:335
const_iterator begin() const
Definition: vgl_rtree.h:260
bool operator==(vgl_rtree_iterator_base< V, B, C > const &a, vgl_rtree_iterator_base< V, B, C > const &b)
Definition: vgl_rtree.hxx:391
unsigned total_vts
Definition: vgl_rtree.h:55
void add(V const &v)
add an element to the rtree.
Definition: vgl_rtree.h:266
vgl_rtree< V, B, C > & operator=(vgl_rtree< V, B, C > const &)
Definition: vgl_rtree.h:355
self & operator--()
Definition: vgl_rtree.h:153
node * chs[vgl_rtree_MAX_CHILDREN]
Definition: vgl_rtree.h:71
Represent a node in the rtree.
Definition: vgl_algo_fwd.h:31
void update_vertex_count(int diff)
Definition: vgl_rtree.hxx:58
void update_child_count(int diff)
Definition: vgl_rtree.hxx:65
vgl_rtree_const_iterator< V, B, C > const_iterator
Definition: vgl_rtree.h:257
node * secret_get_root() const
Definition: vgl_rtree.h:346
vgl_rtree_node< V, B, C > node
Definition: vgl_rtree.h:345
void erase(iterator i)
erase the element pointed to by the iterator.
Definition: vgl_rtree.h:303
virtual bool meets(V const &v) const
return true if the probe "meets" the given object.
Definition: vgl_rtree.h:28
iterator end()
Definition: vgl_rtree.h:262
unsigned local_chs
Definition: vgl_rtree.h:68
#define v
Definition: vgl_vector_2d.h:74
const_iterator end() const
Definition: vgl_rtree.h:263
void print() const
Definition: vgl_rtree.h:348
vgl_rtree_iterator_base< V, B, C > base
Definition: vgl_rtree.h:164
vgl_rtree_const_iterator()=default
unsigned total_chs
Definition: vgl_rtree.h:65
unsigned nodes() const
return number of nodes used by the tree.
Definition: vgl_rtree.h:340
Iterator for rtree.
Definition: vgl_algo_fwd.h:33
bool empty() const
return true iff the tree has no elements.
Definition: vgl_rtree.h:330
node * parent
Definition: vgl_rtree.h:51
Templated rtree class.
Definition: vgl_algo_fwd.h:35
node * root
Definition: vgl_rtree.h:353
vgl_rtree_node(node *parent, V const &v)
Definition: vgl_rtree.hxx:22
bool find(V const &v, node **n, int *i) const
Definition: vgl_rtree.hxx:77
vgl_rtree_iterator< V, B, C > iterator
iterators.
Definition: vgl_rtree.h:256
bool contains(V const &v) const
return true iff the rtree contains an element equal to v.
Definition: vgl_rtree.h:291
void erase(unsigned int i)
Definition: vgl_rtree.hxx:184
void get_all(std::vector< V > &vs) const
get all elements in the tree.
Definition: vgl_rtree.h:324
V & operator *() const
Definition: vgl_rtree.h:150
void get(B const &region, std::vector< V > &) const
Definition: vgl_rtree.hxx:284
self & operator++()
Definition: vgl_rtree.h:152
void update_total_chs(int diff)
Definition: vgl_rtree.hxx:51
#define vgl_rtree_MAX_CHILDREN
max. number of children of a given node.
Definition: vgl_rtree.h:38
const_iterator for rtree.
Definition: vgl_algo_fwd.h:34
void compute_bounds()
Definition: vgl_rtree.hxx:260
V const & operator *() const
Definition: vgl_rtree.h:172
~vgl_rtree()
Definition: vgl_rtree.h:246
bool operator!=(vgl_rtree_iterator_base< V, B, C > const &a, vgl_rtree_iterator_base< V, B, C > const &b)
Definition: vgl_rtree.h:134
vgl_rtree_node< V, B, C > node
Definition: vgl_rtree.h:145
vgl_rtree_node< V, B, C > node
Definition: vgl_rtree.h:166
vgl_rtree_iterator()=default
vgl_rtree_iterator_base< V, B, C > base
Definition: vgl_rtree.h:143
V vts[vgl_rtree_MAX_VERTICES]
Definition: vgl_rtree.h:61
vgl_rtree_node< V, B, C > node
Definition: vgl_rtree.h:118
unsigned local_vts
Definition: vgl_rtree.h:58
Base class for both rtree iterators.
Definition: vgl_algo_fwd.h:32
Function predicate object for querying the tree.
Definition: vgl_algo_fwd.h:30
iterator begin()
Definition: vgl_rtree.h:259