26 #ifndef __TERRALIB_SAM_KDTREE_INTERNAL_INDEX_H 
   27 #define __TERRALIB_SAM_KDTREE_INTERNAL_INDEX_H 
   30 #include "../../geometry/Envelope.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 
  138             const std::size_t last = dataSet.size() - 1;
 
  155               erase(node->getLeft());
 
  158               erase(node->getRight());
 
  173             node->getData().push_back(data);
 
  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, kdData> >& 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);
 
  343         if (data.getX() > e.
m_urx)
 
  347         if (e.
m_llx > data.getX())
 
  351         if (data.getY() > e.
m_ury)
 
  355         if (e.
m_lly > data.getY())
 
  379           typedef typename KdTreeNode::kdKey 
kdKey;
 
  382           typedef typename KdTreeNode::kdData 
kdData;
 
  417           const std::size_t& 
size()
 const 
  453           void build(std::vector<std::pair<kdKey, kdDataItem> >& dataSet)
 
  469               for(std::size_t i = 0; i < k; ++i)
 
  470                 sqrDists.push_back(std::numeric_limits<double>::max());
 
  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());
 
  495               erase(node->getLeft());
 
  498               erase(node->getRight());
 
  504           inline KdTreeNode* 
build(std::vector<std::pair<kdKey, kdDataItem> >& dataSet, 
double averageValue, 
const te::gm::Envelope& mbr);
 
  513           inline void update(KdTreeNode* node, 
const kdKey& key, std::vector<kdDataItem>& report, std::vector<double>& sqrDists, 
te::gm::Envelope& e) 
const;
 
  516           double average(std::vector<std::pair<kdKey, kdDataItem> >& dataSet, 
const char& discriminator)
 const 
  518             const std::size_t 
size = dataSet.size();
 
  520             double medianValue = 0.0;
 
  522             if(discriminator == 
'x')
 
  524               for(
unsigned int i = 0; i < 
size; ++i)
 
  525                 medianValue += dataSet[i].first.getX();
 
  527               return medianValue / 
size;
 
  531               for(
unsigned int i = 0; i < 
size; ++i)
 
  532                 medianValue += dataSet[i].first.getY();
 
  534               return medianValue / 
size;
 
  562       template<
class KdTreeNode>
 
  565         std::vector<KdTreeNode*> reportNodes;
 
  567         search(e, reportNodes);
 
  569         std::size_t nNodes = reportNodes.size();
 
  571         for(std::size_t i = 0; i < nNodes; ++i)
 
  573           std::size_t nElements = reportNodes[i]->getData().size();
 
  575           for(std::size_t j = 0; j < nElements; ++j)
 
  577             if(
Intersects((reportNodes[i])->getData()[j], e))
 
  578               report.push_back((reportNodes[i])->getData()[j]);
 
  583       template<
class KdTreeNode>
 
  588         if(dataSet.size() <= m_bucketSize)
 
  590           KdTreeNode* node = 
new KdTreeNode(averageValue);
 
  592           node->setDiscriminator(
'l');
 
  594           std::size_t size = dataSet.size();
 
  596           for(std::size_t i = 0; i < size; ++i)
 
  597             node->getData().push_back(dataSet[i].second);
 
  605         char discriminator = 
'x';
 
  607         std::vector<std::pair<kdKey, kdDataItem> > leftDataSet;
 
  608         std::vector<std::pair<kdKey, kdDataItem> > rightDataSet;
 
  614           averageValue = average(dataSet, 
'x');
 
  617           newMbr1.
m_urx = averageValue;
 
  618           newMbr2.
m_llx = averageValue;
 
  620           std::size_t size = dataSet.size();
 
  622           for(std::size_t i = 0; i < size; ++ i)
 
  624             if(dataSet[i].first.getX() <= averageValue)
 
  625               leftDataSet.push_back(dataSet[i]);
 
  627               rightDataSet.push_back(dataSet[i]);
 
  635           averageValue = average(dataSet, 
'y');
 
  638           newMbr1.
m_ury = averageValue;
 
  639           newMbr2.
