26 #ifndef __TERRALIB_SAM_KDTREE_INTERNAL_INDEX_H 
   27 #define __TERRALIB_SAM_KDTREE_INTERNAL_INDEX_H 
   30 #include "../../geometry/Envelope.h" 
   31 #include "../../geometry/Utils.h" 
   67       template<
class KdTreeNode> 
class Index 
   72           typedef typename KdTreeNode::kdKey 
kdKey;
 
   75           typedef typename KdTreeNode::kdData 
kdData;
 
  109           const std::size_t& 
size()
 const 
  133           inline void insert(
const kdKey& key, 
const kdDataItem& item);
 
  138             const std::size_t last = dataSet.size() - 1;
 
  155               erase(node->getLeft());
 
  158               erase(node->getRight());
 
  177           inline void search(
const te::gm::Envelope& e, KdTreeNode* node, 
const char& level, std::vector<KdTreeNode*>& report) 
const;
 
  180           KdTreeNode* 
buildOptimized(std::vector<std::pair<kdKey, kdDataItem> >& dataSet, 
const std::size_t& first, 
const std::size_t& last)
 
  182             const std::size_t kth = (last - first + 1) / 2;
 
  184             KdTreeNode* newNode = 
new KdTreeNode(dataSet[first + kth].first);
 
  186             newNode->setData(dataSet[first + kth].second);
 
  190             if(first + kth > first)
 
  191               newNode->setLeft(
buildOptimized(dataSet, first, first + kth - 1));
 
  193             if(first + kth < last)
 
  194               newNode->setRight(
buildOptimized(dataSet, first + kth + 1, last));
 
  222       template<
class KdTreeNode>
 
  227           m_root = 
new KdTreeNode(key);
 
  236           KdTreeNode* x = m_root;
 
  245               if(key.getX() > x->getKey().getX()) 
 
  250               else if(key.getX() < x->getKey().getX())  
 
  255               else if(key.getY() == x->getKey().getY()) 
 
  270               if(key.getY() > x->getKey().getY())
 
  275               else if(key.getY() < x->getKey().getY())
 
  280               else if(key.getX() == x->getKey().getX())
 
  295           KdTreeNode* newNode = 
new KdTreeNode(key);
 
  302             y->setRight(newNode);
 
  308       template<
class KdTreeNode>
 
  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))
 
  314           report.push_back(node);
 
  320             if(node->getKey().getX() >= e.
m_llx)
 
  321               search(e, node->getLeft(), 
'y', report);
 
  324             if(node->getKey().getX() <= e.
m_urx)
 
  325               search(e, node->getRight(), 
'y', report);
 
  330             if(node->getKey().getY() >= e.
m_lly)
 
  331               search(e, node->getLeft(), 
'x', report);
 
  334             if(node->getKey().getY() <= e.
m_ury)
 
  335               search(e, node->getRight(), 
'x', report);
 
  357           typedef typename KdTreeNode::kdKey 
kdKey;
 
  360           typedef typename KdTreeNode::kdData 
kdData;
 
  395           const std::size_t& 
size()
 const 
  431           void build(std::vector<std::pair<kdKey, kdDataItem> >& dataSet)
 
  441           void nearestNeighborSearch(
const kdKey& key, std::vector<kdDataItem>& report, std::vector<double>& sqrDists, 
const std::size_t& k)
 const 
  447               for(std::size_t i = 0; i < k; ++i)
 
  448                 sqrDists.push_back(std::numeric_limits<double>::max());
 
  450               te::gm::Envelope e(-std::numeric_limits<double>::max(), -std::numeric_limits<double>::max(),
 
  451                                  +std::numeric_limits<double>::max(), +std::numeric_limits<double>::max());
 
  473               erase(node->getLeft());
 
  476               erase(node->getRight());
 
  482           inline KdTreeNode* 
build(std::vector<std::pair<kdKey, kdDataItem> >& dataSet, 
double averageValue, 
const te::gm::Envelope& mbr);
 
  491           inline void update(KdTreeNode* node, 
const kdKey& key, std::vector<kdDataItem>& report, std::vector<double>& sqrDists, 
te::gm::Envelope& e) 
const;
 
  494           double average(std::vector<std::pair<kdKey, kdDataItem> >& dataSet, 
const char& discriminator)
 const 
  496             const std::size_t 
size = dataSet.size();
 
  498             double medianValue = 0.0;
 
  500             if(discriminator == 
'x')
 
  502               for(
unsigned int i = 0; i < 
size; ++i)
 
  503                 medianValue += dataSet[i].first.getX();
 
  505               return medianValue / 
size;
 
  509               for(
unsigned int i = 0; i < 
size; ++i)
 
  510                 medianValue += dataSet[i].first.getY();
 
  512               return medianValue / 
size;
 
  540       template<
class KdTreeNode>
 
  543         std::vector<KdTreeNode*> reportNodes;
 
  545         search(e, reportNodes);
 
  547         std::size_t nNodes = reportNodes.size();
 
  549         for(std::size_t i = 0; i < nNodes; ++i)
 
  551           std::size_t nElements = reportNodes[i]->getData().size();
 
  553           for(std::size_t j = 0; j < nElements; ++j)
 
  556               report.push_back((reportNodes[i])->getData()[j]);
 
  561       template<
