Eclipse SUMO - Simulation of Urban MObility
RTree.h
Go to the documentation of this file.
1 #ifndef RTREE_H
2 #define RTREE_H
3 
4 // NOTE This file compiles under MSVC 6 SP5 and MSVC .Net 2003 it may not work on other compilers without modification.
5 
6 // NOTE These next few lines may be win32 specific, you may need to modify them to compile on other platform
7 #include <stdio.h>
8 #include <math.h>
9 #include <assert.h>
10 #include <stdlib.h>
11 
12 #define ASSERT assert // RTree uses ASSERT( condition )
13 #ifndef Min
14  #define Min __min
15 #endif //Min
16 #ifndef Max
17  #define Max __max
18 #endif //Max
19 
20 #define rtree_min(a,b) (a<b?a:b)
21 #define rtree_max(a,b) (a>b?a:b)
22 
23 
24 
25 //
26 // RTree.h
27 //
28 
29 #define RTREE_TEMPLATE template<class DATATYPE, class DATATYPENP, class ELEMTYPE, int NUMDIMS, class CONTEXT, class ELEMTYPEREAL, int TMAXNODES, int TMINNODES>
30 #define RTREE_QUAL RTree<DATATYPE, DATATYPENP, ELEMTYPE, NUMDIMS, CONTEXT, ELEMTYPEREAL, TMAXNODES, TMINNODES>
31 
32 #define RTREE_DONT_USE_MEMPOOLS // This version does not contain a fixed memory allocator, fill in lines with EXAMPLE to implement one.
33 #define RTREE_USE_SPHERICAL_VOLUME // Better split classification, may be slower on some systems
34 
35 #undef RTREE_WANTS_IO
36 
37 // Fwd decl
38 #ifdef RTREE_WANTS_IO
39 class RTFileStream; // File I/O helper class, look below for implementation and notes.
40 #endif
41 
42 
59 template<class DATATYPE, class DATATYPENP, class ELEMTYPE, int NUMDIMS, class CONTEXT,
60  class ELEMTYPEREAL = ELEMTYPE, int TMAXNODES = 8, int TMINNODES = TMAXNODES / 2>
61 class RTree
62 {
63 protected:
64 
65  struct Node; // Fwd decl. Used by other internal structs and iterator
66 
67 public:
68 
69  // These constant must be declared after Branch and before Node struct
70  // Stuck up here for MSVC 6 compiler. NSVC .NET 2003 is much happier.
71  enum
72  {
73  MAXNODES = TMAXNODES,
74  MINNODES = TMINNODES
75  };
76 
77 
78 public:
79  typedef void(DATATYPENP::* Operation)(const CONTEXT &) const;
80 
81  RTree(Operation operation);
82  virtual ~RTree();
83 
88  virtual void Insert(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId);
89 
94  virtual void Remove(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId);
95 
96 
98  //typedef void(DATATYPENP::* Operation)(const CONTEXT &) const;
99 
107  virtual int Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const CONTEXT &c) const;
108 
110 
112  void RemoveAll();
113 
115  int Count();
116 
117 #ifdef RTREE_WANTS_IO
119  bool Load(const char* a_fileName);
121  bool Load(RTFileStream& a_stream);
122 
123 
125  bool Save(const char* a_fileName);
127  bool Save(RTFileStream& a_stream);
128 #endif
129 
131  class Iterator
132  {
133  private:
134 
135  enum { MAX_STACK = 32 }; // Max stack size. Allows almost n^32 where n is number of branches in node
136 
138  {
141  };
142 
143  public:
144 
145  Iterator() { Init(); }
146 
147  ~Iterator() { }
148 
150  bool IsNull() { return (m_tos <= 0); }
151 
153  bool IsNotNull() { return (m_tos > 0); }
154 
156  DATATYPE& operator*()
157  {
158  ASSERT(IsNotNull());
159  StackElement& curTos = m_stack[m_tos - 1];
160  return curTos.m_node->m_branch[curTos.m_branchIndex].m_data;
161  }
162 
164  const DATATYPE& operator*() const
165  {
166  ASSERT(IsNotNull());
167  StackElement& curTos = m_stack[m_tos - 1];
168  return curTos.m_node->m_branch[curTos.m_branchIndex].m_data;
169  }
170 
172  bool operator++() { return FindNextData(); }
173 
174  private:
175 
177  void Init() { m_tos = 0; }
178 
181  {
182  for(;;)
183  {
184  if(m_tos <= 0)
185  {
186  return false;
187  }
188  StackElement curTos = Pop(); // Copy stack top cause it may change as we use it
189 
190  if(curTos.m_node->IsLeaf())
191  {
192  // Keep walking through data while we can
193  if(curTos.m_branchIndex+1 < curTos.m_node->m_count)
194  {
195  // There is more data, just point to the next one
196  Push(curTos.m_node, curTos.m_branchIndex + 1);
197  return true;
198  }
199  // No more data, so it will fall back to previous level
200  }
201  else
202  {
203  if(curTos.m_branchIndex+1 < curTos.m_node->m_count)
204  {
205  // Push sibling on for future tree walk
206  // This is the 'fall back' node when we finish with the current level
207  Push(curTos.m_node, curTos.m_branchIndex + 1);
208  }
209  // Since cur node is not a leaf, push first of next level to get deeper into the tree
210  Node* nextLevelnode = curTos.m_node->m_branch[curTos.m_branchIndex].m_child;
211  Push(nextLevelnode, 0);
212 
213  // If we pushed on a new leaf, exit as the data is ready at TOS
214  if(nextLevelnode->IsLeaf())
215  {
216  return true;
217  }
218  }
219  }
220  }
221 
223  void Push(Node* a_node, int a_branchIndex)
224  {
225  m_stack[m_tos].m_node = a_node;
226  m_stack[m_tos].m_branchIndex = a_branchIndex;
227  ++m_tos;
228  ASSERT(m_tos <= MAX_STACK);
229  }
230 
233  {
234  ASSERT(m_tos > 0);
235  --m_tos;
236  return m_stack[m_tos];
237  }
238 
240  int m_tos;
241 
242  friend class RTree<DATATYPE, DATATYPENP, ELEMTYPE, NUMDIMS, CONTEXT, ELEMTYPEREAL, TMAXNODES, TMINNODES>; // Allow hiding of non-public functions while allowing manipulation by logical owner
243  };
244 
246  void GetFirst(Iterator& a_it)
247  {
248  a_it.Init();
249  if(m_root && (m_root->m_count > 0))
250  {
251  a_it.Push(m_root, 0);
252  a_it.FindNextData();
253  }
254  }
255 
257  void GetNext(Iterator& a_it) { ++a_it; }
258 
260  bool IsNull(Iterator& a_it) { return a_it.IsNull(); }
261 
263  DATATYPE& GetAt(Iterator& a_it) { return *a_it; }
264 
265 protected:
266 
268  struct Rect
269  {
270  ELEMTYPE m_min[NUMDIMS];
271  ELEMTYPE m_max[NUMDIMS];
272  };
273 
277  struct Branch
278  {
280  union
281  {
283  DATATYPE m_data;
284  };
285  };
286 
288  struct Node
289  {
290  bool IsInternalNode() const { return (m_level > 0); } // Not a leaf, but a internal node
291  bool IsLeaf() const { return (m_level == 0); } // A leaf, contains data
292 
293  int m_count;
294  int m_level;
296  };
297 
299  struct ListNode
300  {
303  };
304 
307  {
309  int m_total;
312  int m_count[2];
314  ELEMTYPEREAL m_area[2];
315 
319  ELEMTYPEREAL m_coverSplitArea;
320  };
321 
323  void FreeNode(Node* a_node);
324  void InitNode(Node* a_node);
325  void InitRect(Rect* a_rect);
326  bool InsertRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, Node** a_newNode, int a_level);
327  bool InsertRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root, int a_level);
328  Rect NodeCover(Node* a_node);
329  bool AddBranch(Branch* a_branch, Node* a_node, Node** a_newNode);
330  void DisconnectBranch(Node* a_node, int a_index);
331  int PickBranch(Rect* a_rect, Node* a_node);
332  Rect CombineRect(Rect* a_rectA, Rect* a_rectB);
333  void SplitNode(Node* a_node, Branch* a_branch, Node** a_newNode);
334  ELEMTYPEREAL RectSphericalVolume(Rect* a_rect);
335  ELEMTYPEREAL RectVolume(Rect* a_rect);
336  ELEMTYPEREAL CalcRectVolume(Rect* a_rect);
337  void GetBranches(Node* a_node, Branch* a_branch, PartitionVars* a_parVars);
338  void ChoosePartition(PartitionVars* a_parVars, int a_minFill);
339  void LoadNodes(Node* a_nodeA, Node* a_nodeB, PartitionVars* a_parVars);
340  void InitParVars(PartitionVars* a_parVars, int a_maxRects, int a_minFill);
341  void PickSeeds(PartitionVars* a_parVars);
342  void Classify(int a_index, int a_group, PartitionVars* a_parVars);
343  bool RemoveRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root);
344  bool RemoveRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, ListNode** a_listNode);
346  void FreeListNode(ListNode* a_listNode);
347  bool Overlap(Rect* a_rectA, Rect* a_rectB) const;
348  void ReInsert(Node* a_node, ListNode** a_listNode);
349  bool Search(Node* a_node, Rect* a_rect, int& a_foundCount, const CONTEXT &c) const;
350  void RemoveAllRec(Node* a_node);
351  void Reset();
352  void CountRec(Node* a_node, int& a_count);
353 
354 #ifdef RTREE_WANTS_IO
355  bool SaveRec(Node* a_node, RTFileStream& a_stream);
356  bool LoadRec(Node* a_node, RTFileStream& a_stream);
357 #endif
358 
360  ELEMTYPEREAL m_unitSphereVolume;
362 };
363 
364 
365 #ifdef RTREE_WANTS_IO
366 // Because there is not stream support, this is a quick and dirty file I/O helper.
367 // Users will likely replace its usage with a Stream implementation from their favorite API.
368 class RTFileStream
369 {
370  FILE* m_file;
371 
372 public:
373 
374 
375  RTFileStream()
376  {
377  m_file = NULL;
378  }
379 
380  ~RTFileStream()
381  {
382  Close();
383  }
384 
385  bool OpenRead(const char* a_fileName)
386  {
387  m_file = fopen(a_fileName, "rb");
388  if(!m_file)
389  {
390  return false;
391  }
392  return true;
393  }
394 
395  bool OpenWrite(const char* a_fileName)
396  {
397  m_file = fopen(a_fileName, "wb");
398  if(!m_file)
399  {
400  return false;
401  }
402  return true;
403  }
404 
405  void Close()
406  {
407  if(m_file)
408  {
409  fclose(m_file);
410  m_file = NULL;
411  }
412  }
413 
414  template< typename TYPE >
415  size_t Write(const TYPE& a_value)
416  {
417  ASSERT(m_file);
418  return fwrite((void*)&a_value, sizeof(a_value), 1, m_file);
419  }
420 
421  template< typename TYPE >
422  size_t WriteArray(const TYPE* a_array, int a_count)
423  {
424  ASSERT(m_file);
425  return fwrite((void*)a_array, sizeof(TYPE) * a_count, 1, m_file);
426  }
427 
428  template< typename TYPE >
429  size_t Read(TYPE& a_value)
430  {
431  ASSERT(m_file);
432  return fread((void*)&a_value, sizeof(a_value), 1, m_file);
433  }
434 
435  template< typename TYPE >
436  size_t ReadArray(TYPE* a_array, int a_count)
437  {
438  ASSERT(m_file);
439  return fread((void*)a_array, sizeof(TYPE) * a_count, 1, m_file);
440  }
441 };
442 #endif
443 
444 
446 RTREE_QUAL::RTree(Operation operation)
447 : myOperation(operation)
448 {
450  ASSERT(MINNODES > 0);
451 
452 
453  // We only support machine word size simple data type eg. integer index or object pointer.
454  // Since we are storing as union with non data branch
455  ASSERT(sizeof(DATATYPE) == sizeof(void*) || sizeof(DATATYPE) == sizeof(int));
456 
457  // Precomputed volumes of the unit spheres for the first few dimensions
458  const float UNIT_SPHERE_VOLUMES[] = {
459  0.000000f, 2.000000f, 3.141593f, // Dimension 0,1,2
460  4.188790f, 4.934802f, 5.263789f, // Dimension 3,4,5
461  5.167713f, 4.724766f, 4.058712f, // Dimension 6,7,8
462  3.298509f, 2.550164f, 1.884104f, // Dimension 9,10,11
463  1.335263f, 0.910629f, 0.599265f, // Dimension 12,13,14
464  0.381443f, 0.235331f, 0.140981f, // Dimension 15,16,17
465  0.082146f, 0.046622f, 0.025807f, // Dimension 18,19,20
466  };
467 
468  m_root = AllocNode();
469  m_root->m_level = 0;
470  m_unitSphereVolume = (ELEMTYPEREAL)UNIT_SPHERE_VOLUMES[NUMDIMS];
471 }
472 
473 
475 RTREE_QUAL::~RTree()
476 {
477  Reset(); // Free, or reset node memory
478 }
479 
480 
482 void RTREE_QUAL::Insert(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId)
483 {
484 #ifdef _DEBUG
485  for(int index=0; index<NUMDIMS; ++index)
486  {
487  ASSERT(a_min[index] <= a_max[index]);
488  }
489 #endif //_DEBUG
490 
491  Rect rect;
492 
493  for(int axis=0; axis<NUMDIMS; ++axis)
494  {
495  rect.m_min[axis] = a_min[axis];
496  rect.m_max[axis] = a_max[axis];
497  }
498 
499  InsertRect(&rect, a_dataId, &m_root, 0);
500 }
501 
502 
504 void RTREE_QUAL::Remove(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId)
505 {
506 #ifdef _DEBUG
507  for(int index=0; index<NUMDIMS; ++index)
508  {
509  ASSERT(a_min[index] <= a_max[index]);
510  }
511 #endif //_DEBUG
512 
513  Rect rect;
514 
515  for(int axis=0; axis<NUMDIMS; ++axis)
516  {
517  rect.m_min[axis] = a_min[axis];
518  rect.m_max[axis] = a_max[axis];
519  }
520 
521  RemoveRect(&rect, a_dataId, &m_root);
522 }
523 
524 
525 
527 int RTREE_QUAL::Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const CONTEXT &c) const
528 {
529 #ifdef _DEBUG
530  for(int index=0; index<NUMDIMS; ++index)
531  {
532  ASSERT(a_min[index] <= a_max[index]);
533  }
534 #endif //_DEBUG
535 
536  Rect rect;
537 
538  for(int axis=0; axis<NUMDIMS; ++axis)
539  {
540  rect.m_min[axis] = a_min[axis];
541  rect.m_max[axis] = a_max[axis];
542  }
543 
544  // NOTE: May want to return search result another way, perhaps returning the number of found elements here.
545 
546  int foundCount = 0;
547  Search(m_root, &rect, foundCount, c);
548 
549  return foundCount;
550 }
551 
552 
553 
554 
555 
556 
558 int RTREE_QUAL::Count()
559 {
560  int count = 0;
561  CountRec(m_root, count);
562 
563  return count;
564 }
565 
566 
567 
569 void RTREE_QUAL::CountRec(Node* a_node, int& a_count)
570 {
571  if(a_node->IsInternalNode()) // not a leaf node
572  {
573  for(int index = 0; index < a_node->m_count; ++index)
574  {
575  CountRec(a_node->m_branch[index].m_child, a_count);
576  }
577  }
578  else // A leaf node
579  {
580  a_count += a_node->m_count;
581  }
582 }
583 
584 
585 #ifdef RTREE_WANTS_IO
587 bool RTREE_QUAL::Load(const char* a_fileName)
588 {
589  RemoveAll(); // Clear existing tree
590 
591  RTFileStream stream;
592  if(!stream.OpenRead(a_fileName))
593  {
594  return false;
595  }
596 
597  bool result = Load(stream);
598 
599  stream.Close();
600 
601  return result;
602 }
603 
604 
605 
607 bool RTREE_QUAL::Load(RTFileStream& a_stream)
608 {
609  // Write some kind of header
610  int _dataFileId = ('R'<<0)|('T'<<8)|('R'<<16)|('E'<<24);
611  int _dataSize = sizeof(DATATYPE);
612  int _dataNumDims = NUMDIMS;
613  int _dataElemSize = sizeof(ELEMTYPE);
614  int _dataElemRealSize = sizeof(ELEMTYPEREAL);
615  int _dataMaxNodes = TMAXNODES;
616  int _dataMinNodes = TMINNODES;
617 
618  int dataFileId = 0;
619  int dataSize = 0;
620  int dataNumDims = 0;
621  int dataElemSize = 0;
622  int dataElemRealSize = 0;
623  int dataMaxNodes = 0;
624  int dataMinNodes = 0;
625 
626  a_stream.Read(dataFileId);
627  a_stream.Read(dataSize);
628  a_stream.Read(dataNumDims);
629  a_stream.Read(dataElemSize);
630  a_stream.Read(dataElemRealSize);
631  a_stream.Read(dataMaxNodes);
632  a_stream.Read(dataMinNodes);
633 
634  bool result = false;
635 
636  // Test if header was valid and compatible
637  if( (dataFileId == _dataFileId)
638  && (dataSize == _dataSize)
639  && (dataNumDims == _dataNumDims)
640  && (dataElemSize == _dataElemSize)
641  && (dataElemRealSize == _dataElemRealSize)
642  && (dataMaxNodes == _dataMaxNodes)
643  && (dataMinNodes == _dataMinNodes)
644  )
645  {
646  // Recursively load tree
647  result = LoadRec(m_root, a_stream);
648  }
649 
650  return result;
651 }
652 
653 
655 bool RTREE_QUAL::LoadRec(Node* a_node, RTFileStream& a_stream)
656 {
657  a_stream.Read(a_node->m_level);
658  a_stream.Read(a_node->m_count);
659 
660  if(a_node->IsInternalNode()) // not a leaf node
661  {
662  for(int index = 0; index < a_node->m_count; ++index)
663  {
664  Branch* curBranch = &a_node->m_branch[index];
665 
666  a_stream.ReadArray(curBranch->m_rect.m_min, NUMDIMS);
667  a_stream.ReadArray(curBranch->m_rect.m_max, NUMDIMS);
668 
669  curBranch->m_child = AllocNode();
670  LoadRec(curBranch->m_child, a_stream);
671  }
672  }
673  else // A leaf node
674  {
675  for(int index = 0; index < a_node->m_count; ++index)
676  {
677  Branch* curBranch = &a_node->m_branch[index];
678 
679  a_stream.ReadArray(curBranch->m_rect.m_min, NUMDIMS);
680  a_stream.ReadArray(curBranch->m_rect.m_max, NUMDIMS);
681 
682  a_stream.Read(curBranch->m_data);
683  }
684  }
685 
686  return true; // Should do more error checking on I/O operations
687 }
688 
689 
691 bool RTREE_QUAL::Save(const char* a_fileName)
692 {
693  RTFileStream stream;
694  if(!stream.OpenWrite(a_fileName))
695  {
696  return false;
697  }
698 
699  bool result = Save(stream);
700 
701  stream.Close();
702 
703  return result;
704 }
705 
706 
708 bool RTREE_QUAL::Save(RTFileStream& a_stream)
709 {
710  // Write some kind of header
711  int dataFileId = ('R'<<0)|('T'<<8)|('R'<<16)|('E'<<24);
712  int dataSize = sizeof(DATATYPE);
713  int dataNumDims = NUMDIMS;
714  int dataElemSize = sizeof(ELEMTYPE);
715  int dataElemRealSize = sizeof(ELEMTYPEREAL);
716  int dataMaxNodes = TMAXNODES;
717  int dataMinNodes = TMINNODES;
718 
719  a_stream.Write(dataFileId);
720  a_stream.Write(dataSize);
721  a_stream.Write(dataNumDims);
722  a_stream.Write(dataElemSize);
723  a_stream.Write(dataElemRealSize);
724  a_stream.Write(dataMaxNodes);
725  a_stream.Write(dataMinNodes);
726 
727  // Recursively save tree
728  bool result = SaveRec(m_root, a_stream);
729 
730  return result;
731 }
732 
733 
735 bool RTREE_QUAL::SaveRec(Node* a_node, RTFileStream& a_stream)
736 {
737  a_stream.Write(a_node->m_level);
738  a_stream.Write(a_node->m_count);
739 
740  if(a_node->IsInternalNode()) // not a leaf node
741  {
742  for(int index = 0; index < a_node->m_count; ++index)
743  {
744  Branch* curBranch = &a_node->m_branch[index];
745 
746  a_stream.WriteArray(curBranch->m_rect.m_min, NUMDIMS);
747  a_stream.WriteArray(curBranch->m_rect.m_max, NUMDIMS);
748 
749  SaveRec(curBranch->m_child, a_stream);
750  }
751  }
752  else // A leaf node
753  {
754  for(int index = 0; index < a_node->m_count; ++index)
755  {
756  Branch* curBranch = &a_node->m_branch[index];
757 
758  a_stream.WriteArray(curBranch->m_rect.m_min, NUMDIMS);
759  a_stream.WriteArray(curBranch->m_rect.m_max, NUMDIMS);
760 
761  a_stream.Write(curBranch->m_data);
762  }
763  }
764 
765  return true; // Should do more error checking on I/O operations
766 }
767 #endif
768 
769 
771 void RTREE_QUAL::RemoveAll()
772 {
773  // Delete all existing nodes
774  Reset();
775 
776  m_root = AllocNode();
777  m_root->m_level = 0;
778 }
779 
780 
782 void RTREE_QUAL::Reset()
783 {
784 #ifdef RTREE_DONT_USE_MEMPOOLS
785  // Delete all existing nodes
786  RemoveAllRec(m_root);
787 #else // RTREE_DONT_USE_MEMPOOLS
788  // Just reset memory pools. We are not using complex types
789  // EXAMPLE
790 #endif // RTREE_DONT_USE_MEMPOOLS
791 }
792 
793 
795 void RTREE_QUAL::RemoveAllRec(Node* a_node)
796 {
797  ASSERT(a_node);
798  ASSERT(a_node->m_level >= 0);
799 
800  if(a_node->IsInternalNode()) // This is an internal node in the tree
801  {
802  for(int index=0; index < a_node->m_count; ++index)
803  {
804  RemoveAllRec(a_node->m_branch[index].m_child);
805  }
806  }
807  FreeNode(a_node);
808 }
809 
810 
812 typename RTREE_QUAL::Node* RTREE_QUAL::AllocNode()
813 {
814  Node* newNode;
815 #ifdef RTREE_DONT_USE_MEMPOOLS
816  newNode = new Node;
817 #else // RTREE_DONT_USE_MEMPOOLS
818  // EXAMPLE
819 #endif // RTREE_DONT_USE_MEMPOOLS
820  InitNode(newNode);
821  return newNode;
822 }
823 
824 
826 void RTREE_QUAL::FreeNode(Node* a_node)
827 {
828  ASSERT(a_node);
829 
830 #ifdef RTREE_DONT_USE_MEMPOOLS
831  delete a_node;
832 #else // RTREE_DONT_USE_MEMPOOLS
833  // EXAMPLE
834 #endif // RTREE_DONT_USE_MEMPOOLS
835 }
836 
837 
838 // Allocate space for a node in the list used in DeletRect to
839 // store Nodes that are too empty.
841 typename RTREE_QUAL::ListNode* RTREE_QUAL::AllocListNode()
842 {
843 #ifdef RTREE_DONT_USE_MEMPOOLS
844  return new ListNode;
845 #else // RTREE_DONT_USE_MEMPOOLS
846  // EXAMPLE
847 #endif // RTREE_DONT_USE_MEMPOOLS
848 }
849 
850 
852 void RTREE_QUAL::FreeListNode(ListNode* a_listNode)
853 {
854 #ifdef RTREE_DONT_USE_MEMPOOLS
855  delete a_listNode;
856 #else // RTREE_DONT_USE_MEMPOOLS
857  // EXAMPLE
858 #endif // RTREE_DONT_USE_MEMPOOLS
859 }
860 
861 
863 void RTREE_QUAL::InitNode(Node* a_node)
864 {
865  a_node->m_count = 0;
866  a_node->m_level = -1;
867 }
868 
869 
871 void RTREE_QUAL::InitRect(Rect* a_rect)
872 {
873  for(int index = 0; index < NUMDIMS; ++index)
874  {
875  a_rect->m_min[index] = (ELEMTYPE)0;
876  a_rect->m_max[index] = (ELEMTYPE)0;
877  }
878 }
879 
880 
881 // Inserts a new data rectangle into the index structure.
882 // Recursively descends tree, propagates splits back up.
883 // Returns 0 if node was not split. Old node updated.
884 // If node was split, returns 1 and sets the pointer pointed to by
885 // new_node to point to the new node. Old node updated to become one of two.
886 // The level argument specifies the number of steps up from the leaf
887 // level to insert; e.g. a data rectangle goes in at level = 0.
889 bool RTREE_QUAL::InsertRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, Node** a_newNode, int a_level)
890 {
891  ASSERT(a_rect && a_node && a_newNode);
892  ASSERT(a_level >= 0 && a_level <= a_node->m_level);
893 
894  int index;
895  Branch branch;
896  Node* otherNode;
897 
898  // Still above level for insertion, go down tree recursively
899  if(a_node->m_level > a_level)
900  {
901  index = PickBranch(a_rect, a_node);
902  if (!InsertRectRec(a_rect, a_id, a_node->m_branch[index].m_child, &otherNode, a_level))
903  {
904  // Child was not split
905  a_node->m_branch[index].m_rect = CombineRect(a_rect, &(a_node->m_branch[index].m_rect));
906  return false;
907  }
908  else // Child was split
909  {
910  a_node->m_branch[index].m_rect = NodeCover(a_node->m_branch[index].m_child);
911  branch.m_child = otherNode;
912  branch.m_rect = NodeCover(otherNode);
913  return AddBranch(&branch, a_node, a_newNode);
914  }
915  }
916  else if(a_node->m_level == a_level) // Have reached level for insertion. Add rect, split if necessary
917  {
918  branch.m_rect = *a_rect;
919  branch.m_child = (Node*) a_id;
920  // Child field of leaves contains id of data record
921  return AddBranch(&branch, a_node, a_newNode);
922  }
923  else
924  {
925  // Should never occur
926  ASSERT(0);
927  return false;
928  }
929 }
930 
931 
932 // Insert a data rectangle into an index structure.
933 // InsertRect provides for splitting the root;
934 // returns 1 if root was split, 0 if it was not.
935 // The level argument specifies the number of steps up from the leaf
936 // level to insert; e.g. a data rectangle goes in at level = 0.
937 // InsertRect2 does the recursion.
938 //
940 bool RTREE_QUAL::InsertRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root, int a_level)
941 {
942  ASSERT(a_rect && a_root);
943  ASSERT(a_level >= 0 && a_level <= (*a_root)->m_level);
944 #ifdef _DEBUG
945  for(int index=0; index < NUMDIMS; ++index)
946  {
947  ASSERT(a_rect->m_min[index] <= a_rect->m_max[index]);
948  }
949 #endif //_DEBUG
950 
951  Node* newRoot;
952  Node* newNode;
953  Branch branch;
954 
955  if(InsertRectRec(a_rect, a_id, *a_root, &newNode, a_level)) // Root split
956  {
957  newRoot = AllocNode(); // Grow tree taller and new root
958  newRoot->m_level = (*a_root)->m_level + 1;
959  branch.m_rect = NodeCover(*a_root);
960  branch.m_child = *a_root;
961  AddBranch(&branch, newRoot, NULL);
962  branch.m_rect = NodeCover(newNode);
963  branch.m_child = newNode;
964  AddBranch(&branch, newRoot, NULL);
965  *a_root = newRoot;
966  return true;
967  }
968 
969  return false;
970 }
971 
972 
973 // Find the smallest rectangle that includes all rectangles in branches of a node.
975 typename RTREE_QUAL::Rect RTREE_QUAL::NodeCover(Node* a_node)
976 {
977  ASSERT(a_node);
978 
979  int firstTime = true;
980  Rect rect;
981  InitRect(&rect);
982 
983  for(int index = 0; index < a_node->m_count; ++index)
984  {
985  if(firstTime)
986  {
987  rect = a_node->m_branch[index].m_rect;
988  firstTime = false;
989  }
990  else
991  {
992  rect = CombineRect(&rect, &(a_node->m_branch[index].m_rect));
993  }
994  }
995 
996  return rect;
997 }
998 
999 
1000 // Add a branch to a node. Split the node if necessary.
1001 // Returns 0 if node not split. Old node updated.
1002 // Returns 1 if node split, sets *new_node to address of new node.
1003 // Old node updated, becomes one of two.
1005 bool RTREE_QUAL::AddBranch(Branch* a_branch, Node* a_node, Node** a_newNode)
1006 {
1007  ASSERT(a_branch);
1008  ASSERT(a_node);
1009 
1010  if(a_node->m_count < MAXNODES) // Split won't be necessary
1011  {
1012  a_node->m_branch[a_node->m_count] = *a_branch;
1013  ++a_node->m_count;
1014 
1015  return false;
1016  }
1017  else
1018  {
1019  ASSERT(a_newNode);
1020 
1021  SplitNode(a_node, a_branch, a_newNode);
1022  return true;
1023  }
1024 }
1025 
1026 
1027 // Disconnect a dependent node.
1028 // Caller must return (or stop using iteration index) after this as count has changed
1030 void RTREE_QUAL::DisconnectBranch(Node* a_node, int a_index)
1031 {
1032  ASSERT(a_node && (a_index >= 0) && (a_index < MAXNODES));
1033  ASSERT(a_node->m_count > 0);
1034 
1035  // Remove element by swapping with the last element to prevent gaps in array
1036  a_node->m_branch[a_index] = a_node->m_branch[a_node->m_count - 1];
1037 
1038  --a_node->m_count;
1039 }
1040 
1041 
1042 // Pick a branch. Pick the one that will need the smallest increase
1043 // in area to accomodate the new rectangle. This will result in the
1044 // least total area for the covering rectangles in the current node.
1045 // In case of a tie, pick the one which was smaller before, to get
1046 // the best resolution when searching.
1048 int RTREE_QUAL::PickBranch(Rect* a_rect, Node* a_node)
1049 {
1050  ASSERT(a_rect && a_node);
1051 
1052  bool firstTime = true;
1053  ELEMTYPEREAL increase;
1054  ELEMTYPEREAL bestIncr = (ELEMTYPEREAL)-1;
1055  ELEMTYPEREAL area;
1056  ELEMTYPEREAL bestArea = 0;
1057  int best = 0;
1058  Rect tempRect;
1059 
1060  for(int index=0; index < a_node->m_count; ++index)
1061  {
1062  Rect* curRect = &a_node->m_branch[index].m_rect;
1063  area = CalcRectVolume(curRect);
1064  tempRect = CombineRect(a_rect, curRect);
1065  increase = CalcRectVolume(&tempRect) - area;
1066  if((increase < bestIncr) || firstTime)
1067  {
1068  best = index;
1069  bestArea = area;
1070  bestIncr = increase;
1071  firstTime = false;
1072  }
1073  else if((increase == bestIncr) && (area < bestArea))
1074  {
1075  best = index;
1076  bestArea = area;
1077  bestIncr = increase;
1078  }
1079  }
1080  return best;
1081 }
1082 
1083 
1084 // Combine two rectangles into larger one containing both
1086 typename RTREE_QUAL::Rect RTREE_QUAL::CombineRect(Rect* a_rectA, Rect* a_rectB)
1087 {
1088  ASSERT(a_rectA && a_rectB);
1089 
1090  Rect newRect;
1091 
1092  for(int index = 0; index < NUMDIMS; ++index)
1093  {
1094  newRect.m_min[index] = rtree_min(a_rectA->m_min[index], a_rectB->m_min[index]);
1095  newRect.m_max[index] = rtree_max(a_rectA->m_max[index], a_rectB->m_max[index]);
1096  }
1097 
1098  return newRect;
1099 }
1100 
1101 
1102 
1103 // Split a node.
1104 // Divides the nodes branches and the extra one between two nodes.
1105 // Old node is one of the new ones, and one really new one is created.
1106 // Tries more than one method for choosing a partition, uses best result.
1108 void RTREE_QUAL::SplitNode(Node* a_node, Branch* a_branch, Node** a_newNode)
1109 {
1110  ASSERT(a_node);
1111  ASSERT(a_branch);
1112 
1113  // Could just use local here, but member or external is faster since it is reused
1114  PartitionVars localVars;
1115  PartitionVars* parVars = &localVars;
1116  int level;
1117 
1118  // Load all the branches into a buffer, initialize old node
1119  level = a_node->m_level;
1120  GetBranches(a_node, a_branch, parVars);
1121 
1122  // Find partition
1123  ChoosePartition(parVars, MINNODES);
1124 
1125  // Put branches from buffer into 2 nodes according to chosen partition
1126  *a_newNode = AllocNode();
1127  (*a_newNode)->m_level = a_node->m_level = level;
1128  LoadNodes(a_node, *a_newNode, parVars);
1129 
1130  ASSERT((a_node->m_count + (*a_newNode)->m_count) == parVars->m_total);
1131 }
1132 
1133 
1134 // Calculate the n-dimensional volume of a rectangle
1136 ELEMTYPEREAL RTREE_QUAL::RectVolume(Rect* a_rect)
1137 {
1138  ASSERT(a_rect);
1139 
1140  ELEMTYPEREAL volume = (ELEMTYPEREAL)1;
1141 
1142  for(int index=0; index<NUMDIMS; ++index)
1143  {
1144  volume *= a_rect->m_max[index] - a_rect->m_min[index];
1145  }
1146 
1147  ASSERT(volume >= (ELEMTYPEREAL)0);
1148 
1149  return volume;
1150 }
1151 
1152 
1153 // The exact volume of the bounding sphere for the given Rect
1155 ELEMTYPEREAL RTREE_QUAL::RectSphericalVolume(Rect* a_rect)
1156 {
1157  ASSERT(a_rect);
1158 
1159  ELEMTYPEREAL sumOfSquares = (ELEMTYPEREAL)0;
1160  ELEMTYPEREAL radius;
1161 
1162  for(int index=0; index < NUMDIMS; ++index)
1163  {
1164  ELEMTYPEREAL halfExtent = ((ELEMTYPEREAL)a_rect->m_max[index] - (ELEMTYPEREAL)a_rect->m_min[index]) * 0.5f;
1165  sumOfSquares += halfExtent * halfExtent;
1166  }
1167 
1168  radius = (ELEMTYPEREAL)sqrt(sumOfSquares);
1169 
1170  // Pow maybe slow, so test for common dims like 2,3 and just use x*x, x*x*x.
1171  if(NUMDIMS == 3)
1172  {
1173  return (radius * radius * radius * m_unitSphereVolume);
1174  }
1175  else if(NUMDIMS == 2)
1176  {
1177  return (radius * radius * m_unitSphereVolume);
1178  }
1179  else
1180  {
1181  return (ELEMTYPEREAL)(pow(radius, NUMDIMS) * m_unitSphereVolume);
1182  }
1183 }
1184 
1185 
1186 // Use one of the methods to calculate retangle volume
1188 ELEMTYPEREAL RTREE_QUAL::CalcRectVolume(Rect* a_rect)
1189 {
1190 #ifdef RTREE_USE_SPHERICAL_VOLUME
1191  return RectSphericalVolume(a_rect); // Slower but helps certain merge cases
1192 #else // RTREE_USE_SPHERICAL_VOLUME
1193  return RectVolume(a_rect); // Faster but can cause poor merges
1194 #endif // RTREE_USE_SPHERICAL_VOLUME
1195 }
1196 
1197 
1198 // Load branch buffer with branches from full node plus the extra branch.
1200 void RTREE_QUAL::GetBranches(Node* a_node, Branch* a_branch, PartitionVars* a_parVars)
1201 {
1202  ASSERT(a_node);
1203  ASSERT(a_branch);
1204 
1205  ASSERT(a_node->m_count == MAXNODES);
1206 
1207  // Load the branch buffer
1208  int index;
1209  for(index=0; index < MAXNODES; ++index)
1210  {
1211  a_parVars->m_branchBuf[index] = a_node->m_branch[index];
1212  }
1213  a_parVars->m_branchBuf[MAXNODES] = *a_branch;
1214  a_parVars->m_branchCount = MAXNODES + 1;
1215 
1216  // Calculate rect containing all in the set
1217  a_parVars->m_coverSplit = a_parVars->m_branchBuf[0].m_rect;
1218  for(index=1; index < MAXNODES+1; ++index)
1219  {
1220  a_parVars->m_coverSplit = CombineRect(&a_parVars->m_coverSplit, &a_parVars->m_branchBuf[index].m_rect);
1221  }
1222  a_parVars->m_coverSplitArea = CalcRectVolume(&a_parVars->m_coverSplit);
1223 
1224  InitNode(a_node);
1225 }
1226 
1227 
1228 // Method #0 for choosing a partition:
1229 // As the seeds for the two groups, pick the two rects that would waste the
1230 // most area if covered by a single rectangle, i.e. evidently the worst pair
1231 // to have in the same group.
1232 // Of the remaining, one at a time is chosen to be put in one of the two groups.
1233 // The one chosen is the one with the greatest difference in area expansion
1234 // depending on which group - the rect most strongly attracted to one group
1235 // and repelled from the other.
1236 // If one group gets too full (more would force other group to violate min
1237 // fill requirement) then other group gets the rest.
1238 // These last are the ones that can go in either group most easily.
1240 void RTREE_QUAL::ChoosePartition(PartitionVars* a_parVars, int a_minFill)
1241 {
1242  ASSERT(a_parVars);
1243 
1244  ELEMTYPEREAL biggestDiff;
1245  int group, chosen = 0, betterGroup = 0;
1246 
1247  InitParVars(a_parVars, a_parVars->m_branchCount, a_minFill);
1248  PickSeeds(a_parVars);
1249 
1250  while (((a_parVars->m_count[0] + a_parVars->m_count[1]) < a_parVars->m_total)
1251  && (a_parVars->m_count[0] < (a_parVars->m_total - a_parVars->m_minFill))
1252  && (a_parVars->m_count[1] < (a_parVars->m_total - a_parVars->m_minFill)))
1253  {
1254  biggestDiff = (ELEMTYPEREAL) -1;
1255  for(int index=0; index<a_parVars->m_total; ++index)
1256  {
1257  if(!a_parVars->m_taken[index])
1258  {
1259  Rect* curRect = &a_parVars->m_branchBuf[index].m_rect;
1260  Rect rect0 = CombineRect(curRect, &a_parVars->m_cover[0]);
1261  Rect rect1 = CombineRect(curRect, &a_parVars->m_cover[1]);
1262  ELEMTYPEREAL growth0 = CalcRectVolume(&rect0) - a_parVars->m_area[0];
1263  ELEMTYPEREAL growth1 = CalcRectVolume(&rect1) - a_parVars->m_area[1];
1264  ELEMTYPEREAL diff = growth1 - growth0;
1265  if(diff >= 0)
1266  {
1267  group = 0;
1268  }
1269  else
1270  {
1271  group = 1;
1272  diff = -diff;
1273  }
1274 
1275  if(diff > biggestDiff)
1276  {
1277  biggestDiff = diff;
1278  chosen = index;
1279  betterGroup = group;
1280  }
1281  else if((diff == biggestDiff) && (a_parVars->m_count[group] < a_parVars->m_count[betterGroup]))
1282  {
1283  chosen = index;
1284  betterGroup = group;
1285  }
1286  }
1287  }
1288  Classify(chosen, betterGroup, a_parVars);
1289  }
1290 
1291  // If one group too full, put remaining rects in the other
1292  if((a_parVars->m_count[0] + a_parVars->m_count[1]) < a_parVars->m_total)
1293  {
1294  if(a_parVars->m_count[0] >= a_parVars->m_total - a_parVars->m_minFill)
1295  {
1296  group = 1;
1297  }
1298  else
1299  {
1300  group = 0;
1301  }
1302  for(int index=0; index<a_parVars->m_total; ++index)
1303  {
1304  if(!a_parVars->m_taken[index])
1305  {
1306  Classify(index, group, a_parVars);
1307  }
1308  }
1309  }
1310 
1311  ASSERT((a_parVars->m_count[0] + a_parVars->m_count[1]) == a_parVars->m_total);
1312  ASSERT((a_parVars->m_count[0] >= a_parVars->m_minFill) &&
1313  (a_parVars->m_count[1] >= a_parVars->m_minFill));
1314 }
1315 
1316 
1317 // Copy branches from the buffer into two nodes according to the partition.
1319 void RTREE_QUAL::LoadNodes(Node* a_nodeA, Node* a_nodeB, PartitionVars* a_parVars)
1320 {
1321  ASSERT(a_nodeA);
1322  ASSERT(a_nodeB);
1323  ASSERT(a_parVars);
1324 
1325  for(int index=0; index < a_parVars->m_total; ++index)
1326  {
1327  ASSERT(a_parVars->m_partition[index] == 0 || a_parVars->m_partition[index] == 1);
1328 
1329  if(a_parVars->m_partition[index] == 0)
1330  {
1331  AddBranch(&a_parVars->m_branchBuf[index], a_nodeA, NULL);
1332  }
1333  else if(a_parVars->m_partition[index] == 1)
1334  {
1335  AddBranch(&a_parVars->m_branchBuf[index], a_nodeB, NULL);
1336  }
1337  }
1338 }
1339 
1340 
1341 // Initialize a PartitionVars structure.
1343 void RTREE_QUAL::InitParVars(PartitionVars* a_parVars, int a_maxRects, int a_minFill)
1344 {
1345  ASSERT(a_parVars);
1346 
1347  a_parVars->m_count[0] = a_parVars->m_count[1] = 0;
1348  a_parVars->m_area[0] = a_parVars->m_area[1] = (ELEMTYPEREAL)0;
1349  a_parVars->m_total = a_maxRects;
1350  a_parVars->m_minFill = a_minFill;
1351  for(int index=0; index < a_maxRects; ++index)
1352  {
1353  a_parVars->m_taken[index] = false;
1354  a_parVars->m_partition[index] = -1;
1355  }
1356 }
1357 
1358 
1360 void RTREE_QUAL::PickSeeds(PartitionVars* a_parVars)
1361 {
1362  int seed0=0, seed1=1;
1363  ELEMTYPEREAL worst, waste;
1364  ELEMTYPEREAL area[MAXNODES+1];
1365 
1366  for(int index=0; index<a_parVars->m_total; ++index)
1367  {
1368  area[index] = CalcRectVolume(&a_parVars->m_branchBuf[index].m_rect);
1369  }
1370 
1371  worst = -a_parVars->m_coverSplitArea - 1;
1372  for(int indexA=0; indexA < a_parVars->m_total-1; ++indexA)
1373  {
1374  for(int indexB = indexA+1; indexB < a_parVars->m_total; ++indexB)
1375  {
1376  Rect oneRect = CombineRect(&a_parVars->m_branchBuf[indexA].m_rect, &a_parVars->m_branchBuf[indexB].m_rect);
1377  waste = CalcRectVolume(&oneRect) - area[indexA] - area[indexB];
1378  if(waste > worst)
1379  {
1380  worst = waste;
1381  seed0 = indexA;
1382  seed1 = indexB;
1383  }
1384  }
1385  }
1386  Classify(seed0, 0, a_parVars);
1387  Classify(seed1, 1, a_parVars);
1388 }
1389 
1390 
1391 // Put a branch in one of the groups.
1393 void RTREE_QUAL::Classify(int a_index, int a_group, PartitionVars* a_parVars)
1394 {
1395  ASSERT(a_parVars);
1396  ASSERT(!a_parVars->m_taken[a_index]);
1397 
1398  a_parVars->m_partition[a_index] = a_group;
1399  a_parVars->m_taken[a_index] = true;
1400 
1401  if (a_parVars->m_count[a_group] == 0)
1402  {
1403  a_parVars->m_cover[a_group] = a_parVars->m_branchBuf[a_index].m_rect;
1404  }
1405  else
1406  {
1407  a_parVars->m_cover[a_group] = CombineRect(&a_parVars->m_branchBuf[a_index].m_rect, &a_parVars->m_cover[a_group]);
1408  }
1409  a_parVars->m_area[a_group] = CalcRectVolume(&a_parVars->m_cover[a_group]);
1410  ++a_parVars->m_count[a_group];
1411 }
1412 
1413 
1414 // Delete a data rectangle from an index structure.
1415 // Pass in a pointer to a Rect, the tid of the record, ptr to ptr to root node.
1416 // Returns 1 if record not found, 0 if success.
1417 // RemoveRect provides for eliminating the root.
1419 bool RTREE_QUAL::RemoveRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root)
1420 {
1421  ASSERT(a_rect && a_root);
1422  ASSERT(*a_root);
1423 
1424  Node* tempNode;
1425  ListNode* reInsertList = NULL;
1426 
1427  if(!RemoveRectRec(a_rect, a_id, *a_root, &reInsertList))
1428  {
1429  // Found and deleted a data item
1430  // Reinsert any branches from eliminated nodes
1431  while(reInsertList)
1432  {
1433  tempNode = reInsertList->m_node;
1434 
1435  for(int index = 0; index < tempNode->m_count; ++index)
1436  {
1437  InsertRect(&(tempNode->m_branch[index].m_rect),
1438  tempNode->m_branch[index].m_data,
1439  a_root,
1440  tempNode->m_level);
1441  }
1442 
1443  ListNode* remLNode = reInsertList;
1444  reInsertList = reInsertList->m_next;
1445 
1446  FreeNode(remLNode->m_node);
1447  FreeListNode(remLNode);
1448  }
1449 
1450  // Check for redundant root (not leaf, 1 child) and eliminate
1451  if((*a_root)->m_count == 1 && (*a_root)->IsInternalNode())
1452  {
1453  tempNode = (*a_root)->m_branch[0].m_child;
1454 
1455  ASSERT(tempNode);
1456  FreeNode(*a_root);
1457  *a_root = tempNode;
1458  }
1459  return false;
1460  }
1461  else
1462  {
1463  return true;
1464  }
1465 }
1466 
1467 
1468 // Delete a rectangle from non-root part of an index structure.
1469 // Called by RemoveRect. Descends tree recursively,
1470 // merges branches on the way back up.
1471 // Returns 1 if record not found, 0 if success.
1473 bool RTREE_QUAL::RemoveRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, ListNode** a_listNode)
1474 {
1475  ASSERT(a_rect && a_node && a_listNode);
1476  ASSERT(a_node->m_level >= 0);
1477 
1478  if(a_node->IsInternalNode()) // not a leaf node
1479  {
1480  for(int index = 0; index < a_node->m_count; ++index)
1481  {
1482  if(Overlap(a_rect, &(a_node->m_branch[index].m_rect)))
1483  {
1484  if(!RemoveRectRec(a_rect, a_id, a_node->m_branch[index].m_child, a_listNode))
1485  {
1486  if(a_node->m_branch[index].m_child->m_count >= MINNODES)
1487  {
1488  // child removed, just resize parent rect
1489  a_node->m_branch[index].m_rect = NodeCover(a_node->m_branch[index].m_child);
1490  }
1491  else
1492  {
1493  // child removed, not enough entries in node, eliminate node
1494  ReInsert(a_node->m_branch[index].m_child, a_listNode);
1495  DisconnectBranch(a_node, index); // Must return after this call as count has changed
1496  }
1497  return false;
1498  }
1499  }
1500  }
1501  return true;
1502  }
1503  else // A leaf node
1504  {
1505  for(int index = 0; index < a_node->m_count; ++index)
1506  {
1507  if(a_node->m_branch[index].m_child == (Node*)a_id)
1508  {
1509  DisconnectBranch(a_node, index); // Must return after this call as count has changed
1510  return false;
1511  }
1512  }
1513  return true;
1514  }
1515 }
1516 
1517 
1518 // Decide whether two rectangles overlap.
1520 bool RTREE_QUAL::Overlap(Rect* a_rectA, Rect* a_rectB) const
1521 {
1522  ASSERT(a_rectA && a_rectB);
1523 
1524  for(int index=0; index < NUMDIMS; ++index)
1525  {
1526  if (a_rectA->m_min[index] > a_rectB->m_max[index] ||
1527  a_rectB->m_min[index] > a_rectA->m_max[index])
1528  {
1529  return false;
1530  }
1531  }
1532  return true;
1533 }
1534 
1535 
1536 // Add a node to the reinsertion list. All its branches will later
1537 // be reinserted into the index structure.
1539 void RTREE_QUAL::ReInsert(Node* a_node, ListNode** a_listNode)
1540 {
1541  ListNode* newListNode;
1542 
1543  newListNode = AllocListNode();
1544  newListNode->m_node = a_node;
1545  newListNode->m_next = *a_listNode;
1546  *a_listNode = newListNode;
1547 }
1548 
1549 
1550 
1551 // Search in an index tree or subtree for all data retangles that overlap the argument rectangle.
1553 bool RTREE_QUAL::Search(Node* a_node, Rect* a_rect, int& a_foundCount, const CONTEXT &c) const
1554 {
1555  ASSERT(a_node);
1556  ASSERT(a_node->m_level >= 0);
1557  ASSERT(a_rect);
1558 
1559  if(a_node->IsInternalNode()) // This is an internal node in the tree
1560  {
1561  for(int index=0; index < a_node->m_count; ++index)
1562  {
1563  if(Overlap(a_rect, &a_node->m_branch[index].m_rect))
1564  {
1565  if(!Search(a_node->m_branch[index].m_child, a_rect, a_foundCount, c))
1566  {
1567  return false; // Don't continue searching
1568  }
1569  }
1570  }
1571  }
1572  else // This is a leaf node
1573  {
1574  for(int index=0; index < a_node->m_count; ++index)
1575  {
1576  if(Overlap(a_rect, &a_node->m_branch[index].m_rect))
1577  {
1578  DATATYPE& id = a_node->m_branch[index].m_data;
1579 
1580  // NOTE: There are different ways to return results. Here's where to modify
1581 /* if(&a_resultCallback)
1582  {*/
1583  ++a_foundCount;
1584  (id->*myOperation)(c);
1585  /*
1586  if(!a_resultCallback(id, a_context))
1587  {
1588  return false; // Don't continue searching
1589  }
1590  */
1591 // }
1592  }
1593  }
1594  }
1595 
1596  return true; // Continue searching
1597 }
1598 
1599 
1600 
1601 
1602 #undef RTREE_TEMPLATE
1603 #undef RTREE_QUAL
1604 
1605 #endif //RTREE_H
#define rtree_min(a, b)
Definition: RTree.h:20
#define rtree_max(a, b)
Definition: RTree.h:21
#define RTREE_TEMPLATE
Definition: RTree.h:29
#define ASSERT
Definition: RTree.h:12
Definition: Node.h:39
Iterator is not remove safe.
Definition: RTree.h:132
StackElement m_stack[MAX_STACK]
Stack as we are doing iteration instead of recursion.
Definition: RTree.h:239
DATATYPE & operator*()
Access the current data element. Caller must be sure iterator is not NULL first.
Definition: RTree.h:156
StackElement & Pop()
Pop element off iteration stack (For internal use only)
Definition: RTree.h:232
bool IsNull()
Is iterator invalid.
Definition: RTree.h:150
void Init()
Reset iterator.
Definition: RTree.h:177
int m_tos
Top Of Stack index.
Definition: RTree.h:240
bool operator++()
Find the next data element.
Definition: RTree.h:172
const DATATYPE & operator*() const
Access the current data element. Caller must be sure iterator is not NULL first.
Definition: RTree.h:164
void Push(Node *a_node, int a_branchIndex)
Push node and branch onto iteration stack (For internal use only)
Definition: RTree.h:223
bool FindNextData()
Find the next data element in the tree (For internal use only)
Definition: RTree.h:180
bool IsNotNull()
Is iterator pointing to valid data.
Definition: RTree.h:153
Definition: RTree.h:62
ListNode * AllocListNode()
ELEMTYPEREAL m_unitSphereVolume
Unit sphere constant for required number of dimensions.
Definition: RTree.h:360
virtual void Remove(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE &a_dataId)
void SplitNode(Node *a_node, Branch *a_branch, Node **a_newNode)
void RemoveAll()
DK 15.10.2008 - end.
ELEMTYPEREAL CalcRectVolume(Rect *a_rect)
bool Search(Node *a_node, Rect *a_rect, int &a_foundCount, const CONTEXT &c) const
ELEMTYPEREAL RectSphericalVolume(Rect *a_rect)
bool InsertRect(Rect *a_rect, const DATATYPE &a_id, Node **a_root, int a_level)
void DisconnectBranch(Node *a_node, int a_index)
@ MINNODES
Min elements in node.
Definition: RTree.h:74
@ MAXNODES
Max elements in node.
Definition: RTree.h:73
void InitRect(Rect *a_rect)
Node * AllocNode()
bool AddBranch(Branch *a_branch, Node *a_node, Node **a_newNode)
bool InsertRectRec(Rect *a_rect, const DATATYPE &a_id, Node *a_node, Node **a_newNode, int a_level)
void FreeListNode(ListNode *a_listNode)
virtual ~RTree()
int Count()
Count the data elements in this container. This is slow as no internal counter is maintained.
int PickBranch(Rect *a_rect, Node *a_node)
RTree(Operation operation)
bool RemoveRect(Rect *a_rect, const DATATYPE &a_id, Node **a_root)
void FreeNode(Node *a_node)
void InitNode(Node *a_node)
DATATYPE & GetAt(Iterator &a_it)
Get object at iterator position.
Definition: RTree.h:263
virtual int Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const CONTEXT &c) const
DK 15.10.2008 - begin.
void GetNext(Iterator &a_it)
Get Next for iteration.
Definition: RTree.h:257
void CountRec(Node *a_node, int &a_count)
Operation myOperation
Definition: RTree.h:361
void GetFirst(Iterator &a_it)
Get 'first' for iteration.
Definition: RTree.h:246
void Reset()
void Classify(int a_index, int a_group, PartitionVars *a_parVars)
void RemoveAllRec(Node *a_node)
ELEMTYPEREAL RectVolume(Rect *a_rect)
void PickSeeds(PartitionVars *a_parVars)
void GetBranches(Node *a_node, Branch *a_branch, PartitionVars *a_parVars)
void ReInsert(Node *a_node, ListNode **a_listNode)
void ChoosePartition(PartitionVars *a_parVars, int a_minFill)
virtual void Insert(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE &a_dataId)
bool RemoveRectRec(Rect *a_rect, const DATATYPE &a_id, Node *a_node, ListNode **a_listNode)
void LoadNodes(Node *a_nodeA, Node *a_nodeB, PartitionVars *a_parVars)
Rect CombineRect(Rect *a_rectA, Rect *a_rectB)
void InitParVars(PartitionVars *a_parVars, int a_maxRects, int a_minFill)
void(DATATYPENP::* Operation)(const CONTEXT &) const
Definition: RTree.h:79
bool IsNull(Iterator &a_it)
Is iterator NULL, or at end?
Definition: RTree.h:260
Rect NodeCover(Node *a_node)
bool Overlap(Rect *a_rectA, Rect *a_rectB) const
Node * m_root
Root of tree.
Definition: RTree.h:359
Rect m_rect
Bounds.
Definition: RTree.h:279
DATATYPE m_data
Data Id or Ptr.
Definition: RTree.h:283
Node * m_child
Child node.
Definition: RTree.h:282
A link list of nodes for reinsertion after a delete operation.
Definition: RTree.h:300
Node * m_node
Node.
Definition: RTree.h:302
ListNode * m_next
Next in list.
Definition: RTree.h:301
Node for each branch level.
Definition: RTree.h:289
Branch m_branch[MAXNODES]
Branch.
Definition: RTree.h:295
bool IsLeaf() const
Definition: RTree.h:291
bool IsInternalNode() const
Definition: RTree.h:290
int m_count
Count.
Definition: RTree.h:293
int m_level
Leaf is zero, others positive.
Definition: RTree.h:294
Variables for finding a split partition.
Definition: RTree.h:307
int m_taken[MAXNODES+1]
Definition: RTree.h:311
ELEMTYPEREAL m_area[2]
Definition: RTree.h:314
Rect m_cover[2]
Definition: RTree.h:313
int m_partition[MAXNODES+1]
Definition: RTree.h:308
Branch m_branchBuf[MAXNODES+1]
Definition: RTree.h:316
ELEMTYPEREAL m_coverSplitArea
Definition: RTree.h:319
Minimal bounding rectangle (n-dimensional)
Definition: RTree.h:269
ELEMTYPE m_max[NUMDIMS]
Max dimensions of bounding box.
Definition: RTree.h:271
ELEMTYPE m_min[NUMDIMS]
Min dimensions of bounding box.
Definition: RTree.h:270