m_lly = averageValue;
 
  641           std::size_t size = dataSet.size();
 
  643           for(std::size_t i = 0; i < size; ++ i)
 
  645             if(dataSet[i].first.getY() <= averageValue)
 
  646               leftDataSet.push_back(dataSet[i]);
 
  648               rightDataSet.push_back(dataSet[i]);
 
  654         KdTreeNode* node = 
new KdTreeNode(averageValue);
 
  656         if(rightDataSet.size() == 0) 
 
  658           node->setDiscriminator(
'l');
 
  660           std::size_t size = leftDataSet.size();
 
  662           for(std::size_t i = 0; i < size; ++i)
 
  663             node->getData().push_back(leftDataSet[i].second);
 
  665         else if(leftDataSet.size() == 0) 
 
  667           node->setDiscriminator(
'l');
 
  669           std::size_t size = rightDataSet.size();
 
  671           for(std::size_t i = 0; i < size; ++i)
 
  672             node->getData().push_back(rightDataSet[i].second);
 
  676           node->setDiscriminator(discriminator);
 
  677           node->setLeft(build(leftDataSet, averageValue, newMbr1));
 
  678           node->setRight(build(rightDataSet, averageValue, newMbr2));
 
  684       template<
class KdTreeNode>
 
  687         if(node->getDiscriminator() == 
'l')
 
  689           update(node, key, report, sqrDists, e); 
 
  691         else if(node->getDiscriminator() == 
'x')
 
  693           if(key.getX() <= node->getKey())
 
  695             nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
 
  697             if((e.
m_llx < node->getKey()) && (node->getKey() < e.
m_urx))
 
  698               nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
 
  702             nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
 
  704             if((e.
m_llx < node->getKey()) &&(node->getKey() < e.
m_urx))
 
  705               nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
 
  708         else if(node->getDiscriminator() == 
'y')
 
  710           if(key.getY() <= node->getKey())
 
  712             nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
 
  714             if((e.
m_lly < node->getKey()) &&(node->getKey() < e.
m_ury))
 
  715               nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
 
  719             nearestNeighborSearch(node->getRight(), key, report, sqrDists, e);
 
  721             if((e.
m_lly < node->getKey()) &&(node->getKey() < e.
m_ury))
 
  722               nearestNeighborSearch(node->getLeft(), key, report, sqrDists, e);
 
  727       template<
class KdTreeNode>
 
  730         if(node->getDiscriminator() == 
'x')
 
  733             if(e.
m_llx <= node->getKey())
 
  734               search(e, node->getLeft(), report);
 
  737             if(e.
m_urx >= node->getKey())
 
  738               search(e, node->getRight(), report);
 
  740         else if(node->getDiscriminator() == 
'y')
 
  743             if(e.
m_lly <= node->getKey())
 
  744               search(e, node->getLeft(), report);
 
  747             if(e.
m_ury >= node->getKey())
 
  748               search(e, node->getRight(), report);
 
  751           report.push_back(node);
 
  754       template<
class KdTreeNode>
 
  757         const std::size_t size = node->getData().size();
 
  759         const std::size_t nNeighbors = report.size();
 
  762         for(std::size_t i = 0; i < size; ++i)
 
  764           double dx = (key.getX() - node->getData()[i].getX());
 
  765           double dy = (key.getY() - node->getData()[i].getY());
 
  767           double dkp = (dx * dx) + (dy * dy); 
 
  770           if(dkp < sqrDists[nNeighbors - 1])
 
  774             for(std::size_t j = 0; j < nNeighbors; ++j)
 
  776               if(dkp < sqrDists[j]) 
 
  779                 for(std::size_t k = nNeighbors - 1; k > j; --k)
 
  781                   report[k]   = report[k - 1];
 
  782                   sqrDists[k] = sqrDists[k - 1];
 
  786                 report[j] = node->getData()[i];
 
  796       double maxDist = sqrDists[nNeighbors - 1];
 
  798       if(maxDist != std::numeric_limits<double>::max())
 
  799         maxDist = sqrt(maxDist);
 
  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;
 
An Envelope defines a 2D rectangular region.
 
double m_llx
Lower left corner x-coordinate.
 
double m_urx
Upper right corner x-coordinate.
 
double m_ury
Upper right corner y-coordinate.
 
