diff --git a/utils/shapeindex/quadtree.hh b/utils/shapeindex/quadtree.hh index a5f301b34..76c876f9e 100644 --- a/utils/shapeindex/quadtree.hh +++ b/utils/shapeindex/quadtree.hh @@ -34,227 +34,254 @@ struct quadtree_node Envelope ext_; quadtree_node* children_[4]; quadtree_node(const Envelope& ext) - :ext_(ext) + : ext_(ext),data_() { memset(children_,0,sizeof(quadtree_node*)*4); } - ~quadtree_node() + + ~quadtree_node() { + for (int i=0;i<4;++i) + { + if (children_[i]) + { + delete children_[i],children_[i]=0; + } + } } + + int num_subnodes() const + { + int count=0; + for (int i=0;i<4;++i) + { + if (children_[i]) + { + ++count; + } + } + return count; + } }; template class quadtree { - private: - quadtree_node* root_; - const int maxdepth_; - const double ratio_; - public: - quadtree(const Envelope& extent,int maxdepth,double ratio) - : root_(new quadtree_node(extent)), - maxdepth_(maxdepth), - ratio_(ratio){} - ~quadtree() - { - destroy_node(root_); - } - void insert(const T& data,const Envelope& item_ext) - { - insert(data,item_ext,root_,maxdepth_); - } - int count() const - { - return count_nodes(root_); - } +private: + quadtree_node* root_; + const int maxdepth_; + const double ratio_; +public: + quadtree(const Envelope& extent,int maxdepth,double ratio) + : root_(new quadtree_node(extent)), + maxdepth_(maxdepth), + ratio_(ratio){} + ~quadtree() + { + if (root_) delete root_; + } + void insert(const T& data,const Envelope& item_ext) + { + insert(data,item_ext,root_,maxdepth_); + } + int count() const + { + return count_nodes(root_); + } + int count_items() const + { + int count=0; + count_items(root_,count); + return count; + } + void print() const + { + print(root_); + } + void trim() + { + trim_tree(root_); + } + + void write(std::ostream& out) + { + char header[16]; + memset(header,0,16); + header[0]='m'; + header[1]='a'; + header[2]='p'; + header[4]='n'; + header[5]='i'; + header[6]='k'; + out.write(header,16); + write_node(out,root_); + } - void print() const - { - print(root_); - } +private: - void write(std::ostream& out) - { - char header[16]; - memset(header,0,16); - header[0]='m'; - header[1]='a'; - header[2]='p'; - header[4]='n'; - header[5]='i'; - header[6]='k'; - out.write(header,16); - //trim_tree(root_);//TODO trim empty nodes - write_node(out,root_); - } + void trim_tree(quadtree_node*& node) + { + if (node) + { + for (int i=0;i<4;++i) + { + trim_tree(node->children_[i]); + } - private: + if (node->num_subnodes()==1 && node->data_.size()==0) + { + for (int i=0;i<4;++i) + { + if (node->children_[i]) + { + node=node->children_[i]; + break; + } + } + } + } + } - void destroy_node(quadtree_node* node) - { - if (node) - { - for (int i=0;i<4;++i) - { - destroy_node(node->children_[i]); - } - delete node,node=0; - } - } + int count_nodes(const quadtree_node* node) const + { + if (!node) + { + return 0; + } + else + { + int count = 1; + for (int i=0;i<4;++i) + { + count += count_nodes(node->children_[i]); + } + return count; + } + } - bool trim_tree(quadtree_node* node) - { + void count_items(const quadtree_node* node,int& count) const + { + if (node) + { + count += node->data_.size(); + for (int i=0;i<4;++i) + { + count_items(node->children_[i],count); + } + } + } - for (int i=0;i<4;++i) - { - if (node->children_[i] && trim_tree(node->children_[i])) - { - std::cout << "destroy"<children_[i]); - } - } + int subnode_offset(const quadtree_node* node) const + { + int offset=0; + for (int i=0;i<4;i++) + { + if (node->children_[i]) + { + offset +=sizeof(Envelope)+(node->children_[i]->data_.size()*sizeof(T))+3*sizeof(int); + offset +=subnode_offset(node->children_[i]); + } + } + return offset; + } - int num_shapes=node->data_.size(); - int num_subnodes=0; - if (num_shapes==0) - { - quadtree_node* subnode=0; - for (int i=0;i<4;++i) - { - if (node->children_[i]) - { - subnode=node->children_[i]; - ++num_subnodes; - } - } - if (num_subnodes==1) - { - node=subnode; // memory leak! - } - } - return (num_shapes == 0 && num_subnodes == 0); - } + void write_node(std::ostream& out,const quadtree_node* node) const + { + if (node) + { + int offset=subnode_offset(node); + int shape_count=node->data_.size(); + int recsize=sizeof(Envelope) + 3 * sizeof(int) + shape_count * sizeof(T); + char* node_record=new char[recsize]; + memset(node_record,0,recsize); + memcpy(node_record,&offset,4); + memcpy(node_record+4,&node->ext_,sizeof(Envelope)); + memcpy(node_record+36,&shape_count,4); + for (int i=0;idata_[i]),sizeof(T)); + } + int num_subnodes=0; + for (int i=0;i<4;++i) + { + if (node->children_[i]) + { + ++num_subnodes; + } + } + memcpy(node_record + 40 + shape_count * sizeof(T),&num_subnodes,4); + out.write(node_record,recsize); + delete [] node_record; - int count_nodes(const quadtree_node* node) const - { - if (!node) - { - return 0; - } - else - { - int count = 1; - for (int i=0;i<4;++i) - { - count += count_nodes(node->children_[i]); - } - return count; - } - } + for (int i=0;i<4;++i) + { + write_node(out,node->children_[i]); + } + } + } - int subnode_offset(const quadtree_node* node) const - { - int offset=0; - for (int i=0;i<4;i++) - { - if (node->children_[i]) - { - offset +=sizeof(Envelope)+(node->children_[i]->data_.size()*sizeof(T))+3*sizeof(int); - offset +=subnode_offset(node->children_[i]); - } - } - return offset; - } + void print(const quadtree_node* node,int level=0) const + { + if (node) + { + typename std::vector::const_iterator itr=node->data_.begin(); + std::string pad; + for (int i=0;iext_<data_.end()) + { + std::cout<<*itr<<" "; + ++itr; + } + std::cout<children_[i],level+4); + } + } + } - void write_node(std::ostream& out,const quadtree_node* node) const - { - if (node) - { - int offset=subnode_offset(node); - int shape_count=node->data_.size(); - int recsize=sizeof(Envelope) + 3 * sizeof(int) + shape_count * sizeof(T); - char* node_record=new char[recsize]; - memset(node_record,0,recsize); - memcpy(node_record,&offset,4); - memcpy(node_record+4,&node->ext_,sizeof(Envelope)); - memcpy(node_record+36,&shape_count,4); - for (int i=0;idata_[i]),sizeof(T)); - } - int num_subnodes=0; - for (int i=0;i<4;++i) - { - if (node->children_[i]) - ++num_subnodes; - } - memcpy(node_record + 40 + shape_count * sizeof(T),&num_subnodes,4); - out.write(node_record,recsize); - delete [] node_record; + void insert(const T& data,const Envelope& item_ext,quadtree_node* node,int maxdepth) + { + if (node && node->ext_.contains(item_ext)) + { + coord2d c=node->ext_.center(); - for (int i=0;i<4;++i) - { - write_node(out,node->children_[i]); - } - } - } + double width=node->ext_.width(); + double height=node->ext_.height(); - void print(const quadtree_node* node) const - { - if (node) - { - typename std::vector::const_iterator itr=node->data_.begin(); - std::cout<<"node extent:"<ext_<data_.end()) - { - std::cout<<*itr<<" "; - ++itr; - } - std::cout<children_[i]); - } - } - } + double lox=node->ext_.minx(); + double loy=node->ext_.miny(); + double hix=node->ext_.maxx(); + double hiy=node->ext_.maxy(); - void insert(const T& data,const Envelope& item_ext,quadtree_node* node,int maxdepth) - { - if (node && node->ext_.contains(item_ext)) - { - coord2d c=node->ext_.center(); + Envelope ext[4]; + ext[0]=Envelope(lox,loy,lox + width * ratio_,loy + height * ratio_); + ext[1]=Envelope(hix - width * ratio_,loy,hix,loy + height * ratio_); + ext[2]=Envelope(lox,hiy - height*ratio_,lox + width * ratio_,hiy); + ext[3]=Envelope(hix - width * ratio_,hiy - height*ratio_,hix,hiy); - double width=node->ext_.width(); - double height=node->ext_.height(); - - double lox=node->ext_.minx(); - double loy=node->ext_.miny(); - double hix=node->ext_.maxx(); - double hiy=node->ext_.maxy(); - - Envelope ext[4]; - ext[0]=Envelope(lox,loy,lox + width * ratio_,loy + height * ratio_); - ext[1]=Envelope(hix - width * ratio_,loy,hix,loy + height * ratio_); - ext[2]=Envelope(lox,hiy - height*ratio_,lox + width * ratio_,hiy); - ext[3]=Envelope(hix - width * ratio_,hiy - height*ratio_,hix,hiy); - - if (maxdepth > 1) - { - for (int i=0;i<4;++i) - { - if (ext[i].contains(item_ext)) - { - if (!node->children_[i]) - { - node->children_[i]=new quadtree_node(ext[i]); - } - insert(data,item_ext,node->children_[i],maxdepth-1); - return; - } - } - } - node->data_.push_back(data); - } - } + if (maxdepth > 1) + { + for (int i=0;i<4;++i) + { + if (ext[i].contains(item_ext)) + { + if (!node->children_[i]) + { + node->children_[i]=new quadtree_node(ext[i]); + } + insert(data,item_ext,node->children_[i],maxdepth-1); + return; + } + } + } + node->data_.push_back(data); + } + } }; #endif //QUADTREE_HH diff --git a/utils/shapeindex/shapeindex.cc b/utils/shapeindex/shapeindex.cc index a9728c97c..0137a4f1a 100644 --- a/utils/shapeindex/shapeindex.cc +++ b/utils/shapeindex/shapeindex.cc @@ -109,7 +109,8 @@ int main (int argc,char** argv) { arguments.ratio = DEFAULT_RATIO; argp_parse(&argp, argc, argv, 0, 0, &arguments); - std::cout<<"start processing "<