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 terralib/sam/kdtree/Index.h
22
23 \brief A class that represents a two dimensional K-d Tree (2-d Tree).
24*/
25
26#ifndef __TERRALIB_SAM_KDTREE_INTERNAL_INDEX_H
27#define __TERRALIB_SAM_KDTREE_INTERNAL_INDEX_H
28
29// TerraLib
30#include "../../geometry/Envelope.h"
31#include "Node.h"
32
33// STL
34#include <cmath>
35#include <limits>
36#include <vector>
37#include <utility>
38
39namespace te
40{
41 namespace sam
42 {
43 namespace kdtree
44 {
45 /*!
46 \class Index
47
48 \brief A class that represents a two dimensional K-d Tree (2-d Tree).
49
50 \note This type of tree stores the data into nodes (not only in the leafs node).
51
52 \note This tree may be built by two ways:
53 1) Inserting each element in the tree. In this case the tree can becomes unbalanced, but in practical
54 cases this is not the expected, and is the best way to construct the tree (faster way).
55 2) Passing a container with pairs (key/data-item) and using the method buildOptimized after
56 calling kdsort. The tree built this way is almost balanced but will be construct in time O(N log N).
57 Warning: In this case items with the same key will be stores in different nodes!
58
59 \note This type of tree may be of special interest of EXTENT SEARCH QUERIES.
60
61 \note If the node type is kd_node_data_single_tag than NodeData and NodeDataItem are the same types.
62 And if one entry with the same key already exist, so they will be overwrite.
63
64 \note If the node type is kd_node_data_set_tag than NodeData mus have a method called push_back(NodeDataItem)
65 that permits to store elements with the same key in the node.
66 */
67 template<class KdTreeNode> class Index
68 {
69 public:
70
71 //! Export key type.
72 typedef typename KdTreeNode::kdKey kdKey;
73
74 //! Export data type.
75 typedef typename KdTreeNode::kdData kdData;
76
77 //! Export data item type.
78 typedef typename KdTreeNode::kdDataItem kdDataItem;
79
80 //! Export data type.
81 typedef typename KdTreeNode::kdDataTag kdDataTag;
82
83 /*! \brief Constructor. */
85 : m_root(0),
86 m_mbr(mbr),
87 m_size(0)
88 {
89 }
90
91 /*! \brief Destructor. */
93 {
94 clear();
95 }
96
97 /*! \brief It clears all tree nodes. */
98 void clear()
99 {
100 if(m_root)
101 {
102 erase(m_root);
103 m_root = 0;
104 m_size = 0;
105 }
106 }
107
108 /*! \brief It returns the number of tree nodes. */
109 const std::size_t& size() const
110 {
111 return m_size;
112 }
113
114 /*! \brief It returns true if the tree is empty and false otherwise. */
115 bool isEmpty() const
116 {
117 return m_root == 0;
118 }
119
120 /*! \brief It sets the minimum bounding box of all elements in the tree. */
121 void setMBR(const te::gm::Envelope& mbr)
122 {
123 m_mbr = mbr;
124 }
125
126 /*! \brief It gets the minimum bounding box of all elements in the tree. */
128 {
129 return m_mbr;
130 }
131
132 /*! \brief It inserts the data with a given key in tree. */
133 inline void insert(const kdKey& key, const kdData& item);
134
135 /*! \brief It inserts the data in the tree and and keeps it balanced: the kdsort algorithm must be called before. */
136 void buildOptimized(std::vector<std::pair<kdKey, kdData> >& dataSet)
137 {
138 const std::size_t last = dataSet.size() - 1;
139 m_root = buildOptimized(dataSet, 0, last);
140 }
141
142 /*! \brief Range search query. */
143 void search(const te::gm::Envelope& e, std::vector<KdTreeNode*>& report) const
144 {
145 if(m_root)
146 search(e, m_root, 'x', report);
147 }
148
149 private:
150
151 /*! \brief It Erases a node from the tree and all nodes below it. */
152 void erase(KdTreeNode* node)
153 {
154 if(node->hasLeft())
155 erase(node->getLeft());
156
157 if(node->hasRight())
158 erase(node->getRight());
159
160 delete node;
161 }
162
163 /*! \brief It inserts data for single nodes, i.e. nodes that stores only one element. */
164 void insertData(KdTreeNode*& node, const kdData& data, const kd_node_m_datasingle_tag&)
165 {
166 node->setData(data);
167 }
168
169 // Not build!
170 /*! \brief It inserts data for set nodes, i.e., nodes that may stores many element. */
171 void insertData(KdTreeNode*& node, const kdData& data, const kd_node_m_dataset_tag&)
172 {
173 node->getData().push_back(data);
174 }
175
176 /*! \brief Recursive range query. */
177 inline void search(const te::gm::Envelope& e, KdTreeNode* node, const char& level, std::vector<KdTreeNode*>& report) const;
178
179 /*! \brief It builds the tree recursively. */
180 KdTreeNode* buildOptimized(std::vector<std::pair<kdKey, kdData> >& dataSet, const std::size_t& first, const std::size_t& last)
181 {
182 const std::size_t kth = (last - first + 1) / 2;
183
184 KdTreeNode* newNode = new KdTreeNode(dataSet[first + kth].first);
185
186 newNode->setData(dataSet[first + kth].second);
187
188 ++m_size;
189
190 if(first + kth > first)
191 newNode->setLeft(buildOptimized(dataSet, first, first + kth - 1));
192
193 if(first + kth < last)
194 newNode->setRight(buildOptimized(dataSet, first + kth + 1, last));
195
196 return newNode;
197 }
198
199 /*!
200 \brief No copy constructor allowed.
201
202 \param rhs The other index.
203 */
204 Index(const Index& rhs);
205
206 /*!
207 \brief No assignment operator allowed.
208
209 \param rhs The other index.
210
211 \return A reference for this.
212 */
213 Index& operator=(const Index& rhs);
214
215 private:
216
217 KdTreeNode* m_root; //!< Pointer to the root node.
218 te::gm::Envelope m_mbr; //!< Minimum bounding box of all nodes.
219 std::size_t m_size; //!< The size of the K-d Tree (number of nodes).
220 };
221
222 template<class KdTreeNode>
223 void Index<KdTreeNode>::insert(const kdKey& key, const kdData& item)
224 {
225 if(m_root == 0)
226 {
227 m_root = new KdTreeNode(key);
228 insertData(m_root, item, kdDataTag());
229 }
230 else
231 {
232 char level = 'x';
233
234 bool left = false;
235
236 KdTreeNode* x = m_root;
237 KdTreeNode* y = 0;
238
239 while(x != 0)
240 {
241 y = x;
242
243 if(level == 'x')
244 {
245 if(key.getX() > x->getKey().getX()) // if the key is greater than, inserts in the right subtree
246 {
247 x = x->getRight();
248 left = false;
249 }
250 else if(key.getX() < x->getKey().getX()) // if the key is smaller than, inserts in the left subtree
251 {
252 x = x->getLeft();
253 left = true;
254 }
255 else if(key.getY() == x->getKey().getY()) // if the key already exist, in the case of single node the data will be overwrite and in the case of set node they will push_back the item
256 {
257 insertData(x, item, kdDataTag());
258 return;
259 }
260 else // found the same axis partition, so go left
261 {
262 x = x->getLeft();
263 left = true;
264 }
265
266 level = 'y';
267 }
268 else
269 {
270 if(key.getY() > x->getKey().getY())
271 {
272 x = x->getRight();
273 left = false;
274 }
275 else if(key.getY() < x->getKey().getY())
276 {
277 x = x->getLeft();
278 left = true;
279 }
280 else if(key.getX() == x->getKey().getX())
281 {
282 insertData(x, item, kdDataTag());
283 return;
284 }
285 else
286 {
287 x = x->getLeft();
288 left = true;
289 }
290
291 level = 'x';
292 }
293 }
294
295 KdTreeNode* newNode = new KdTreeNode(key);
296
297 insertData(newNode, item, kdDataTag());
298
299 if(left)
300 y->setLeft(newNode);
301 else
302 y->setRight(newNode);
303 }
304
305 ++m_size;
306 }
307
308 template<class KdTreeNode>
309 void Index<KdTreeNode>::search(const te::gm::Envelope& e, KdTreeNode* node, const char& level, std::vector<KdTreeNode*>& report) const
310 {
311 if((node->getKey().getX() >= e.m_llx) && (node->getKey().getX() <= e.m_urx) &&
312 (node->getKey().getY() >= e.m_lly) && (node->getKey().getY() <= e.m_ury))
313 {
314 report.push_back(node);
315 }
316
317 if(level == 'x')
318 {
319 if(node->hasLeft())
320 if(node->getKey().getX() >= e.m_llx)
321 search(e, node->getLeft(), 'y', report);
322
323 if(node->hasRight())
324 if(node->getKey().getX() <= e.m_urx)
325 search(e, node->getRight(), 'y', report);
326 }
327 else
328 {
329 if(node->hasLeft())
330 if(node->getKey().getY() >= e.m_lly)
331 search(e, node->getLeft(), 'x', report);
332
333 if(node->hasRight())
334 if(node->getKey().getY() <= e.m_ury)
335 search(e, node->getRight(), 'x', report);
336 }
337 }
338
339 template<typename T>
340 bool Intersects(const T& data, const te::gm::Envelope& e)
341 {
342 // point to the right of envelope
343 if (data.getX() > e.m_urx)
344 return false;
345
346 // point to the left of envelope
347 if (e.m_llx > data.getX())
348 return false;
349
350 // point is above envelope
351 if (data.getY() > e.m_ury)
352 return false;
353
354 // point is below envelope
355 if (e.m_lly > data.getY())
356 return false;
357
358 return true;
359 }
360
361 /*!
362 \class AdaptativeIndex
363
364 \brief A class that represents a two dimensional K-d Tree (2-d Tree) that store data-elements into the leafs.
365
366 \note This type of tree stores the data only in the leaf nodes.
367
368 \note The process of construction expect that the tree is almost balanced.
369
370 \note This type of tree may be of special interest of NEAREST NEIGHBOR SEARCH QUERIES.
371
372 \note After a extent search it will be necessary to do a refinement.
373 */
374 template<class KdTreeNode> class AdaptativeIndex
375 {
376 public:
377
378 //! Export key type.
379 typedef typename KdTreeNode::kdKey kdKey;
380
381 //! Export data type.
382 typedef typename KdTreeNode::kdData kdData;
383
384 //! Export data item type.
385 typedef typename KdTreeNode::kdDataItem kdDataItem;
386
387 //! Export node type.
388 typedef KdTreeNode kdNode;
389
390 /*! \brief Constructor. */
391 AdaptativeIndex(const te::gm::Envelope& mbr, const std::size_t& bucketSize = 12)
392 : m_root(0),
393 m_mbr(mbr),
394 m_size(0),
395 m_bucketSize(bucketSize)
396 {
397 }
398
399 /*! \brief Destructor. */
401 {
402 clear();
403 }
404
405 /*! \brief It clears all tree nodes. */
406 void clear()
407 {
408 if(m_root)
409 {
410 erase(m_root);
411 m_root = 0;
412 m_size = 0;
413 }
414 }
415
416 /*! \brief It returns the number of tree nodes. */
417 const std::size_t& size() const
418 {
419 return m_size;
420 }
421
422 /*! \brief It returns true if the tree is empty and false otherwise. */
423 bool isEmpty() const
424 {
425 return m_root == 0;
426 }
427
428 /*! \brief It sets the minimum bounding box of all elements in the tree. */
429 void setMBR(const te::gm::Envelope& mbr)
430 {
431 m_mbr = mbr;
432 }
433
434 /*! \brief It gets the minimum bounding box of all elements in the tree. */
436 {
437 return m_mbr;
438 }
439
440 /*! \brief It sets bucket size for leaf nodes. */
441 void setBucketSize(const std::size_t& size)
442 {
444 }
445
446 /*! \brief It gets bucket size for leaf nodes. */
447 const std::size_t& getBucketSize() const
448 {
449 return m_bucketSize;
450 }
451
452 /*! \brief It inserts the data set into the tree. */
453 void build(std::vector<std::pair<kdKey, kdDataItem> >& dataSet)
454 {
455 m_root = build(dataSet, 0.0, m_mbr);
456 }
457
458 /*!
459 \brief It searches the nearest data in nodes: you must pass an array of kdDataItem of size "k"
460 with coordinates values (X() and Y()) adjusted to td::numeric_limits<double>::max() (this dummy values will be replaced at processing time),
461 and if not all neighbors are found so sqrDists will contains td::numeric_limits<double>::max() in array index.
462 */
463 void nearestNeighborSearch(const kdKey& key, std::vector<kdDataItem>& report, std::vector<double>& sqrDists, const std::size_t& k) const
464 {
465 if(m_root)
466 {
467 sqrDists.clear();
468
469 for(std::size_t i = 0; i < k; ++i)
470 sqrDists.push_back(std::numeric_limits<double>::max());
471
472 te::gm::Envelope e(-std::numeric_limits<double>::max(), -std::numeric_limits<double>::max(),
473 +std::numeric_limits<double>::max(), +std::numeric_limits<double>::max());
474
475 nearestNeighborSearch(m_root, key, report, sqrDists, e);
476 }
477 }
478
479 /*! \brief Range search query. */
480 void search(const te::gm::Envelope& e, std::vector<KdTreeNode*>& report) const
481 {
482 if(m_root)
483 search(e, m_root, report);
484 }
485
486 /*! \brief Range search query: the refinement is already done. */
487 inline void search(const te::gm::Envelope& e, std::vector<kdDataItem>& report) const;
488
489 private:
490
491 /*! \brief It Erases a node from the tree and all nodes below it. */
492 void erase(KdTreeNode* node)
493 {
494 if(node->hasLeft())
495 erase(node->getLeft());
496
497 if(node->hasRight())
498 erase(node->getRight());
499
500 delete node;
501 }
502
503 /*! \brief It builds the tree recursivily. */
504 inline KdTreeNode* build(std::vector<std::pair<kdKey, kdDataItem> >& dataSet, double averageValue, const te::gm::Envelope& mbr);
505
506 /*! \brief Recursive nearest neighbor search. */
507 inline void nearestNeighborSearch(KdTreeNode* node, const kdKey& key, std::vector<kdDataItem>& report, std::vector<double>& sqrDists, te::gm::Envelope& e) const;
508
509 /*! \brief Recursive range query. */
510 inline void search(const te::gm::Envelope& e, KdTreeNode* node, std::vector<KdTreeNode*>& report) const;
511
512 /*! \brief It updates the neighbor list. */
513 inline void update(KdTreeNode* node, const kdKey& key, std::vector<kdDataItem>& report, std::vector<double>& sqrDists, te::gm::Envelope& e) const;
514
515 /*! \brief It returns the average value along the axis. */
516 double average(std::vector<std::pair<kdKey, kdDataItem> >& dataSet, const char& discriminator) const
517 {
518 const std::size_t size = dataSet.size();
519
520 double medianValue = 0.0;
521
522 if(discriminator == 'x')
523 {
524 for(unsigned int i = 0; i < size; ++i)
525 medianValue += dataSet[i].first.getX();
526
527 return medianValue / size;
528 }
529 else
530 {
531 for(unsigned int i = 0; i < size; ++i)
532 medianValue += dataSet[i].first.getY();
533
534 return medianValue / size;
535 }
536 }
537
538 /*!
539 \brief No copy constructor allowed.
540
541 \param rhs The other index.
542 */
544
545 /*!
546 \brief No assignment operator allowed.
547
548 \param rhs The other index.
549
550 \return A reference for this.
551 */
553
554 private:
555
556 KdTreeNode* m_root; //!< Pointer to the root node.
557 te::gm::Envelope m_mbr; //!< Minimum bounding box of all nodes.
558 std::size_t m_size; //!< The size of the K-d Tree (number of nodes).
559 std::size_t m_bucketSize; //!< Bucket size (maximum number of elements in each node).
560 };
561
562 template<class KdTreeNode>
563 void AdaptativeIndex<KdTreeNode>::search(const te::gm::Envelope& e, std::vector<kdDataItem>& report) const
564 {
565 std::vector<KdTreeNode*> reportNodes;
566
567 search(e, reportNodes);
568
569 std::size_t nNodes = reportNodes.size();
570
571 for(std::size_t i = 0; i < nNodes; ++i)
572 {
573 std::size_t nElements = reportNodes[i]->getData().size();
574
575 for(std::size_t j = 0; j < nElements; ++j)
576 {
577 if(Intersects((reportNodes[i])->getData()[j], e))
578 report.push_back((reportNodes[i])->getData()[j]);
579 }
580 }
581 }
582
583 template<class KdTreeNode>
584 KdTreeNode* AdaptativeIndex<KdTreeNode>::build(std::vector<std::pair<kdKey, kdDataItem> >& dataSet, double averageValue, const te::gm::Envelope& mbr)
585 {
586 ++m_size;
587
588 if(dataSet.size() <= m_bucketSize)
589 {
590 KdTreeNode* node = new KdTreeNode(averageValue);
591
592 node->setDiscriminator('l');
593
594 std::size_t size = dataSet.size();
595
596 for(std::size_t i = 0; i < size; ++i)
597 node->getData().push_back(dataSet[i].second);
598
599 return node;
600 }
601
602 te::gm::Envelope newMbr1(mbr);
603 te::gm::Envelope newMbr2(mbr);
604
605 char discriminator = 'x';
606
607 std::vector<std::pair<kdKey, kdDataItem> > leftDataSet;
608 std::vector<std::pair<kdKey, kdDataItem> > rightDataSet;
609
610 // Finds the largest dimension
611 if((mbr.m_urx - mbr.m_llx) > (mbr.m_ury - mbr.m_lly))
612 {
613 // Finds the median along "x" axis
614 averageValue = average(dataSet, 'x');
615
616 // Adjust box for left and right branchs
617 newMbr1.m_urx = averageValue;
618 newMbr2.m_llx = averageValue;
619
620 std::size_t size = dataSet.size();
621
622 for(std::size_t i = 0; i < size; ++ i)
623 {
624 if(dataSet[i].first.getX() <= averageValue)
625 leftDataSet.push_back(dataSet[i]);
626 else
627 rightDataSet.push_back(dataSet[i]);
628 }
629 }
630 else
631 {
632 discriminator = 'y';
633
634 // Finds the median along "y" axis
635 averageValue = average(dataSet, 'y');
636
637 // Adjust box for left and right branchs
638 newMbr1.m_ury = averageValue;
639 newMbr2.m_lly = averageValue;
640
641 std::size_t size = dataSet.size();
642
643 for(std::size_t i = 0; i < size; ++ i)
644 {
645 if(dataSet[i].first.getY() <= averageValue)
646 leftDataSet.push_back(dataSet[i]);
647 else
648 rightDataSet.push_back(dataSet[i]);
649 }
650 }
651
652 dataSet.clear();
653
654 KdTreeNode* node = new KdTreeNode(averageValue);
655
656 if(rightDataSet.size() == 0) // If all coordinates have the same coordinate values, the right vector will be empty so we need stop division to
657 {
658 node->setDiscriminator('l');
659
660 std::size_t size = leftDataSet.size();
661
662 for(std::size_t i = 0; i < size; ++i)
663 node->getData().push_back(leftDataSet[i].second);
664 }
665 else if(leftDataSet.size() == 0) // If all coordinates have the same coordinate values, the left vector is empty, so we need to stop
666 {
667 node->setDiscriminator('l');
668
669 std::size_t size = rightDataSet.size();
670
671 for(std::size_t i = 0; i < size; ++i)
672 node->getData().push_back(rightDataSet[i].second);
673 }
674 else
675 {
676 node->setDiscriminator(discriminator);
677 node->setLeft(build(leftDataSet, averageValue, newMbr1));
678 node->setRight(build(rightDataSet, averageValue, newMbr2));
679 }
680
681 return node;
682 }
683
684 template<class KdTreeNode>
685 void AdaptativeIndex<KdTreeNode>::nearestNeighborSearch(KdTreeNode* node, const kdKey& key, std::vector<kdDataItem>& report, std::vector<double>& sqrDists, te::gm::Envelope& e) const
686 {
687 if(node->getDiscriminator() == 'l')
688 {
689 update(node, key, report, sqrDists, e); // this is a leaf node -> update list of neighbours
690 }
691 else if(node->getDiscriminator() == 'x')
692 {
693 if(key.getX() <= node->getKey())
694 {
695 nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
696
697 if((e.m_llx < node->getKey()) && (node->getKey() < e.m_urx))
698 nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
699 }
700 else
701 {
702 nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
703
704 if((e.m_llx < node->getKey()) &&(node->getKey() < e.m_urx))
705 nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
706 }
707 }
708 else if(node->getDiscriminator() == 'y')
709 {
710 if(key.getY() <= node->getKey())
711 {
712 nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
713
714 if((e.m_lly < node->getKey()) &&(node->getKey() < e.m_ury))
715 nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
716 }
717 else
718 {
719 nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
720
721 if((e.m_lly < node->getKey()) &&(node->getKey() < e.m_ury))
722 nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
723 }
724 }
725 }
726
727 template<class KdTreeNode>
728 void AdaptativeIndex<KdTreeNode>::search(const te::gm::Envelope& e, KdTreeNode* node, std::vector<KdTreeNode*>& report) const
729 {
730 if(node->getDiscriminator() == 'x')
731 {
732 if(node->hasLeft())
733 if(e.m_llx <= node->getKey())
734 search(e, node->getLeft(), report);
735
736 if(node->hasRight())
737 if(e.m_urx >= node->getKey())
738 search(e, node->getRight(), report);
739 }
740 else if(node->getDiscriminator() == 'y')
741 {
742 if(node->hasLeft())
743 if(e.m_lly <= node->getKey())
744 search(e, node->getLeft(), report);
745
746 if(node->hasRight())
747 if(e.m_ury >= node->getKey())
748 search(e, node->getRight(), report);
749 }
750 else
751 report.push_back(node);
752 }
753
754 template<class KdTreeNode>
755 void AdaptativeIndex<KdTreeNode>::update(KdTreeNode* node, const kdKey& key, std::vector<kdDataItem>& report, std::vector<double>& sqrDists, te::gm::Envelope& e) const
756 {
757 const std::size_t size = node->getData().size();
758
759 const std::size_t nNeighbors = report.size();
760
761// for each element in the node, we need to search for distances less than of some one of sqrDists
762 for(std::size_t i = 0; i < size; ++i)
763 {
764 double dx = (key.getX() - node->getData()[i].getX());
765 double dy = (key.getY() - node->getData()[i].getY());
766
767 double dkp = (dx * dx) + (dy * dy); // square distance from the key point to the node
768
769// if the distance of "i-th" element is less than the maximum distance in the sqrDists
770 if(dkp < sqrDists[nNeighbors - 1])
771 {
772// so the element must be reported
773// and the srqDists vector must be rearranged
774 for(std::size_t j = 0; j < nNeighbors; ++j)
775 {
776 if(dkp < sqrDists[j]) // if the position is found
777 {
778// move the elements to the right
779 for(std::size_t k = nNeighbors - 1; k > j; --k)
780 {
781 report[k] = report[k - 1];
782 sqrDists[k] = sqrDists[k - 1];
783 }
784
785// inserts the element in the report and update its distance
786 report[j] = node->getData()[i];
787
788 sqrDists[j] = dkp;
789
790 break;
791 }
792 }
793 }
794 }
795
796 double maxDist = sqrDists[nNeighbors - 1];
797
798 if(maxDist != std::numeric_limits<double>::max())
799 maxDist = sqrt(maxDist);
800
801 e.m_llx = key.getX() - maxDist;
802 e.m_lly = key.getY() - maxDist;
803 e.m_urx = key.getX() + maxDist;
804 e.m_ury = key.getY() + maxDist;
805 }
806
807 } // end namespace kdtree
808 } // end namespace sam
809} // end namespace te
810
811#endif // __TERRALIB_SAM_KDTREE_INTERNAL_INDEX_H
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:52
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
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 a two dimensional K-d Tree (2-d Tree) that store data-elements into the leafs...
Definition: Index.h:375
double average(std::vector< std::pair< kdKey, kdDataItem > > &dataSet, const char &discriminator) const
It returns the average value along the axis.
Definition: Index.h:516
void nearestNeighborSearch(const kdKey &key, std::vector< kdDataItem > &report, std::vector< double > &sqrDists, const std::size_t &k) const
It searches the nearest data in nodes: you must pass an array of kdDataItem of size "k" with coordina...
Definition: Index.h:463
bool isEmpty() const
It returns true if the tree is empty and false otherwise.
Definition: Index.h:423
void update(KdTreeNode *node, const kdKey &key, std::vector< kdDataItem > &report, std::vector< double > &sqrDists, te::gm::Envelope &e) const
It updates the neighbor list.
Definition: Index.h:755
void setBucketSize(const std::size_t &size)
It sets bucket size for leaf nodes.
Definition: Index.h:441
void setMBR(const te::gm::Envelope &mbr)
It sets the minimum bounding box of all elements in the tree.
Definition: Index.h:429
void erase(KdTreeNode *node)
It Erases a node from the tree and all nodes below it.
Definition: Index.h:492
const std::size_t & size() const
It returns the number of tree nodes.
Definition: Index.h:417
KdTreeNode::kdData kdData
Export data type.
Definition: Index.h:382
const te::gm::Envelope & getMBR() const
It gets the minimum bounding box of all elements in the tree.
Definition: Index.h:435
std::size_t m_size
The size of the K-d Tree (number of nodes).
Definition: Index.h:558
KdTreeNode::kdKey kdKey
Export key type.
Definition: Index.h:379
AdaptativeIndex(const te::gm::Envelope &mbr, const std::size_t &bucketSize=12)
Constructor.
Definition: Index.h:391
~AdaptativeIndex()
Destructor.
Definition: Index.h:400
AdaptativeIndex & operator=(const AdaptativeIndex &rhs)
No assignment operator allowed.
AdaptativeIndex(const AdaptativeIndex &rhs)
No copy constructor allowed.
KdTreeNode kdNode
Export node type.
Definition: Index.h:388
void clear()
It clears all tree nodes.
Definition: Index.h:406
const std::size_t & getBucketSize() const
It gets bucket size for leaf nodes.
Definition: Index.h:447
KdTreeNode::kdDataItem kdDataItem
Export data item type.
Definition: Index.h:385
void search(const te::gm::Envelope &e, std::vector< KdTreeNode * > &report) const
Range search query.
Definition: Index.h:480
KdTreeNode * m_root
Pointer to the root node.
Definition: Index.h:556
void build(std::vector< std::pair< kdKey, kdDataItem > > &dataSet)
It inserts the data set into the tree.
Definition: Index.h:453
std::size_t m_bucketSize
Bucket size (maximum number of elements in each node).
Definition: Index.h:559
te::gm::Envelope m_mbr
Minimum bounding box of all nodes.
Definition: Index.h:557
A class that represents a two dimensional K-d Tree (2-d Tree).
Definition: Index.h:68
KdTreeNode * m_root
Pointer to the root node.
Definition: Index.h:217
void buildOptimized(std::vector< std::pair< kdKey, kdData > > &dataSet)
It inserts the data in the tree and and keeps it balanced: the kdsort algorithm must be called before...
Definition: Index.h:136
const te::gm::Envelope & getMBR() const
It gets the minimum bounding box of all elements in the tree.
Definition: Index.h:127
~Index()
Destructor.
Definition: Index.h:92
KdTreeNode::kdDataItem kdDataItem
Export data item type.
Definition: Index.h:78
std::size_t m_size
The size of the K-d Tree (number of nodes).
Definition: Index.h:219
void search(const te::gm::Envelope &e, KdTreeNode *node, const char &level, std::vector< KdTreeNode * > &report) const
Recursive range query.
Definition: Index.h:309
KdTreeNode::kdDataTag kdDataTag
Export data type.
Definition: Index.h:81
void insertData(KdTreeNode *&node, const kdData &data, const kd_node_m_datasingle_tag &)
It inserts data for single nodes, i.e. nodes that stores only one element.
Definition: Index.h:164
bool isEmpty() const
It returns true if the tree is empty and false otherwise.
Definition: Index.h:115
void insert(const kdKey &key, const kdData &item)
It inserts the data with a given key in tree.
Definition: Index.h:223
Index(const Index &rhs)
No copy constructor allowed.
void insertData(KdTreeNode *&node, const kdData &data, const kd_node_m_dataset_tag &)
It inserts data for set nodes, i.e., nodes that may stores many element.
Definition: Index.h:171
KdTreeNode::kdKey kdKey
Export key type.
Definition: Index.h:72
te::gm::Envelope m_mbr
Minimum bounding box of all nodes.
Definition: Index.h:218
void search(const te::gm::Envelope &e, std::vector< KdTreeNode * > &report) const
Range search query.
Definition: Index.h:143
void setMBR(const te::gm::Envelope &mbr)
It sets the minimum bounding box of all elements in the tree.
Definition: Index.h:121
KdTreeNode * buildOptimized(std::vector< std::pair< kdKey, kdData > > &dataSet, const std::size_t &first, const std::size_t &last)
It builds the tree recursively.
Definition: Index.h:180
void erase(KdTreeNode *node)
It Erases a node from the tree and all nodes below it.
Definition: Index.h:152
Index & operator=(const Index &rhs)
No assignment operator allowed.
Index(const te::gm::Envelope &mbr)
Constructor.
Definition: Index.h:84
void clear()
It clears all tree nodes.
Definition: Index.h:98
KdTreeNode::kdData kdData
Export data type.
Definition: Index.h:75
const std::size_t & size() const
It returns the number of tree nodes.
Definition: Index.h:109
bool Intersects(const T &data, const te::gm::Envelope &e)
Definition: Index.h:340
TerraLib.
A class that represents an R-tree node.
Kd-Tree node type for nodes with multuple elements (used by template instantiation).
Definition: Node.h:39
Kd-tree node type for nodes with single elements (used by template instantiation).
Definition: Node.h:36