class KdTreeNode>
 
  566         if(dataSet.size() <= m_bucketSize)
 
  568           KdTreeNode* node = 
new KdTreeNode(averageValue);
 
  570           node->setDiscriminator(
'l');
 
  572           std::size_t size = dataSet.size();
 
  574           for(std::size_t i = 0; i < size; ++i)
 
  575             node->getData().push_back(dataSet[i].second);
 
  583         char discriminator = 
'x';
 
  585         std::vector<std::pair<kdKey, kdDataItem> > leftDataSet;
 
  586         std::vector<std::pair<kdKey, kdDataItem> > rightDataSet;
 
  592           averageValue = average(dataSet, 
'x');
 
  595           newMbr1.
m_urx = averageValue;
 
  596           newMbr2.
m_llx = averageValue;
 
  598           std::size_t size = dataSet.size();
 
  600           for(std::size_t i = 0; i < size; ++ i)
 
  602             if(dataSet[i].first.getX() <= averageValue)
 
  603               leftDataSet.push_back(dataSet[i]);
 
  605               rightDataSet.push_back(dataSet[i]);
 
  613           averageValue = average(dataSet, 
'y');
 
  616           newMbr1.
m_ury = averageValue;
 
  617           newMbr2.
m_lly = averageValue;
 
  619           std::size_t size = dataSet.size();
 
  621           for(std::size_t i = 0; i < size; ++ i)
 
  623             if(dataSet[i].first.getY() <= averageValue)
 
  624               leftDataSet.push_back(dataSet[i]);
 
  626               rightDataSet.push_back(dataSet[i]);
 
  632         KdTreeNode* node = 
new KdTreeNode(averageValue);
 
  634         if(rightDataSet.size() == 0) 
 
  636           node->setDiscriminator(
'l');
 
  638           std::size_t size = leftDataSet.size();
 
  640           for(std::size_t i = 0; i < size; ++i)
 
  641             node->getData().push_back(leftDataSet[i].second);
 
  643         else if(leftDataSet.size() == 0) 
 
  645           node->setDiscriminator(
'l');
 
  647           std::size_t size = rightDataSet.size();
 
  649           for(std::size_t i = 0; i < size; ++i)
 
  650             node->getData().push_back(rightDataSet[i].second);
 
  654           node->setDiscriminator(discriminator);
 
  655           node->setLeft(build(leftDataSet, averageValue, newMbr1));
 
  656           node->setRight(build(rightDataSet, averageValue, newMbr2));
 
  662       template<
class KdTreeNode>
 
  665         if(node->getDiscriminator() == 
'l')
 
  667           update(node, key, report, sqrDists, e); 
 
  669         else if(node->getDiscriminator() == 
'x')
 
  671           if(key.getX() <= node->getKey())
 
  673             nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
 
  675             if((e.
m_llx < node->getKey()) && (node->getKey() < e.
m_urx))
 
  676               nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
 
  680             nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
 
  682             if((e.
m_llx < node->getKey()) &&(node->getKey() < e.
m_urx))
 
  683               nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
 
  686         else if(node->getDiscriminator() == 
'y')
 
  688           if(key.getY() <= node->getKey())
 
  690             nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
 
  692             if((e.
m_lly < node->getKey()) &&(node->getKey() < e.
m_ury))
 
  693               nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
 
  697             nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
 
  699             if((e.
m_lly < node->getKey()) &&(node->getKey() < e.
m_ury))
 
  700               nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
 
  705       template<
class KdTreeNode>
 
  708         if(node->getDiscriminator() == 
'x')
 
  711             if(e.
m_llx <= node->getKey())
 
  712               search(e, node->getLeft(), report);
 
  715             if(e.
m_urx >= node->getKey())
 
  716               search(e, node->getRight(), report);
 
  718         else if(node->getDiscriminator() == 
'y')
 
  721             if(e.
m_lly <= node->getKey())
 
  722               search(e, node->getLeft(), report);
 
  725             if(e.
m_ury >= node->getKey())
 
  726               search(e, node->getRight(), report);
 
  729           report.push_back(node);
 
  732       template<
class KdTreeNode>
 
  735         const std::size_t size = node->getData().size();
 
  737         const std::size_t nNeighbors = report.size();
 
  740         for(std::size_t i = 0; i < size; ++i)
 
  742           double dx = (key.getX() - node->getData()[i].getX());
 
  743           double dy = (key.getY() - node->getData()[i].getY());
 
  745           double dkp = (dx * dx) + (dy * dy); 
 
  748           if(dkp < sqrDists[nNeighbors - 1])
 
  752             for(std::size_t j = 0; j < nNeighbors; ++j)
 
  754               if(dkp < sqrDists[j]) 
 
  757                 for(std::size_t k = nNeighbors - 1; k > j; --k)
 
  759                   report[k]   = report[k - 1];
 
  760                   sqrDists[k] = sqrDists[k - 1];
 
  764                 report[j] = node->getData()[i];
 
  774       double maxDist = sqrDists[nNeighbors - 1];
 
  776       if(maxDist != std::numeric_limits<double>::max())
 
  777         maxDist = sqrt(maxDist);
 
  779       e.