double m_lly
Lower left corner y-coordinate.
 
A class that represents a two dimensional K-d Tree (2-d Tree) that store data-elements into the leafs...
 
AdaptativeIndex & operator=(const AdaptativeIndex &rhs)
No assignment operator allowed.
 
double average(std::vector< std::pair< kdKey, kdDataItem > > &dataSet, const char &discriminator) const
It returns the average value along the axis.
 
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...
 
bool isEmpty() const
It returns true if the tree is empty and false otherwise.
 
const std::size_t & size() const
It returns the number of tree nodes.
 
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.
 
void setBucketSize(const std::size_t &size)
It sets bucket size for leaf nodes.
 
void setMBR(const te::gm::Envelope &mbr)
It sets the minimum bounding box of all elements in the tree.
 
void erase(KdTreeNode *node)
It Erases a node from the tree and all nodes below it.
 
const std::size_t & getBucketSize() const
It gets bucket size for leaf nodes.
 
KdTreeNode::kdData kdData
Export data type.
 
std::size_t m_size
The size of the K-d Tree (number of nodes).
 
KdTreeNode::kdKey kdKey
Export key type.
 
AdaptativeIndex(const te::gm::Envelope &mbr, const std::size_t &bucketSize=12)
Constructor.
 
~AdaptativeIndex()
Destructor.
 
AdaptativeIndex(const AdaptativeIndex &rhs)
No copy constructor allowed.
 
KdTreeNode kdNode
Export node type.
 
void clear()
It clears all tree nodes.
 
KdTreeNode::kdDataItem kdDataItem
Export data item type.
 
void search(const te::gm::Envelope &e, std::vector< KdTreeNode * > &report) const
Range search query.
 
KdTreeNode * m_root
Pointer to the root node.
 
void build(std::vector< std::pair< kdKey, kdDataItem > > &dataSet)
It inserts the data set into the tree.
 
std::size_t m_bucketSize
Bucket size (maximum number of elements in each node).
 
const te::gm::Envelope & getMBR() const
It gets the minimum bounding box of all elements in the tree.
 
te::gm::Envelope m_mbr
Minimum bounding box of all nodes.
 
A class that represents a two dimensional K-d Tree (2-d Tree).
 
KdTreeNode * m_root
Pointer to the root node.
 
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...
 
KdTreeNode::kdDataItem kdDataItem
Export data item type.
 
KdTreeNode * buildOptimized(std::vector< std::pair< kdKey, kdData > > &dataSet, const std::size_t &first, const std::size_t &last)
It builds the tree recursively.
 
std::size_t m_size
The size of the K-d Tree (number of nodes).
 
void search(const te::gm::Envelope &e, KdTreeNode *node, const char &level, std::vector< KdTreeNode * > &report) const
Recursive range query.
 
KdTreeNode::kdDataTag kdDataTag
Export data type.
 
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.
 
bool isEmpty() const
It returns true if the tree is empty and false otherwise.
 
Index & operator=(const Index &rhs)
No assignment operator allowed.
 
void insert(const kdKey &key, const kdData &item)
It inserts the data with a given key in tree.
 
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.
 
KdTreeNode::kdKey kdKey
Export key type.
 
te::gm::Envelope m_mbr
Minimum bounding box of all nodes.
 
const te::gm::Envelope & getMBR() const
It gets the minimum bounding box of all elements in the tree.
 
void search(const te::gm::Envelope &e, std::vector< KdTreeNode * > &report) const
Range search query.
 
void setMBR(const te::gm::Envelope &mbr)
It sets the minimum bounding box of all elements in the tree.
 
const std::size_t & size() const
It returns the number of tree nodes.
 
void erase(KdTreeNode *node)
It Erases a node from the tree and all nodes below it.
 
Index(const te::gm::Envelope &mbr)
Constructor.
 
void clear()
It clears all tree nodes.
 
KdTreeNode::kdData kdData
Export data type.
 
bool Intersects(const T &data, const te::gm::Envelope &e)
 
A class that represents an R-tree node.
 
Kd-Tree node type for nodes with multuple elements (used by template instantiation).
 
Kd-tree node type for nodes with single elements (used by template instantiation).