Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Quadtree.hpp
Go to the documentation of this file.
00001 
00012 /* $Id$ */
00013 
00014 #ifndef LGL_LGLQUADTREE_HPP
00015 #define LGL_LGLQUADTREE_HPP
00016 
00017 #include <iostream>
00018 
00019 #include <list>
00020 #include <vector>
00021 
00022 #include <lgl/Decomp.hpp>
00023 #include <lgl/Decomposer.hpp>
00024 #include <lgl/Raster.hpp>
00025 
00026 using namespace std;
00027 
00028 namespace jafar { //namespace jafar
00029   namespace lgl { //namespace lgl
00030 
00031   // some declaration to speed up the compilation
00032   template<typename T, class RasterT> class Quadtree;
00033   template<typename T, class RasterT> class QuadNode;
00034   template<typename T, class RasterT> class QuadNodeLeaf;
00035   template<typename T, class RasterT> class QuadNodeInternal;
00036 
00042   template <
00043     typename T,
00044     class RasterT
00045     >
00046   class Quadtree : public TDecomposer<T,RasterT> { /*{{{ class Quadtree*/
00047 
00048   public:
00049 
00051     enum {  QUADTREE_TOP_LEFT_CELL=0,   QUADTREE_TOP_RIGHT_CELL,
00052             QUADTREE_BOTTOM_LEFT_CELL,  QUADTREE_BOTTOM_RIGHT_CELL };
00053 
00060     enum  UNWISE_SIZE_DIVISION_POLITIC {LEFTTOP, BOTTOMRIGHT, BALANCE};
00061 
00062     // Default dull constructor
00063     //Quadtree();
00064 
00068     Quadtree(RasterT* _raster, UNWISE_SIZE_DIVISION_POLITIC _uspolitic=LEFTTOP);
00069 
00072     ~Quadtree();
00073 
00077       QuadNodeInternal<T,RasterT>* getRootCell() const;
00078 
00082     bool getClusterForCell(const RasterCellIndex& cell, RasterRect& cluster) const;
00083 
00087     bool getClusterForCell(const RasterCellIndex& cell, RasterCellIndex& clusterRoot) const;
00088 
00092     bool getAdjacentClusters(const RasterCellIndex& root_cell, Decomp::SIDE side,std::list<RasterCellIndex>& clusters) const;
00093 
00097     T getData(const RasterRect& rect) const;
00098 
00102     T getData(const RasterCellIndex& cluster) const;
00103 
00104 
00109     std::list<QuadNodeLeaf<T,RasterT>*> getFullLeavesList() const;
00110 
00111    private:
00112 
00114     QuadNodeInternal<T,RasterT>* root;
00115 
00117     UNWISE_SIZE_DIVISION_POLITIC uspolitic;
00118 
00119     friend class QuadNode<T,RasterT>;
00120     friend class QuadNodeInternal<T,RasterT>;
00121     friend class QuadNodeLeaf<T,RasterT>;
00122 
00126     QuadNodeLeaf<T,RasterT>* getLeafForCell(const RasterCellIndex& cell) const;
00127     QuadNodeLeaf<T,RasterT>* getLeafForRect(const RasterRect& rect) const;
00128 
00137     void setNewLeaf(QuadNodeLeaf<T,RasterT>* leaf, bool multiCluster=false);
00138 
00139 
00141     std::list<QuadNodeLeaf<T,RasterT>*> allLeaves;
00142 
00143    }; /*}}} end of class Quadtree*/
00144 
00145 
00151    template <typename T, class RasterT>
00152    class QuadNode { /*{{{ class QuadNode*/
00153 
00154      public:
00155 
00157       QuadNode(Quadtree<T,RasterT>* _tree, QuadNodeInternal<T,RasterT>* _parent, RasterRect _r);
00158 
00159       virtual ~QuadNode();
00160 
00162       enum  NODE_TYPE {INTERNAL_NODE, LEAF_NODE, ROOT_NODE};
00163 
00165       bool contains(const RasterCellIndex& cell) const;
00166       bool contains(const RasterRect& _rect) const;
00167 
00168       QuadNodeInternal<T,RasterT>* getParent() const;
00169 
00170       Quadtree<T,RasterT>* getTree() const;
00171 
00176       void setParent(QuadNodeInternal<T,RasterT>* _parent);
00177 
00178       // abstract methods
00179       /*
00180       virtual int getxroot() const = 0;
00181       virtual int getyroot() const = 0;
00182       virtual int getxsize() const = 0;
00183       virtual int getysize() const = 0;
00184 
00185       virtual RasterRect getRect()const=0;
00186       */
00187       int getxroot() const { return rect.xtopleft; };
00188       int getyroot() const { return rect.ytopleft; };
00189       int getxsize() const { return rect.xsize(); }
00190       int getysize() const { return rect.ysize(); }
00191       RasterRect  getRect()   const { return rect; }
00192 
00193 
00194       virtual QuadNodeLeaf<T,RasterT>* getLeafForCell(const RasterCellIndex& cell) =0;
00195 
00196       virtual NODE_TYPE getType() const=0;
00197 
00198     protected:
00199 
00201       Quadtree<T,RasterT>* tree;
00202 
00204       QuadNodeInternal<T,RasterT>* parent;
00205 
00206       RasterRect rect;
00207 
00208   }; /* end of class QuadNode }}}*/
00209 
00214    template <typename T, class RasterT>
00215    class QuadNodeInternal : public QuadNode<T,RasterT> { /*{{{ class QuadNodeInternal*/
00216 
00217      private:
00218 
00222       bool divide( const RasterRect& _rect, bool xbalance=true, bool ybalance=true);
00223 
00225       //RasterRect rect;
00226      public:
00227 
00231       QuadNodeInternal(Quadtree<T,RasterT>* _tree, QuadNodeInternal<T,RasterT>* _parent, RasterRect rect, bool xbalance=true, bool ybalance=true);
00232 
00233       ~QuadNodeInternal();
00234 
00235       /*
00236       int getxroot() const;
00237       int getyroot() const;
00238       int getxsize() const;
00239       int getysize() const;
00240       RasterRect getRect() const;
00241       */
00242 
00243 
00244       typename QuadNode<T,RasterT>::NODE_TYPE getType() const;
00245 
00246       // get the cluster (tree leaf) for cell
00247       QuadNodeLeaf<T,RasterT>* getLeafForCell(const RasterCellIndex& cell);
00248 
00252       QuadNode<T,RasterT>* getChild(int index);
00253 
00254       // get the position (topleft,topright,bottomleft,bottoright) of a child
00255       int getChildPos(QuadNode<T,RasterT>* child);
00256 
00271       bool setChildren(QuadNode<T,RasterT>* S1, QuadNode<T,RasterT>* S2, QuadNode<T,RasterT>* S3, QuadNode<T,RasterT>* S4);
00272 
00273       bool setChild(QuadNode<T,RasterT>* child,int index);
00274 
00275      protected:
00276 
00286       //std::vector<QuadNode<T,RasterT>*> children;
00287       QuadNode<T,RasterT>* children[4];
00288 
00289       template<typename U, class URasterT>
00290       friend std::ostream& operator<< (std::ostream& out, const QuadNodeInternal<U,URasterT>& node);
00291 
00292    }; /* end of class QuadNodeInternal }}}*/
00293    
00299    template <typename T, class RasterT>
00300    class QuadNodeLeaf: public QuadNode<T,RasterT> { /*{{{ class QuadNodeLeaf */
00301      private:
00302 
00309       int nodePos;
00310 
00316       T data;
00317 
00324       //RasterRect rect;
00325 
00326       // adjacent clusters to this cluster represented by the quadtree leaf
00327       //std::vector<std::vector<QuadNodeLeaf*>> neighboors;
00328 
00329       //template<typename U, class URasterT>
00330       //friend std::ostream& operator<< (std::ostream& out, const QuadNodeLeaf<U,URasterT>& node);
00331 
00332     public:
00333 
00342       QuadNodeLeaf(Quadtree<T,RasterT>* _tree, QuadNodeInternal<T,RasterT>* _parent, int _nodePos, RasterRect _rect, T _data=RasterT::DEFAULT_DATA_VALUE());
00343 
00347       ~QuadNodeLeaf();
00348 
00349       /*
00350       int getxroot() const;
00351       int getyroot() const;
00352       int getxsize() const;
00353       int getysize() const;
00354       RasterRect getRect() const;
00355       */
00356 
00357       typename QuadNode<T,RasterT>::NODE_TYPE getType() const;
00358 
00359 
00360       // if the leaf contains only one cluster
00361       bool hasManyClusters() const;
00362 
00363       bool isAtomic() const;
00364 
00365       QuadNodeLeaf<T,RasterT>* getLeafForCell(const RasterCellIndex& cell);
00366 
00367       bool getClusterForCell(const RasterCellIndex& cell, RasterRect& cluster);
00368 
00369       // return the data of the cluster represented by the leaf
00370       T getData(const RasterCellIndex& clusterRoot);
00371 
00372   }; /* class QuadNodeLeaf }}}*/
00373 
00374    /**************************************************
00375     *                 IMPLEMENTATION                 *
00376     **************************************************/
00377 
00378   /*--------------------- Quadtree ---------------------- {{{*/
00379   template <typename T, class RasterT>
00380    Quadtree<T,RasterT>::Quadtree(RasterT* _raster, UNWISE_SIZE_DIVISION_POLITIC _uspolitic):
00381     TDecomposer<T,RasterT>(_raster),
00382     root(NULL),
00383     uspolitic(_uspolitic)
00384    { //{{{
00385 
00386     RasterRect rect = this->raster->getRasterRect();
00387     // check if the raster is homogene, if not decompose in quadtree
00388     if ((rect.xsize()>0)&&(rect.ysize()>0)) {
00389       if (this->raster->isHomogeneous(rect)==false) {
00390         root = new QuadNodeInternal<T,RasterT>(this,NULL,rect,true,true);
00391       } else {
00392         // We don't set any root cell
00393         root = NULL;
00394         this->decomp->setCluster(rect);
00395       }
00396     }
00397    } //}}}
00398 
00399   template <typename T, class RasterT>
00400   Quadtree<T,RasterT>::~Quadtree() {
00401     // Clear the leaves container
00402     allLeaves.clear();
00403     // Recursive deletion of all nodes
00404     delete root;
00405     // Clearing the clusters in the decomposition structure
00406     delete this->decomp;
00407   }
00408 
00409   template <typename T, class RasterT>
00410   QuadNodeInternal<T,RasterT>* Quadtree<T,RasterT>::getRootCell() const {
00411     return root;
00412   }
00413 
00414    template <typename T, class RasterT>
00415    std::list<QuadNodeLeaf<T,RasterT>*> Quadtree<T,RasterT>::getFullLeavesList() const {
00416     return allLeaves;
00417    }
00418 
00419    template <typename T, class RasterT>
00420    bool Quadtree<T,RasterT>::getClusterForCell(const RasterCellIndex& cell, RasterRect& cluster) const {
00421     QuadNodeLeaf<T,RasterT>* leaf = getLeafForCell(cell);
00422 
00423     if (leaf==NULL)
00424     {
00425       if (root == NULL)
00426       {
00427         // No root in tree means there were no need to decompose.
00428         // So directly returning the full Raster's rectangle.
00429         cluster = this->raster->getRasterRect();
00430         return true;
00431       } 
00432       // Else if root exist and no leaves are found there is a prob.
00433       return false;
00434     }
00435 
00436     // if leaf is not a cluster but a set of (1 or more) cluster of size (1,1)
00437     if (leaf->hasManyClusters())
00438       cluster.setRect(cell.i,cell.j,1,1);
00439     else
00440       cluster=leaf->getRect();
00441 
00442     return true;
00443    }
00444 
00448    template <typename T, class RasterT>
00449    bool Quadtree<T,RasterT>::getClusterForCell(const RasterCellIndex& cell, RasterCellIndex& clusterRoot) const {
00450     QuadNodeLeaf<T,RasterT>* leaf = getLeafForCell(cell);
00451 
00452     if (leaf==NULL)
00453       return false;
00454 
00455     // if leaf is not a cluster but a set of (1 or more) cluster of size (1,1)
00456     if (leaf->hasManyClusters())
00457       clusterRoot=cell;
00458     else
00459       clusterRoot.set(leaf->getRect().xroot(),leaf->getRect().yroot());
00460     return true;
00461    }
00462 
00466    template <typename T, class RasterT>
00467    bool Quadtree<T,RasterT>::getAdjacentClusters(const RasterCellIndex& root_cell, Decomp::SIDE side, std::list<RasterCellIndex>& clusters) const
00468    { //{{{
00469 
00470     DecompCluster* curCell;
00471     RasterCellIndex curCluster;
00472     int i,j;
00473     int clusterXSize = this->decomp->at(root_cell.i,root_cell.j)->xsize;
00474     int clusterYSize = this->decomp->at(root_cell.i,root_cell.j)->ysize;
00475     int curClusterXRoot, curClusterYRoot;
00476     bool curCellIsRootCluster;
00477 
00478     switch(side) {
00479     case Decomp::CLUSTER_TOP_SIDE:
00480       {
00481       int topSide_i=root_cell.i-1;
00482       if (topSide_i < this->raster->getxroot()) {
00483       break;
00484       }
00485       j=root_cell.j;
00486       while (j<root_cell.j+clusterYSize) {
00487         curCell=this->decomp->at(topSide_i,j);
00488         if (curCell != NULL) {
00489           curCellIsRootCluster=!curCell->isNegative();
00490           //curClusterXRoot=curCellIsRootCluster?topSide_i:(topSide_i+curCell->xsize+1);
00491           //curClusterYRoot=curCellIsRootCluster?j:(j+curCell->ysize+1);
00492           if (curCellIsRootCluster)
00493           {
00494             curClusterXRoot = topSide_i;
00495             curClusterYRoot = j;
00496             j += curCell->ysize;
00497           } else {
00498             curClusterXRoot = (topSide_i+curCell->xsize+1);
00499             curClusterYRoot = (j+curCell->ysize+1);
00500           }
00501           clusters.push_back(RasterCellIndex(curClusterXRoot,curClusterYRoot));
00502         }
00503         j++;
00504       }
00505       if (clusters.empty()) {
00506         getClusterForCell(RasterCellIndex(topSide_i,root_cell.j),curCluster);
00507         clusters.push_back(curCluster);
00508       }
00509       break;
00510       }
00511     case Decomp::CLUSTER_BOTTOM_SIDE:
00512       {
00513        int bottomSide_i=root_cell.i+clusterXSize;
00514        if (bottomSide_i<this->raster->getxroot()) {
00515         break;
00516        }
00517        j=root_cell.j;
00518        while (j<root_cell.j+clusterYSize) {
00519         curCell=this->decomp->at(bottomSide_i,j);
00520         if (curCell!=NULL) {
00521           curCellIsRootCluster=!curCell->isNegative();
00522           //curClusterXRoot=curCellIsRootCluster?bottomSide_i:(bottomSide_i+curCell->xsize+1);
00523           //curClusterYRoot=curCellIsRootCluster?j:(j+curCell->ysize+1);
00524           if (curCellIsRootCluster)
00525           {
00526             curClusterXRoot = bottomSide_i;
00527             curClusterYRoot = j;
00528            j += curCell->ysize;
00529           } else {
00530             curClusterXRoot = (bottomSide_i+curCell->xsize+1);
00531             curClusterYRoot = (j+curCell->ysize+1);
00532           }
00533 
00534           clusters.push_back(RasterCellIndex(curClusterXRoot,curClusterYRoot));
00535         }
00536         j++;
00537        }
00538        if (clusters.empty()) {
00539         getClusterForCell(RasterCellIndex(bottomSide_i,root_cell.j),curCluster);
00540         clusters.push_back(curCluster);
00541        }
00542        break;
00543       }
00544     case Decomp::CLUSTER_LEFT_SIDE:
00545     {
00546       int leftSide_j=root_cell.j-1;
00547       if (leftSide_j<this->raster->getyroot()) {
00548         break;
00549       }
00550       i=root_cell.i;
00551       while (i<root_cell.i+clusterXSize) {
00552         curCell=this->decomp->at(i,leftSide_j);
00553         if (curCell!=NULL) {
00554           curCellIsRootCluster=!curCell->isNegative();
00555           //curClusterXRoot=curCellIsRootCluster?i:(i+curCell->xsize+1);
00556           //curClusterYRoot=curCellIsRootCluster?leftSide_j:(leftSide_j+curCell->ysize+1);
00557           if (curCellIsRootCluster)
00558           {
00559             curClusterXRoot = i;
00560             curClusterYRoot = leftSide_j;
00561             i += curCell->xsize;
00562           } else {
00563             curClusterXRoot = (i+curCell->xsize+1);
00564             curClusterYRoot = (leftSide_j+curCell->ysize+1);
00565           }
00566 
00567           clusters.push_back(RasterCellIndex(curClusterXRoot,curClusterYRoot));
00568         }
00569         i++;
00570       }
00571       if (clusters.empty()) {
00572         getClusterForCell(RasterCellIndex(root_cell.i,leftSide_j),curCluster);
00573         clusters.push_back(curCluster);
00574       }
00575       break;
00576       }
00577     case Decomp::CLUSTER_RIGHT_SIDE:
00578     {
00579       int rightSide_j=root_cell.j+clusterYSize;
00580       if (rightSide_j<this->raster->getyroot()) {
00581         break;
00582       }
00583       i=root_cell.i;
00584       while (i<root_cell.i+clusterXSize) {
00585         curCell=this->decomp->at(i,rightSide_j);
00586         if (curCell!=NULL) {
00587           curCellIsRootCluster=!curCell->isNegative();
00588           //curClusterXRoot=curCellIsRootCluster?i:(i+curCell->xsize+1);
00589           //curClusterYRoot=curCellIsRootCluster?rightSide_j:(rightSide_j+curCell->ysize+1);
00590           if (curCellIsRootCluster)
00591           {
00592             curClusterXRoot = i;
00593             curClusterYRoot = rightSide_j;
00594             i += curCell->xsize;
00595           } else {
00596             curClusterXRoot = (i+curCell->xsize+1);
00597             curClusterYRoot = (rightSide_j+curCell->ysize+1);
00598           }
00599 
00600           clusters.push_back(RasterCellIndex(curClusterXRoot,curClusterYRoot));
00601         }
00602         i++;
00603       }
00604       if (clusters.empty()) {
00605         getClusterForCell(RasterCellIndex(root_cell.i,rightSide_j),curCluster);
00606         clusters.push_back(curCluster);
00607       }
00608       break;
00609     }
00610     default:
00611       return false;
00612     }
00613     return true;
00614    } //}}}
00615 
00619    template <typename T, class RasterT>
00620    T Quadtree<T,RasterT>::getData(const RasterRect& rect) const {
00621     // look for the leaf
00622     QuadNodeLeaf<T,RasterT>* leaf = getLeafForRect(rect);
00623     if (leaf==NULL)
00624       return RasterT::DEFAULT_DATA_VALUE();
00625     else
00626       return leaf->getData(RasterCellIndex(rect.xtopleft,rect.ytopleft));
00627    }
00628 
00632    template <typename T, class RasterT>
00633    T Quadtree<T,RasterT>::getData(const RasterCellIndex& cluster) const {
00634     // looking for the leaf that contains this cluster
00635     QuadNodeLeaf<T,RasterT>* leaf = getLeafForCell(cluster);
00636     if (leaf==NULL)
00637       return RasterT::DEFAULT_DATA_VALUE();
00638     else
00639       return leaf->getData(cluster);
00640    }
00641 
00645    template <typename T, class RasterT>
00646    QuadNodeLeaf<T,RasterT>* Quadtree<T,RasterT>::getLeafForCell(const RasterCellIndex& cell) const {
00647     if (root == NULL)
00648     { return NULL; }
00649 
00650     QuadNodeLeaf<T,RasterT>* cluster =  root->getLeafForCell(cell);
00651     if (cluster == NULL)
00652     {
00653       std::cout << "[Quadtree] cannot get cluster for cell " << cell.i << "," << cell.j << std::endl;
00654     }
00655 
00656     return cluster;
00657    }
00658 
00659    template <typename T, class RasterT>
00660    QuadNodeLeaf<T,RasterT>* Quadtree<T,RasterT>::getLeafForRect(const RasterRect& rect) const {
00661     if (root==NULL)
00662     { return NULL; }
00663 
00664     QuadNodeLeaf<T,RasterT>* cluster =  root->getLeafForCell(RasterCellIndex(rect.xtopleft,rect.ytopleft));
00665     if (cluster==NULL) {
00666       std::cout << "[Quadtree] cannot get cluster for rect " << rect << std::endl;
00667     }
00668 
00669     if (cluster->getRect().contains(rect)) {
00670       return cluster;
00671     } else {
00672       return NULL;
00673     }
00674    }
00675 
00676   template <typename T, class RasterT>
00677   void Quadtree<T,RasterT>::setNewLeaf(QuadNodeLeaf<T,RasterT>* leaf, bool multiCluster) {
00678     RasterRect leafRect = leaf->getRect();
00679     if (multiCluster) {
00680       // Case where the leaf is not a square and quadtree division can not be homogeneous anymore.
00681       for (int i = leafRect.xroot(); i <= leafRect.xend(); i++) {
00682         for (int j = leafRect.yroot();j <= leafRect.yend(); j++) {
00683           this->decomp->setLeafCluster(RasterRect(i,j,1,1));
00684         }
00685       }
00686     } else {
00687       // update the decomp structure in the nominal case
00688       this->decomp->setLeafCluster(leafRect);
00689     }
00690 
00692     allLeaves.push_front(leaf);
00693   }
00694 
00695   /*---}}}*/
00696   /*--------------------- QuadNode ---------------------- {{{*/
00697 
00698    template <typename T, class RasterT>
00699    QuadNode<T,RasterT>::QuadNode(Quadtree<T,RasterT>* _tree, QuadNodeInternal<T,RasterT>* _parent, RasterRect _rect):
00700     tree(_tree),
00701     parent(_parent),
00702     rect(_rect)
00703   {
00704   }
00705        
00706   template <typename T, class RasterT>
00707   QuadNode<T,RasterT>::~QuadNode() {}
00708 
00709   template <typename T, class RasterT>
00710   bool QuadNode<T,RasterT>::contains(const RasterCellIndex& cell) const {
00711     return rect.contains(cell);
00712   }
00713 
00714   template <typename T, class RasterT>
00715   bool QuadNode<T,RasterT>::contains(const RasterRect& _rect) const {
00716     return rect.contains(_rect);
00717   }
00718 
00719   template <typename T, class RasterT>
00720   QuadNodeInternal<T,RasterT>* QuadNode<T,RasterT>::getParent() const
00721   {
00722     return parent;
00723   }
00724 
00725   template <typename T, class RasterT>
00726   Quadtree<T,RasterT>* QuadNode<T,RasterT>::getTree() const {
00727     return tree;
00728   }
00729 
00734   template <typename T, class RasterT>
00735   void QuadNode<T,RasterT>::setParent(QuadNodeInternal<T,RasterT>* _parent) {
00736     parent=_parent;
00737   }
00738 
00739   /*---}}}*/
00740   /*--------------------- QuadNodeInternal ---------------------- {{{*/
00741 
00745    template <typename T, class RasterT>
00746    QuadNodeInternal<T,RasterT>::QuadNodeInternal(Quadtree<T,RasterT>* _tree, QuadNodeInternal<T,RasterT>* _parent, RasterRect _rect, bool xbalance, bool ybalance):
00747     QuadNode<T,RasterT>(_tree,_parent,_rect)
00748    { //{{{
00749     // resize the vector of children nodes
00750     //children.resize(4, NULL);
00751     children[0] = NULL;
00752     children[1] = NULL;
00753     children[2] = NULL;
00754     children[3] = NULL;
00755 
00756     // divide this internal node
00757     if (divide(this->rect, xbalance, ybalance)==false) {
00758       std::cout << "#EEE# [Quadtree] Error while dividing the node" << std::endl;
00759       return;
00760     }
00761 
00762    } //}}}
00763 
00764    template <typename T, class RasterT>
00765    QuadNodeInternal<T,RasterT>::~QuadNodeInternal() {
00766      for (int i =  Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL;
00767               i <= Quadtree<T,RasterT>::QUADTREE_BOTTOM_RIGHT_CELL;
00768           i++)
00769      {
00770        delete (children[i]);
00771      }
00772    }
00773 
00777   template <typename T, class RasterT>
00778   bool QuadNodeInternal<T,RasterT>::divide( const RasterRect& _rect, bool xbalance, bool ybalance) {//{{{
00779 
00780     // std::cout << "[Quadtree] Devide " << _rect << std::endl;
00781 
00782     int _xroot = _rect.xtopleft;
00783     int _yroot = _rect.ytopleft;
00784     int _xsize = _rect.xsize();
00785     int _ysize = _rect.ysize();
00786 
00787     if ((_xsize<=1)||(_ysize<=1)) {
00788       return false;
00789     }
00790 
00791     // divide to 4 children
00792     // x size is multiple of 2
00793     int topleft_xsize, topleft_ysize;
00794     if (_xsize%2==0) {
00795       topleft_xsize=_xsize/2;
00796     } else {
00797       if (((this->tree)->uspolitic ==  Quadtree<T,RasterT>::LEFTTOP)||(((this->tree)->uspolitic ==  Quadtree<T,RasterT>::BALANCE)&&(xbalance==true))) {
00798         topleft_xsize = (_xsize+1)/2;
00799       } else {
00800         topleft_xsize = (_xsize-1)/2;
00801       }
00802     }
00803     if (_ysize%2==0) {
00804       topleft_ysize=_ysize/2;
00805     } else {
00806       if ((this->tree->uspolitic ==  Quadtree<T,RasterT>::LEFTTOP)||((this->tree->uspolitic ==  Quadtree<T,RasterT>::BALANCE)&&(ybalance==true))) {
00807        topleft_ysize = (_ysize+1)/2;
00808       } else {
00809        topleft_ysize = (_ysize-1)/2;
00810       }
00811     }
00812 
00813     // create 4 children nodes
00814     // 0 - top left
00815     RasterRect rectTopLeft(_xroot, _yroot, topleft_xsize, topleft_ysize);
00816     if ((topleft_xsize<=1)||(topleft_ysize<=1)||(this->tree->raster->isHomogeneous(rectTopLeft))) {
00817       // create a leaf
00818        // std::cout << "[Quadtree] Create leaf " << rectTopLeft << std::endl;
00819       QuadNodeLeaf<T,RasterT>* topleft = new QuadNodeLeaf<T,RasterT>(this->tree,this,Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL,rectTopLeft);
00820        // std::cout << "[Quadtree] Create leaf created " << rectTopLeft << std::endl;
00821       setChild(topleft,Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL);
00822       // std::cout << "[Quadtree] Create leaf DONE" << rectTopLeft << std::endl;
00823     } else {
00824       // else create another QuadNodeInternal to continue the quadtree decomposition
00825       QuadNodeInternal<T,RasterT>* topleft = new QuadNodeInternal<T,RasterT>(this->tree,this,rectTopLeft,!xbalance,!ybalance);
00826       setChild(topleft,Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL);
00827     }
00828 
00829     // 1 - top right
00830     //RasterRect rectTopRight(_xroot,_yroot+topleft_ysize,topleft_xsize,_ysize-topleft_ysize);
00831     RasterRect rectTopRight(_xroot+topleft_xsize,_yroot, _xsize-topleft_xsize, topleft_ysize);
00832 
00833     if ((rectTopRight.xsize()<=1)||(rectTopRight.ysize()<=1)||(this->tree->raster->isHomogeneous(rectTopRight))) {
00834       QuadNodeLeaf<T,RasterT>* topright = new QuadNodeLeaf<T,RasterT>(this->tree,this,Quadtree<T,RasterT>::QUADTREE_TOP_RIGHT_CELL,rectTopRight);
00835       setChild(topright,Quadtree<T,RasterT>::QUADTREE_TOP_RIGHT_CELL);
00836     } else {
00837       QuadNodeInternal<T,RasterT>* topright = new QuadNodeInternal<T,RasterT>(this->tree,this,rectTopRight,!xbalance,!ybalance);
00838       setChild(topright,Quadtree<T,RasterT>::QUADTREE_TOP_RIGHT_CELL);
00839     }
00840 
00841     // 2 - bottom left
00842     //RasterRect rectBottomLeft(_xroot+topleft_xsize,_yroot,_xsize-topleft:_xsize,topleft_ysize);
00843     RasterRect rectBottomLeft(_xroot,_yroot+topleft_ysize, topleft_xsize, _ysize-topleft_ysize);
00844 
00845     if (( rectBottomLeft.xsize() <=1)||(rectBottomLeft.ysize() <= 1)||(this->tree->raster->isHomogeneous(rectBottomLeft))) {
00846       QuadNodeLeaf<T,RasterT>*  bottomleft = new QuadNodeLeaf<T,RasterT>(this->tree,this,Quadtree<T,RasterT>::QUADTREE_BOTTOM_LEFT_CELL,rectBottomLeft);
00847       setChild(bottomleft,Quadtree<T,RasterT>::QUADTREE_BOTTOM_LEFT_CELL);
00848     } else {
00849       QuadNodeInternal<T,RasterT>*  bottomleft = new QuadNodeInternal<T,RasterT>(this->tree,this,rectBottomLeft,!xbalance,!ybalance);
00850       setChild(bottomleft,Quadtree<T,RasterT>::QUADTREE_BOTTOM_LEFT_CELL);
00851     }
00852 
00853     // 3 - bottom right
00854     RasterRect rectBottomRight(_xroot+topleft_xsize,_yroot+topleft_ysize,_xsize-topleft_xsize,_ysize-topleft_ysize);
00855 
00856     if (( rectBottomRight.xsize()<=1)||(rectBottomRight.ysize()<=1)||(this->tree->raster->isHomogeneous(rectBottomRight))) {
00857       QuadNodeLeaf<T,RasterT>* bottomright = new QuadNodeLeaf<T,RasterT>(this->tree,this,Quadtree<T,RasterT>::QUADTREE_BOTTOM_RIGHT_CELL,rectBottomRight);
00858       setChild(bottomright,Quadtree<T,RasterT>::QUADTREE_BOTTOM_RIGHT_CELL);          
00859     } else {
00860       QuadNodeInternal<T,RasterT>* bottomright = new QuadNodeInternal<T,RasterT>(this->tree,this,rectBottomRight,!xbalance,!ybalance);
00861       setChild(bottomright,Quadtree<T,RasterT>::QUADTREE_BOTTOM_RIGHT_CELL);          
00862     }
00863 
00864     // std::cout << "[Quadtree] Devide end " << _rect << std::endl;
00865 
00866     return true;
00867 
00868    } //}}}
00869 /*
00870    template <typename T, class RasterT>
00871    int QuadNodeInternal<T,RasterT>::getxroot() const {
00872     return children[Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL]->getxroot();
00873    }
00874 
00875    template <typename T, class RasterT>
00876    int QuadNodeInternal<T,RasterT>::getyroot() const {
00877     return children[Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL]->getyroot();
00878    }
00879 
00880    template <typename T, class RasterT>
00881    int QuadNodeInternal<T,RasterT>::getxsize() const {
00882     return children[Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL]->getxsize() + children[Quadtree<T,RasterT>::QUADTREE_TOP_RIGHT_CELL]->getxsize();
00883    }
00884 
00885    template <typename T, class RasterT>
00886    int QuadNodeInternal<T,RasterT>::getysize() const {
00887     return children[Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL]->getysize() + children[Quadtree<T,RasterT>::QUADTREE_BOTTOM_LEFT_CELL]->getysize();
00888    }
00889 
00890   template <typename T, class RasterT>
00891   RasterRect QuadNodeInternal<T,RasterT>::getRect() const {
00892     return RasterRect(getxroot(),getyroot(),getxsize(),getysize());
00893   }
00894 */
00895 
00896    template <typename T, class RasterT>
00897    typename QuadNode<T,RasterT>::NODE_TYPE QuadNodeInternal<T,RasterT>::getType() const {
00898     return  QuadNode<T,RasterT>::INTERNAL_NODE;
00899    }
00900 
00901    // Get the cluster (tree leaf) for cell
00902    template <typename T, class RasterT>
00903    QuadNodeLeaf<T,RasterT>* QuadNodeInternal<T,RasterT>::getLeafForCell(const RasterCellIndex& cell) {
00904 
00905     if (children[Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL]->contains(cell)) {
00906       return children[Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL]->getLeafForCell(cell);
00907     }
00908 
00909     if (children[Quadtree<T,RasterT>::QUADTREE_TOP_RIGHT_CELL]->contains(cell)) {
00910       return children[Quadtree<T,RasterT>::QUADTREE_TOP_RIGHT_CELL]->getLeafForCell(cell);
00911     }
00912 
00913     if (children[Quadtree<T,RasterT>::QUADTREE_BOTTOM_LEFT_CELL]->contains(cell)) {
00914       return children[Quadtree<T,RasterT>::QUADTREE_BOTTOM_LEFT_CELL]->getLeafForCell(cell);
00915     }
00916 
00917     if (children[Quadtree<T,RasterT>::QUADTREE_BOTTOM_RIGHT_CELL]->contains(cell)) {
00918       return children[Quadtree<T,RasterT>::QUADTREE_BOTTOM_RIGHT_CELL]->getLeafForCell(cell);
00919     }
00920 
00921     // At this point the only possibility is that we are at the ROOT node
00922     // and thus we must return the root node as a leaf... tough !
00923     // For now a bad MEMORY solution is to create a leaf-copy of the root cell
00924     // on the fly.. on the fly means it is freed no where !
00925     //return (new QuadNodeLeaf<T,RasterT>(this->tree, this, 0, this->rect, this->tree->getRaster()->getData(cell) ));
00926     // This would be bad so we'd rather deal with it at a higher level
00927     return NULL;
00928    }
00929 
00933    template <typename T, class RasterT>
00934    QuadNode<T,RasterT>* QuadNodeInternal<T,RasterT>::getChild(int index) {
00935     if ((index < 0) || (index > 4)) {
00936       std::cout << "[Quadtree] Child index is invalid" << std::endl;
00937       return NULL;
00938     }
00939     return children[index];
00940    }
00941 
00942    // get the position (topleft,topright,bottomleft,bottoright) of a child
00943    template <typename T, class RasterT>
00944    int QuadNodeInternal<T,RasterT>::getChildPos(QuadNode<T,RasterT>* child) {
00945     for (int i=0;i<4;i++) {
00946       if (children[i]==child)
00947        return i;
00948     }
00949     return -1;
00950    }
00951 
00966    template <typename T, class RasterT>
00967    bool QuadNodeInternal<T,RasterT>::setChildren(QuadNode<T,RasterT>* S1, QuadNode<T,RasterT>* S2, QuadNode<T,RasterT>* S3, QuadNode<T,RasterT>* S4) {
00968     // free memory
00969     delete children[Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL];
00970     delete children[Quadtree<T,RasterT>::QUADTREE_TOP_RIGHT_CELL];
00971     delete children[Quadtree<T,RasterT>::QUADTREE_BOTTOM_LEFT_CELL];
00972     delete children[Quadtree<T,RasterT>::QUADTREE_BOTTOM_RIGHT_CELL];
00973 
00974     children[Quadtree<T,RasterT>::QUADTREE_TOP_LEFT_CELL]=S1;
00975     children[Quadtree<T,RasterT>::QUADTREE_TOP_RIGHT_CELL]=S2;
00976     children[Quadtree<T,RasterT>::QUADTREE_BOTTOM_LEFT_CELL]=S3;
00977     children[Quadtree<T,RasterT>::QUADTREE_BOTTOM_RIGHT_CELL]=S4;
00978     return true;
00979    }
00980 
00981    template <typename T, class RasterT>
00982    bool QuadNodeInternal<T,RasterT>::setChild(QuadNode<T,RasterT>* child,int index) {
00983     if (child == NULL) {
00984       std::cout << "[Quadtree] Internal node error, empty children" << std::endl;
00985       return false;
00986     } else if ((index<0)||(index>4)) {
00987       std::cout << "[Quadtree] Child index is invalid" << std::endl;       
00988       delete child;
00989         child = NULL;
00990       return false;
00991     } else {
00992       // free mem at corresponding index
00993       delete children[index];
00994       // set child
00995       children[index]=child;
00996     }
00997     return true;
00998    }
00999 
01000   /*}}}*/
01001   /*--------------------- QuadNodeLeaf ---------------------- {{{*/
01002 
01003   template <typename T, class RasterT>
01004   QuadNodeLeaf<T,RasterT>::QuadNodeLeaf(Quadtree<T,RasterT>* _tree, QuadNodeInternal<T,RasterT>* _parent, int _nodePos, RasterRect _rect, T _data):
01005     QuadNode<T,RasterT>(_tree,_parent, _rect),
01006     nodePos(_nodePos),
01007     data(_data)
01008   {
01009     // update decomp structure
01010     // if the leaf contains more than 1 cluster
01011     if (hasManyClusters())  {
01012       // update the decomp structure in the tree
01013       this->getTree()->setNewLeaf(this,true);
01014     } else {
01015       // update the decomp structure in the tree
01016       this->getTree()->setNewLeaf(this);
01017     }
01018 
01019     // std::cout << "[Leaf] update decomp done " << _rect << std::endl;
01020 
01021     if ((data==RasterT::DEFAULT_DATA_VALUE()) && (!isAtomic()) && (!(hasManyClusters()))) {
01022       // looking data for the cluster (non atomic)
01023       data = this->tree->getRaster()->getData(this->rect);
01024     }
01025 
01026     // std::cout << "[Leaf] get data done " << _rect << std::endl;
01027 
01028   }
01029 
01033    template <typename T, class RasterT>
01034    QuadNodeLeaf<T,RasterT>::~QuadNodeLeaf() {
01035 
01036    }
01037 
01038 /*
01039    template <typename T, class RasterT>
01040    int QuadNodeLeaf<T,RasterT>::getxroot() const {
01041     return rect.xtopleft;
01042    }
01043 
01044    template <typename T, class RasterT>
01045    int QuadNodeLeaf<T,RasterT>::getyroot() const {
01046     return rect.ytopleft;
01047    }
01048 
01049    template <typename T, class RasterT>
01050    int QuadNodeLeaf<T,RasterT>::getxsize() const {
01051     return rect.xsize();
01052    }
01053 
01054    template <typename T, class RasterT>
01055    int QuadNodeLeaf<T,RasterT>::getysize() const {
01056     return rect.ysize();
01057    }
01058 
01059    template <typename T, class RasterT>
01060    RasterRect QuadNodeLeaf<T,RasterT>::getRect() const {
01061     return RasterRect(getxroot(),getyroot(),getxsize(),getysize());
01062    }
01063 
01064 */
01065    template <typename T, class RasterT>
01066    typename QuadNode<T,RasterT>::NODE_TYPE QuadNodeLeaf<T,RasterT>::getType() const {
01067     return QuadNode<T,RasterT>::LEAF_NODE;
01068    }
01069 
01070    // if the leaf contains only one cluster
01071    template <typename T, class RasterT>
01072    bool QuadNodeLeaf<T,RasterT>::hasManyClusters() const {
01073     if (   ((this->rect.xsize()==1)&&(this->rect.ysize()>1))
01074        || ((this->rect.xsize()>1)&&(this->rect.ysize()==1)))
01075       return true;
01076     return false;
01077    }
01078 
01079    template <typename T, class RasterT>
01080    bool QuadNodeLeaf<T,RasterT>::isAtomic() const {
01081     return ((this->rect.xsize()==1)&&(this->rect.ysize()==1));
01082    }
01083 
01084   template <typename T, class RasterT>
01085   QuadNodeLeaf<T,RasterT>* QuadNodeLeaf<T,RasterT>::getLeafForCell(const RasterCellIndex& cell) {//{{{
01086     if (this->contains(cell)) {
01087       return this;
01088     } else {
01089       return NULL;
01090     }
01091   }//}}}
01092 
01093   template <typename T, class RasterT>
01094   bool QuadNodeLeaf<T,RasterT>::getClusterForCell(const RasterCellIndex& cell, RasterRect& cluster) { //{{{
01095     if (this->contains(cell)) {
01096       if (hasManyClusters()) {
01097         cluster.setRect(cell.i,cell.j,1,1);
01098       } else {
01099         cluster=this->rect;
01100       }
01101       return true;
01102     } else {
01103       return false;
01104     }
01105   }//}}}
01106 
01107    template <typename T, class RasterT>
01108    T QuadNodeLeaf<T,RasterT>::getData(const RasterCellIndex& clusterRoot) {//{{{
01109     // if the leaf has only one cluster => return the 0-index element inside the data vector
01110     // if not, find the element by the index computed from substraction of the wanted cluster root indices and the leaf cluster root indices
01111     // if the leaf cluster is one raster cell
01112     if (isAtomic()||hasManyClusters())
01113       return this->tree->getRaster()->getData(clusterRoot);
01114     else
01115       return data;
01116  } //}}}
01117 
01118    /*}}}*/
01119    /*------------------------- IO operators -----------------------{{{*/
01120 
01121     template <typename T, class RasterT>
01122     std::ostream& operator<< (std::ostream& out, const QuadNodeLeaf<T,RasterT>& node) {
01123       out << node.getRect() << std::endl;
01124       return out;
01125     }
01126 
01127     template <typename T, class RasterT>
01128     std::ostream& operator<< (std::ostream& out, const QuadNodeInternal<T,RasterT>& node) {
01129       out << node.getRect() << std::endl;
01130       return out;
01131     }
01132 
01133     template <typename T, typename RasterT>
01134     std::ostream& operator<< (std::ostream& out, const Quadtree<T,RasterT>& tree) { /*{{{*/
01135 
01136       std::list<QuadNodeLeaf<T,RasterT>*> leaves = tree.getFullLeavesList();
01137 
01138       // "typename" is required here to make the compiler understand that
01139       // "iterator" is not a static variable but really a type of STL list.
01140       typename std::list<QuadNodeLeaf<T,RasterT>* >::iterator  it;
01141 
01142       if (tree.getRootCell() != NULL)
01143       {
01144         out << "# Quadtree root node : " << tree.getRootCell() << std::endl;
01145         out << "# Quadtree root node : " << (tree.getRootCell())->getRect() << std::endl;
01146         out << "# Number of leaves : " << leaves.size() << std::endl;
01147         out << "# Xcenter    Ycenter   Xsize    Ysize" << std::endl;
01148 
01149         double xleft = 0.0;
01150         double ytop = 0.0;
01151         double xsize = 0.0;
01152         double ysize = 0.0;
01153 
01154         // Gnuplot header: some useful parameters
01155         out << "\tset key off" << std::endl;
01156 
01157         for (it = leaves.begin(); it != leaves.end(); ++it)
01158         {
01159           /* Prints each leaf's coordinates */
01160           xleft = (double)(*it)->getxroot();
01161           ytop  = -(double)(*it)->getyroot(); /* Minus to get into Raster origin on top left corner */
01162           xsize = (double)(*it)->getxsize();
01163           ysize = (double)(*it)->getysize();
01164 
01165           /* Converting to be gnuplot compatible.
01166            * Gnuplot needs : rectangle center & rectangle size
01167            * (or left down corner coord & top right corner coord)
01168            */
01169           xleft = xleft + xsize/2.0; /* xleft is to be considered as xcenter now */
01170           ytop  = ytop  - ysize/2.0; /* ytop  is to be considered as ycenter now */
01171 
01172           out << "\tset object rect center "<< xleft <<","<< ytop
01173               <<" size "<<xsize<<","<<ysize << " back fs empty border 3" << std::endl;
01174         }
01175 
01176         out << "\tplot [0:" << ((tree.getRootCell())->getRect()).xsize() << "] [-" << ((tree.getRootCell())->getRect()).ysize() << ":0] 0"
01177           << std::endl << "\tpause -1" << std::endl;
01178       } else {
01179         out << "# Quadtree has not root cell. Containing only 1 leaf." << std::endl;
01180         out << "# Number of leaves : " << leaves.size() << std::endl;
01181       }
01182 
01183       // Clearing the copied list
01184       leaves.clear();
01185       return out;
01186     } /*}}}*/
01187 
01188    /*--------------- end of IO Operators }}}*/
01189 
01190   } /* end of namespace lgl */
01191 } /* end of namespace jafar */
01192 
01193 #endif // _QUADTREE_HPP
01194 
01195 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:24 for Jafar by doxygen 1.7.6.1
LAAS-CNRS