m_llx = key.getX() - maxDist;
 
  780       e.
m_lly = key.getY() - maxDist;
 
  781       e.
m_urx = key.getX() + maxDist;
 
  782       e.
m_ury = key.getY() + maxDist;
 
  789 #endif  // __TERRALIB_SAM_KDTREE_INTERNAL_INDEX_H 
void insert(const kdKey &key, const kdDataItem &item)
It inserts the data with a given key in tree. 
 
void clear()
It clears all tree nodes. 
 
void setMBR(const te::gm::Envelope &mbr)
It sets the minimum bounding box of all elements in the tree. 
 
const te::gm::Envelope & getMBR() const 
It gets the minimum bounding box of all elements in the tree. 
 
KdTreeNode::kdDataTag kdDataTag
Export data type. 
 
A class that represents an Kd-tree node. 
 
std::size_t m_bucketSize
Bucket size (maximum number of elements in each node). 
 
void search(const te::gm::Envelope &e, std::vector< KdTreeNode * > &report) const 
Range search query. 
 
void erase(KdTreeNode *node)
It Erases a node from the tree and all nodes below it. 
 
KdTreeNode::kdKey kdKey
Export key type. 
 
A class that represents a two dimensional K-d Tree (2-d Tree) that store data-elements into the leafs...
 
te::gm::Envelope m_mbr
Minimum bounding box of all nodes. 
 
double m_urx
Upper right corner x-coordinate. 
 
KdTreeNode kdNode
Export node type. 
 
KdTreeNode::kdData kdData
Export data type. 
 
const std::size_t & size() const 
It returns the number of tree nodes. 
 
bool isEmpty() const 
It returns true if the tree is empty and false otherwise. 
 
double average(std::vector< std::pair< kdKey, kdDataItem > > &dataSet, const char &discriminator) const 
It returns the average value along the axis. 
 
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. 
 
KdTreeNode * m_root
Pointer to the root node. 
 
KdTreeNode::kdData kdData
Export data type. 
 
std::size_t m_size
The size of the K-d Tree (number of nodes). 
 
void setBucketSize(const std::size_t &size)
It sets bucket size for leaf nodes. 
 
double m_llx
Lower left corner x-coordinate. 
 
An Envelope defines a 2D rectangular region. 
 
const std::size_t & size() const 
It returns the number of tree nodes. 
 
void build(std::vector< std::pair< kdKey, kdDataItem > > &dataSet)
It inserts the data set into the tree. 
 
void buildOptimized(std::vector< std::pair< kdKey, kdDataItem > > &dataSet)
It inserts the data in the tree and and keeps it balanced: the kdsort algorithm must be called before...
 
const te::gm::Envelope & getMBR() const 
It gets the minimum bounding box of all elements in the tree. 
 
AdaptativeIndex(const te::gm::Envelope &mbr, const std::size_t &bucketSize=12)
Constructor. 
 
te::gm::Envelope m_mbr
Minimum bounding box of all nodes. 
 
const std::size_t & getBucketSize() const 
It gets bucket size for leaf nodes. 
 
A class that represents a two dimensional K-d Tree (2-d Tree). 
 
bool Intersects(const T1 &o1, const T2 &o2)
 
double m_lly
Lower left corner y-coordinate. 
 
KdTreeNode::kdDataItem kdDataItem
Export data item type. 
 
KdTreeNode * m_root
Pointer to the root node. 
 
void insertData(KdTreeNode *&node, const kdDataItem &data, const kd_node_m_datasingle_tag &)
It inserts data for single nodes, i.e. nodes that stores only one element. 
 
Kd-tree node type for nodes with single elements (used by template instantiation). 
 
AdaptativeIndex & operator=(const AdaptativeIndex &rhs)
No assignment operator allowed. 
 
double m_ury
Upper right corner y-coordinate. 
 
void clear()
It clears all tree nodes. 
 
KdTreeNode::kdDataItem kdDataItem
Export data item type. 
 
std::size_t m_size
The size of the K-d Tree (number of nodes). 
 
void setMBR(const te::gm::Envelope &mbr)
It sets the minimum bounding box of all elements in the tree. 
 
Index(const te::gm::Envelope &mbr)
Constructor. 
 
bool isEmpty() const 
It returns true if the tree is empty and false otherwise. 
 
void search(const te::gm::Envelope &e, std::vector< KdTreeNode * > &report) const 
Range search query. 
 
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...
 
Index & operator=(const Index &rhs)
No assignment operator allowed. 
 
~AdaptativeIndex()
Destructor. 
 
KdTreeNode * buildOptimized(std::vector< std::pair< kdKey, kdDataItem > > &dataSet, const std::size_t &first, const std::size_t &last)
It builds the tree recursively. 
 
void erase(KdTreeNode *node)
It Erases a node from the tree and all nodes below it. 
 
KdTreeNode::kdKey kdKey
Export key type.