Loading...
Searching...
No Matches
Index.h
Go to the documentation of this file.
1/* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2
3 This file is part of the TerraLib - a Framework for building GIS enabled applications.
4
5 TerraLib is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 TerraLib is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with TerraLib. See COPYING. If not, write to
17 TerraLib Team at <terralib-team@terralib.org>.
18 */
19
20/*!
21 \file Index.h
22
23 \brief An implementation of R-tree data structure for main memory.
24*/
25
26#ifndef __TERRALIB_SAM_RTREE_INTERNAL_INDEX_H
27#define __TERRALIB_SAM_RTREE_INTERNAL_INDEX_H
28
29// TerraLib
30#include "Node.h"
31#include "PartitionVars.h"
32
33// STL
34#include <cassert>
35#include <vector>
36
37namespace te
38{
39 namespace sam
40 {
41 namespace rtree
42 {
43 /*!
44 \class Index
45
46 \brief A class that represents an R-tree.
47
48 This implementation is based on:
49
50 <i>Antonin Guttman. R-Trees: A Dynamic Index Structure for Spatial Searching. ACM SIGMOD: International Conference on Management of Data, 1984, pp. 47-57</i>.
51
52 and in his original source code.
53
54 \todo Implement nearest neighbour query.
55 */
56 template<class DATATYPE, int MAXNODES = 8, int MINNODES = MAXNODES / 2> class Index
57 {
58 public:
59
63
64 /*! \brief Constructor. */
66
67 /*!
68 \brief Constructor.
69
70 \param mbr The MBR of all elements in the R-tree.
71
72 \pre The given MBR must be valid.
73 */
75
76 /*! \brief Destructor. */
78
79 /*!
80 \brief It returns the number of elements in the tree.
81
82 \return The number of indexed elements.
83 */
84 std::size_t size(void) const;
85
86 /*!
87 \brief It returns true if the tree is empty.
88
89 \return True if the tree is empty.
90 */
91 bool isEmpty(void) const;
92
93 /*! It clears all tree nodes and make it ready for new insertions. */
94 void clear(void);
95
96 /*!
97 \brief It inserts an item into the tree.
98
99 \param mbr The object MBR.
100 \param data The object to be indexed.
101 */
102 void insert(const te::gm::Envelope& mbr, const DATATYPE& data);
103
104 /*!
105 \brief It removes an item from the tree.
106
107 \param mbr The object MBR.
108 \param data The object to be removed from the tree.
109
110 \return True if the object is found and removed, false otherwise.
111 */
112 bool remove(const te::gm::Envelope& mbr, const DATATYPE& data);
113
114 /*!
115 \brief Range search query.
116
117 \param mbr The search rectangle.
118 \param report A vector to output the founded objects.
119
120 \return the number of found objects.
121 */
122 int search(const te::gm::Envelope& mbr, std::vector<DATATYPE>& report) const;
123
124 /*!
125 \brief It sets the bounding box of all elements in the tree.
126
127 \param mbr The bounding box of all elements in the tree.
128 */
129 void setMBR(const te::gm::Envelope& mbr);
130
131 /*!
132 \brief It returns the bounding box of all elements in the tree.
133
134 \return The bounding box of all elements in the tree.
135 */
136 const te::gm::Envelope& getMBR(void) const;
137
138 protected:
139
140 /*!
141 \brief It inserts a data rectangle into an index structure.
142
143 \return It returns true if root was split, false if it was not.
144 */
145 bool insert(const te::gm::Envelope& mbr, const DATATYPE& data, NodeType** root, int level);
146
147 /*!
148 \brief It deletes a data rectangle from an index structure.
149
150 \return It returns 1 if record not found, 0 if success.
151 */
152 bool remove(const te::gm::Envelope& mbr, const DATATYPE& data, NodeType** root);
153
154 /*!
155 \brief It deletes a rectangle from non-root part of an index structure.
156
157 \return
158 */
159 bool remove2(const te::gm::Envelope& mbr, const DATATYPE& data, NodeType* n, std::vector<NodeType*>& ee);
160
161 /*!
162 \brief It disconnects a dependent node.
163 */
164 void disconBranch(NodeType* n, int i);
165
166 /*!
167 \brief It inserts a new data rectangle into the index structure.
168 */
170 const DATATYPE& data,
171 NodeType* node,
172 NodeType** newNode,
173 int level);
174
175 /*!
176 \brief Recursive range query.
177 */
178 void search(const te::gm::Envelope& mbr,
179 NodeType* node,
180 std::vector<DATATYPE>& report,
181 int& foundObjs) const;
182
183 /*!
184 \brief Find the smallest rectangle that includes all rectangles in branches of a node.
185 */
187
188 /*!
189 \brief Combine two rectangles into larger one containing both.
190 */
192 const te::gm::Envelope& mbrB) const;
193
194 /*!
195 \brief Add a branch to a node.
196 */
197 bool addBranch(BranchType* branch,
198 NodeType* node,
199 NodeType** newNode) const;
200
201 /*!
202 \brief Pick a branch.
203 */
204 int pickBranch(const te::gm::Envelope& mbr, NodeType* node) const;
205
206 /*!
207 \brief Split a node.
208 */
209 void splitNode(NodeType* node, BranchType* branch, NodeType** newNode) const;
210
212
214
216
217 void classify(int i, int group, PartitionVarsType& p) const;
218
220
222
223 /*!
224 \brief Erases a node from the tree and all nodes below it.
225
226 \param node The node to be removed.
227
228 \pos The node pointer will be invalidated.
229 */
230 void erase(NodeType* node);
231
232
233 private:
234
235
236 /*!
237 \brief No copy constructor allowed.
238
239 \param rhs The other rtree.
240 */
241 Index(const Index& rhs);
242
243 /*!
244 \brief No assignment operator allowed.
245
246 \param rhs The other rtree.
247
248 \return A reference for this instance.
249 */
250 Index& operator=(const Index& rhs);
251
252
253 private:
254
255 NodeType* m_root; //!< Pointer to the root node.
256 te::gm::Envelope m_mbr; //!< Bounding box of the tree.
257 mutable std::size_t m_size; //!< The size of R-Tree (number of nodes).
258 };
259
260 template<class DATATYPE, int MAXNODES, int MINNODES> inline
262 : m_root(0), m_size(0)
263 {
264 ++m_size;
265 m_root = new NodeType();
266 m_root->m_level = 0;
267 }
268
269 template<class DATATYPE, int MAXNODES, int MINNODES> inline
271 : m_root(0), m_mbr(mbr), m_size(0)
272 {
273 assert(m_mbr.isValid());
274 ++m_size;
275 m_root = new NodeType();
276 m_root->m_level = 0;
277 }
278
279 template<class DATATYPE, int MAXNODES, int MINNODES> inline
281 {
282 clear();
283 delete m_root;
284 }
285
286 template<class DATATYPE, int MAXNODES, int MINNODES> inline
288 {
289 return m_size;
290 }
291
292 template<class DATATYPE, int MAXNODES, int MINNODES> inline
294 {
295 return (m_root->m_count == 0);
296 }
297
298 template<class DATATYPE, int MAXNODES, int MINNODES> inline
300 {
301 if(m_root)
302 {
303 erase(m_root);
304 m_root = 0;
305
306 m_size = 1;
307 m_root = new NodeType();
308 m_root->m_level = 0;
309 }
310 }
311
312 template<class DATATYPE, int MAXNODES, int MINNODES> inline
314 {
315 insert(mbr, data, &m_root, 0);
316 m_mbr.Union(mbr);
317 }
318
319 template<class DATATYPE, int MAXNODES, int MINNODES> inline
321 {
322 return remove(mbr, data, &m_root);
323 }
324
325 template<class DATATYPE, int MAXNODES, int MINNODES> inline
326 int Index<DATATYPE, MAXNODES, MINNODES>::search(const te::gm::Envelope& mbr, std::vector<DATATYPE>& report) const
327 {
328 int foundObjs = 0;
329
330 if(m_root)
331 search(mbr, m_root, report, foundObjs);
332
333 return foundObjs;
334 }
335
336 template<class DATATYPE, int MAXNODES, int MINNODES> inline
338 {
339 m_mbr = mbr;
340 }
341
342 template<class DATATYPE, int MAXNODES, int MINNODES> inline
344 {
345 return m_mbr;
346 }
347
348 template<class DATATYPE, int MAXNODES, int MINNODES> inline
349 bool Index<DATATYPE, MAXNODES, MINNODES>::insert(const te::gm::Envelope& mbr, const DATATYPE& data, NodeType** root, int level)
350 {
351// this is the algorithm insert
352 NodeType* newNode;
353
354 if(chooseLeaf(mbr, data, *root, &newNode, level)) // I1
355 {
356// I4
357// if root was split
358// grow a new root, make tree taller
359 ++m_size;
360 NodeType* newRoot = new NodeType();
361
362 newRoot->m_level = (*root)->m_level + 1;
363
364// first half node
365 BranchType branch;
366 branch.m_mbr = nodeCover(*root);
367 branch.m_child = *root;
368 addBranch(&branch, newRoot, 0);
369
370// second half node
371 branch.m_mbr = nodeCover(newNode);
372 branch.m_child = newNode;
373 addBranch(&branch, newRoot, 0);
374
375 *root = newRoot;
376
377 return true;
378 }
379
380 return false;
381 }
382
383 template<class DATATYPE, int MAXNODES, int MINNODES> inline
384 bool Index<DATATYPE, MAXNODES, MINNODES>::remove(const te::gm::Envelope& mbr, const DATATYPE& data, NodeType** root)
385 {
386 NodeType *t;
387 std::vector<NodeType*> reInsertList;
388
389 if(remove2(mbr, data, *root, reInsertList))
390 {
391// if we are here, so we have found and deleted a data item
392
393// reinsert any branches from eliminated nodes
394 while(!reInsertList.empty())
395 {
396 t = reInsertList[0];
397
398 for(int i = 0; i < t->m_count; ++i)
399 insert(t->m_branch[i].m_mbr, t->m_branch[i].m_data, root, t->m_level);
400
401// erase node from list
402 reInsertList.erase(reInsertList.begin());
403
404// remove node card from memory
405 delete t;
406 --m_size;
407 }
408
409// check for redundant root (not leaf, 1 child) and eliminate
410 if(((*root)->m_count == 1) && ((*root)->isInternalNode()))
411 {
412 t = (*root)->m_branch[0].m_child;
413
414 delete (*root);
415 --m_size;
416
417 *root = t;
418 }
419
420 return true;
421 }
422
423 return false;
424 }
425
426 template<class DATATYPE, int MAXNODES, int MINNODES> inline
427 bool Index<DATATYPE, MAXNODES, MINNODES>::remove2(const te::gm::Envelope& mbr, const DATATYPE& data, NodeType* n, std::vector<NodeType*>& ee)
428 {
429 int i;
430
431 if(n->isInternalNode()) /* not a leaf node */
432 {
433 for(i = 0; i < n->m_count; ++i)
434 {
435 if(mbr.intersects(n->m_branch[i].m_mbr))
436 {
437 if(remove2(mbr, data, n->m_branch[i].m_child, ee))
438 {
439 if(n->m_branch[i].m_child->m_count >= MINNODES)
440 n->m_branch[i].m_mbr = nodeCover(n->m_branch[i].m_child);
441 else
442 {
443 /* not enough entries in child, eliminate child node */
444 ee.push_back(n->m_branch[i].m_child); //reInsert(n->m_branch[i].m_child, ee);
445 disconBranch(n, i);
446 }
447
448 return true; // found item
449 }
450 }
451 }
452
453 return false; // din't find item
454 }
455 else /* a leaf node */
456 {
457 for(i = 0; i < n->m_count; ++i)
458 {
459 if(n->m_branch[i].m_data == data)
460 {
461 disconBranch(n, i);
462 return true; // found item
463 }
464 }
465
466 return false; // didn't find item
467 }
468 }
469
470 template<class DATATYPE, int MAXNODES, int MINNODES>
472 {
473// remove element copying the last element in array
474 n->m_branch[i] = n->m_branch[n->m_count - 1];
475
476 --(n->m_count);
477 }
478
479 template<class DATATYPE, int MAXNODES, int MINNODES>
480 bool Index<DATATYPE, MAXNODES, MINNODES>::chooseLeaf(const te::gm::Envelope& mbr, const DATATYPE& data, NodeType* node, NodeType** newNode, int level)
481 {
482 if(node->m_level > level)
483 {
484// Still above level for insertion, go down tree recursively
485 int i = pickBranch(mbr, node); // CL3
486
487 NodeType* n2;
488 if(!chooseLeaf(mbr, data, node->m_branch[i].m_child, &n2, level))
489 {
490// child was not split
491 node->m_branch[i].m_mbr = combineRect(mbr, node->m_branch[i].m_mbr);
492
493 return false;
494 }
495 else
496 {
497// child was split
498 node->m_branch[i].m_mbr = nodeCover(node->m_branch[i].m_child);
499
500 BranchType b;
501 b.m_child = n2;
502 b.m_mbr = nodeCover(n2);
503
504 return addBranch(&b, node, newNode);
505 }
506 }
507 else if (node->m_level == level)
508 {
509// have reached level for insertion. Add mbr, split if necessary
510 BranchType b;
511 b.m_mbr = mbr;
512 //b.m_child = (NodeType*) data;
513 b.m_data = data;
514
515// child field of leaves contains tid of data record
516 return addBranch(&b, node, newNode);
517 }
518 else
519 {
520// Not supposed to happen
521 //throw;
522 return false;
523 }
524 }
525
526 template<class DATATYPE, int MAXNODES, int MINNODES>
527 void Index<DATATYPE, MAXNODES, MINNODES>::search(const te::gm::Envelope& mbr, NodeType* node, std::vector<DATATYPE>& report, int& foundObjs) const
528 {
529 int i;
530// S1
531 if(node->isInternalNode()) // This is an internal node in the tree
532 {
533 for(i = 0; i < node->m_count; ++i)
534 {
535 if(mbr.intersects(node->m_branch[i].m_mbr))
536 search(mbr, node->m_branch[i].m_child, report, foundObjs);
537 }
538 }
539// S2
540 else // This is a leaf node
541 {
542 for(i = 0; i < node->m_count; ++i)
543 {
544 if(mbr.intersects(node->m_branch[i].m_mbr))
545 {
546 DATATYPE& id = node->m_branch[i].m_data;
547 report.push_back(id);
548
549 ++foundObjs;
550 }
551 }
552 }
553
554 return;
555 }
556
557 template<class DATATYPE, int MAXNODES, int MINNODES>
559 {
560 bool flag = true;
561
563
564 for(int i = 0; i < n->m_count; ++i)
565 {
566 if(flag)
567 {
568 r = n->m_branch[i].m_mbr;
569 flag = false;
570 }
571 else
572 r = combineRect(r, n->m_branch[i].m_mbr);
573 }
574
575 return r;
576 }
577
578 template<class DATATYPE, int MAXNODES, int MINNODES> inline
580 {
581 te::gm::Envelope newRect(mbrA);
582 newRect.Union(mbrB);
583 return newRect;
584 }
585
586 template<class DATATYPE, int MAXNODES, int MINNODES> inline
588 {
589 if(node->m_count < MAXNODES) /* split won't be necessary */
590 {
591 node->m_branch[node->m_count] = *branch;
592 ++(node->m_count);
593 return false;
594 }
595 else
596 {
597 splitNode(node, branch, newNode);
598 return true;
599 }
600 }
601
602 template<class DATATYPE, int MAXNODES, int MINNODES> inline
604 {
605// CL3
606 bool flag = true;
607 double bestIncr = -1.0;
608 double bestArea = 0.;
609 int best = 0;
610
611 for(int i = 0; i < node->m_count; ++i)
612 {
613 te::gm::Envelope rr = node->m_branch[i].m_mbr;
614 double area = rr.getArea();
615
616 rr = combineRect(mbr, rr);
617
618 double increase = rr.getArea() - area;
619
620 if((increase < bestIncr) || flag)
621 {
622 best = i;
623 bestArea = area;
624 bestIncr = increase;
625 flag = false;
626 }
627 else if((increase == bestIncr) && (area < bestArea))
628 {
629 best = i;
630 bestArea = area;
631 bestIncr = increase;
632 }
633 }
634
635 return best;
636 }
637
638 template<class DATATYPE, int MAXNODES, int MINNODES> inline
640 {
641 PartitionVarsType partitions;
642
643// load all the branches into a buffer, initialize old node
644 int level = node->m_level;
645
646 getBranches(node, branch, partitions);
647
648// find partition
649 methodZero(partitions);
650
651// put branches from buffer into 2 nodes according to chosen partition
652 ++m_size;
653
654 *newNode = new NodeType();
655 (*newNode)->m_level = node->m_level = level;
656
657 loadNodes(node, *newNode, partitions);
658 }
659
660 template<class DATATYPE, int MAXNODES, int MINNODES> inline
662 {
663// load the branch buffer
664 for(int i = 0; i < MAXNODES; ++i)
665 {
666 p.m_branchBuf[i] = n->m_branch[i];
667 }
668
669 p.m_branchBuf[MAXNODES] = *b;
670
671// calculate mbr containing all in the set
672 p.m_coverSplit = p.m_branchBuf[0].m_mbr;
673
674 for(int i = 1; i <= MAXNODES; ++i)
675 p.m_coverSplit = combineRect(p.m_coverSplit, p.m_branchBuf[i].m_mbr);
676
677 n->init();
678 }
679
680 template<class DATATYPE, int MAXNODES, int MINNODES> inline
682 {
683 p.init();
684 pickSeeds(p);
685 pigeonhole(p);
686 }
687
688 template<class DATATYPE, int MAXNODES, int MINNODES> inline
690 {
691 double w;
692 double separation;
693 double bestSep;
694 double width[2];
695 int leastUpper[2];
696 int greatestLower[2];
697 int seed0;
698 int seed1;
699 int i;
700// LPS1
701// find the rectangles farthest out in each dimbrion along dimens "x"
702 greatestLower[0] = leastUpper[0] = 0;
703
704 for(i = 1; i <= MAXNODES; ++i)
705 {
706 te::gm::Envelope& r = p.m_branchBuf[i].m_mbr;
707
708 if(r.m_llx > p.m_branchBuf[greatestLower[0]].m_mbr.m_llx)
709 greatestLower[0] = i;
710
711 if(r.m_urx < p.m_branchBuf[leastUpper[0]].m_mbr.m_urx)
712 leastUpper[0] = i;
713 }
714
715// LPS2
716// LPS3
717// find the width of the whole collection along this dimension
718 width[0] = p.m_coverSplit.m_urx - p.m_coverSplit.m_llx;
719
720// find the rectangles farthest out in each dimbrion along dimens "y"
721 greatestLower[1] = leastUpper[1] = 0;
722
723 for(i = 1; i <= MAXNODES; ++i)
724 {
725 te::gm::Envelope& r = p.m_branchBuf[i].m_mbr;
726
727 if(r.m_lly > p.m_branchBuf[greatestLower[1]].m_mbr.m_lly)
728 greatestLower[1] = i;
729
730 if(r.m_ury < p.m_branchBuf[leastUpper[1]].m_mbr.m_ury)
731 leastUpper[1] = i;
732 }
733
734// LPS2
735// LPS3
736// find the width of the whole collection along this dimension
737 width[1] = p.m_coverSplit.m_ury - p.m_coverSplit.m_lly;
738
739
740// pick the best separation dimension and the two seed mbrs
741
742// divisor for normalizing by width
743
744// x
745 if(width[0] == 0.0)
746 w = 1.0;
747 else
748 w = width[0];
749
750 te::gm::Envelope rlow = p.m_branchBuf[leastUpper[0]].m_mbr;
751 te::gm::Envelope rhigh = p.m_branchBuf[greatestLower[0]].m_mbr;
752
753 seed0 = leastUpper[0];
754 seed1 = greatestLower[0];
755
756 bestSep = (rhigh.m_llx - rlow.m_urx) / w;
757
758// y
759 if(width[1] == 0.0)
760 w = 1.0;
761 else
762 w = width[1];
763
764 rlow = p.m_branchBuf[leastUpper[1]].m_mbr;
765 rhigh = p.m_branchBuf[greatestLower[1]].m_mbr;
766
767 separation = (rhigh.m_lly - rlow.m_ury) / w;
768
769// LPS3
770 if(separation > bestSep)
771 {
772 seed0 = leastUpper[1];
773 seed1 = greatestLower[1];
774
775 bestSep = separation;
776 }
777
778 if(seed0 != seed1)
779 {
780 classify(seed0, 0, p);
781 classify(seed1, 1, p);
782 }
783 }
784
785 template<class DATATYPE, int MAXNODES, int MINNODES> inline
787 {
788 p.m_partition[i] = group;
789 p.m_taken[i] = 1;
790
791 if(p.m_count[group] == 0)
792 p.m_cover[group] = p.m_branchBuf[i].m_mbr;
793 else
794 p.m_cover[group] = combineRect(p.m_branchBuf[i].m_mbr, p.m_cover[group]);
795
796 p.m_area[group] = p.m_cover[group].getArea();
797
798 ++(p.m_count[group]);
799 }
800
801 template<class DATATYPE, int MAXNODES, int MINNODES> inline
803 {
804 te::gm::Envelope newCover[2];
805
806 double newArea[2];
807 double increase[2];
808
809 for(int i = 0; i <= MAXNODES; ++i)
810 {
811 if(p.m_taken[i] == 0)
812 {
813// if one group too full, put mbr in the other regardless
814 if(p.m_count[0] >= (MAXNODES + 1 - MINNODES))
815 {
816 classify(i, 1, p);
817 continue;
818 }
819 else if(p.m_count[1] >= (MAXNODES + 1 - MINNODES))
820 {
821 classify(i, 0, p);
822 continue;
823 }
824
825// find the areas of the two groups' old and new covers
826 for(int group = 0; group < 2; ++group)
827 {
828 if(p.m_count[group] > 0)
829 {
830 newCover[group] = combineRect(p.m_branchBuf[i].m_mbr, p.m_cover[group]);
831 }
832 else
833 {
834 newCover[group] = p.m_branchBuf[i].m_mbr;
835 }
836
837 newArea[group] = newCover[group].getArea();
838 increase[group] = newArea[group] - p.m_area[group];
839 }
840
841// put mbr in group whose cover will need to expand less
842 if(increase[0] < increase[1])
843 classify(i, 0, p);
844 else if(increase[1] < increase[0])
845 classify(i, 1, p);
846// put mbr in group that will have a smaller area cover
847 else if(p.m_area[0] < p.m_area[1])
848 classify(i, 0, p);
849 else if(p.m_area[1] < p.m_area[0])
850 classify(i, 1, p);
851// put mbr in group with fewer elements
852 else if(p.m_count[0] < p.m_count[1])
853 classify(i, 0, p);
854 else
855 classify(i, 1, p);
856 }
857 }
858 }
859
860 template<class DATATYPE, int MAXNODES, int MINNODES> inline
862 {
863 for(int i = 0; i <= MAXNODES; ++i)
864 {
865 if(p.m_partition[i] == 0)
866 addBranch(&(p.m_branchBuf[i]), n, 0);
867 else if(p.m_partition[i] == 1)
868 addBranch(&(p.m_branchBuf[i]), q, 0);
869 //else
870 // throw; // ERROR
871 }
872 }
873
874 template<class DATATYPE, int MAXNODES, int MINNODES> inline
876 {
877 if(node->isLeaf())
878 {
879 delete node;
880 return;
881 }
882
883 for(int i = 0u; i < node->m_count; ++i)
884 erase(node->m_branch[i].m_child);
885
886 delete node;
887 return;
888 }
889
890 } // end namespace rtree
891 } // end namespace sam
892} // end namespace te
893
894
895#endif // __TERRALIB_SAM_RTREE_INTERNAL_INDEX_H
896
mydialect insert("=", new te::da::BinaryOpEncoder("="))
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:52
bool isValid() const
It tells if the rectangle is valid or not.
bool intersects(const Envelope &rhs) const
It returns true if the envelopes "spatially intersects".
Definition: Envelope.h:492
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
double getArea() const
It returns the area of this envelope as measured in the spatial reference system of it.
Definition: Envelope.h:452
void Union(const Envelope &rhs)
It updates the envelop with coordinates of another envelope.
Definition: Envelope.h:554
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
A class that represents an R-tree.
Definition: Index.h:57
void pigeonhole(PartitionVarsType &p) const
Definition: Index.h:802
te::gm::Envelope combineRect(const te::gm::Envelope &mbrA, const te::gm::Envelope &mbrB) const
Combine two rectangles into larger one containing both.
Definition: Index.h:579
void getBranches(NodeType *n, BranchType *b, PartitionVarsType &p) const
Definition: Index.h:661
bool insert(const te::gm::Envelope &mbr, const DATATYPE &data, NodeType **root, int level)
It inserts a data rectangle into an index structure.
Definition: Index.h:349
bool isEmpty(void) const
It returns true if the tree is empty.
Definition: Index.h:293
bool remove(const te::gm::Envelope &mbr, const DATATYPE &data)
It removes an item from the tree.
Definition: Index.h:320
void disconBranch(NodeType *n, int i)
It disconnects a dependent node.
Definition: Index.h:471
~Index()
Destructor.
Definition: Index.h:280
void clear(void)
Definition: Index.h:299
void search(const te::gm::Envelope &mbr, NodeType *node, std::vector< DATATYPE > &report, int &foundObjs) const
Recursive range query.
Definition: Index.h:527
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
Definition: Index.h:326
bool remove2(const te::gm::Envelope &mbr, const DATATYPE &data, NodeType *n, std::vector< NodeType * > &ee)
It deletes a rectangle from non-root part of an index structure.
Definition: Index.h:427
std::size_t m_size
The size of R-Tree (number of nodes).
Definition: Index.h:257
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
Definition: Index.h:313
void methodZero(PartitionVarsType &p) const
Definition: Index.h:681
Index & operator=(const Index &rhs)
No assignment operator allowed.
Index(const te::gm::Envelope &mbr)
Constructor.
Definition: Index.h:270
void setMBR(const te::gm::Envelope &mbr)
It sets the bounding box of all elements in the tree.
Definition: Index.h:337
void loadNodes(NodeType *n, NodeType *q, PartitionVarsType &p) const
Definition: Index.h:861
bool chooseLeaf(const te::gm::Envelope &mbr, const DATATYPE &data, NodeType *node, NodeType **newNode, int level)
It inserts a new data rectangle into the index structure.
Definition: Index.h:480
Index(const Index &rhs)
No copy constructor allowed.
NodeType * m_root
Pointer to the root node.
Definition: Index.h:255
void splitNode(NodeType *node, BranchType *branch, NodeType **newNode) const
Split a node.
Definition: Index.h:639
std::size_t size(void) const
It returns the number of elements in the tree.
Definition: Index.h:287
NodeType::BranchType BranchType
Definition: Index.h:61
te::sam::rtree::PartitionVars< BranchType, MAXNODES > PartitionVarsType
Definition: Index.h:62
void classify(int i, int group, PartitionVarsType &p) const
Definition: Index.h:786
Node< DATATYPE, MAXNODES, MINNODES > NodeType
Definition: Index.h:60
te::gm::Envelope nodeCover(NodeType *n) const
Find the smallest rectangle that includes all rectangles in branches of a node.
Definition: Index.h:558
bool remove(const te::gm::Envelope &mbr, const DATATYPE &data, NodeType **root)
It deletes a data rectangle from an index structure.
Definition: Index.h:384
int pickBranch(const te::gm::Envelope &mbr, NodeType *node) const
Pick a branch.
Definition: Index.h:603
void erase(NodeType *node)
Erases a node from the tree and all nodes below it.
Definition: Index.h:875
void pickSeeds(PartitionVarsType &p) const
Definition: Index.h:689
Index()
Constructor.
Definition: Index.h:261
te::gm::Envelope m_mbr
Bounding box of the tree.
Definition: Index.h:256
const te::gm::Envelope & getMBR(void) const
It returns the bounding box of all elements in the tree.
Definition: Index.h:343
bool addBranch(BranchType *branch, NodeType *node, NodeType **newNode) const
Add a branch to a node.
Definition: Index.h:587
A class that represents an R-tree node.
Definition: Node.h:46
BranchType m_branch[MAXNODES]
Branches.
Definition: Node.h:112
bool isInternalNode() const
It returns true if this is a internal node.
Definition: Node.h:62
void init()
This method is used during split when a node retained and used again (beeing re-filled).
Definition: Node.h:78
int m_count
The number of elements in the node (count).
Definition: Node.h:110
bool isLeaf() const
It returns true if this is a leaf node.
Definition: Node.h:72
int m_level
Leaf is zero, others positive.
Definition: Node.h:111
TerraLib.
A class that represents an R-tree node.
NODE * m_child
A pointer to the child node.
Definition: Branch.h:51
DATATYPE m_data
An object-identifier (oid).
Definition: Branch.h:52
te::gm::Envelope m_mbr
Bounding box containing all the objects under the branch or an object bounding box.
Definition: Branch.h:47
Auxiliary structure when searching for a split partition.
Definition: PartitionVars.h:44
te::gm::Envelope m_cover[2]
Auxiliary box of each new page.
Definition: PartitionVars.h:48
int m_count[2]
Number of entries in each new page.
Definition: PartitionVars.h:47
te::gm::Envelope m_coverSplit
Auxiliary box covering branchBuf.
Definition: PartitionVars.h:51
int m_taken[MAXNODES+1]
Flag to indicate that entry is ok.
Definition: PartitionVars.h:46
void init()
Initializes partition vars.
Definition: PartitionVars.h:54
double m_area[2]
Auxiliary area of each new page.
Definition: PartitionVars.h:49
int m_partition[MAXNODES+1]
Auxiliary partition vector.
Definition: PartitionVars.h:45
BRANCH m_branchBuf[MAXNODES+1]
Auxiliary branch buffer.
Definition: PartitionVars.h:50