00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef KORTREE_H
00023 #define KORTREE_H
00024
00025 #include <QPair>
00026 #include <QMap>
00027 #include <QList>
00028 #include <QVector>
00029 #include <QDebug>
00030 #include <QPointF>
00031 #include <QRectF>
00032 #include <QPainter>
00033 #include <qvarlengtharray.h>
00034
00044 template <typename T>
00045 class KoRTree
00046 {
00047 public:
00054 KoRTree( int capacity, int minimum );
00055
00059 virtual ~KoRTree();
00060
00070 virtual void insert( const QRectF& bb, const T& data );
00071
00080 void remove( const T& data );
00081
00090 virtual QList<T> intersects( const QRectF& rect ) const;
00091
00100 QList<T> contains( const QPointF &point ) const;
00101
00108 QList<QRectF> keys() const;
00109
00116 QList<T> values() const;
00117
00118 #ifdef KOFFICE_RTREE_DEBUG
00119
00124 void paint( QPainter & p ) const;
00125
00129 void debug() const;
00130 #endif
00131
00132 protected:
00133 class NoneLeafNode;
00134 class LeafNode;
00135
00136 class Node
00137 {
00138 public:
00139 #ifdef KOFFICE_RTREE_DEBUG
00140 static int nodeIdCnt;
00141 #endif
00142 Node( int capacity, int level, Node * parent );
00143 virtual ~Node() {}
00144
00145 virtual void remove( int index );
00146
00147 virtual void move( Node * node, int index ) = 0;
00148
00149 virtual LeafNode * chooseLeaf( const QRectF& bb ) = 0;
00150 virtual NoneLeafNode * chooseNode( const QRectF& bb, int level ) = 0;
00151
00152 virtual void intersects( const QRectF& rect, QMap<int,T> & result ) const = 0;
00153 virtual void contains( const QPointF & point, QMap<int,T> & result ) const = 0;
00154
00155 virtual void keys( QList<QRectF> & result ) const = 0;
00156 virtual void values( QMap<int,T> & result ) const = 0;
00157
00158 virtual Node * parent() const { return m_parent; }
00159 virtual void setParent( Node * parent ) { m_parent = parent; }
00160
00161 virtual int childCount() const { return m_counter; }
00162
00163 virtual const QRectF& boundingBox() const { return m_boundingBox; }
00164 virtual void updateBoundingBox();
00165
00166 virtual const QRectF& childBoundingBox( int index ) const { return m_childBoundingBox[index]; }
00167 virtual void setChildBoundingBox( int index, const QRectF& rect ) { m_childBoundingBox[index] = rect; }
00168
00169 virtual void clear();
00170 virtual bool isRoot() const { return m_parent == 0; }
00171 virtual bool isLeaf() const { return false; }
00172
00173 virtual int place() const { return m_place; }
00174 virtual void setPlace( int place ) { m_place = place; }
00175
00176 virtual int level() const { return m_level; }
00177 virtual void setLevel( int level ) { m_level = level; }
00178
00179 #ifdef KOFFICE_RTREE_DEBUG
00180 virtual int nodeId() const { return m_nodeId; }
00181
00182 virtual void paint( QPainter & p, int level ) const = 0;
00183 virtual void debug( QString line ) const = 0;
00184
00185 protected:
00186 static QColor levelColor[];
00187 virtual void paintRect( QPainter & p, int level ) const;
00188 #endif
00189 protected:
00190 Node * m_parent;
00191 QRectF m_boundingBox;
00192 QVector<QRectF> m_childBoundingBox;
00193 int m_counter;
00194
00195 int m_place;
00196 #ifdef KOFFICE_RTREE_DEBUG
00197 int m_nodeId;
00198 #endif
00199 int m_level;
00200 };
00201
00202 class NoneLeafNode : virtual public Node
00203 {
00204 public:
00205 NoneLeafNode( int capacity, int level, Node * parent );
00206 virtual ~NoneLeafNode() {}
00207
00208 virtual void insert( const QRectF& bb, Node * data );
00209 virtual void remove( int index );
00210 virtual void move( Node * node, int index );
00211
00212 virtual LeafNode * chooseLeaf( const QRectF& bb );
00213 virtual NoneLeafNode * chooseNode( const QRectF& bb, int level );
00214
00215 virtual void intersects( const QRectF& rect, QMap<int,T> & result ) const;
00216 virtual void contains( const QPointF & point, QMap<int,T> & result ) const;
00217
00218 virtual void keys( QList<QRectF> & result ) const;
00219 virtual void values( QMap<int,T> & result ) const;
00220
00221 virtual Node * getNode( int index ) const;
00222
00223 #ifdef KOFFICE_RTREE_DEBUG
00224 virtual void paint( QPainter & p, int level ) const;
00225 virtual void debug( QString line ) const;
00226 #endif
00227 protected:
00228 virtual Node * getLeastEnlargement( const QRectF& bb ) const;
00229
00230 QVector<Node *> m_childs;
00231 };
00232
00233 class LeafNode : virtual public Node
00234 {
00235 public:
00236 static int dataIdCounter;
00237
00238 LeafNode( int capacity, int level, Node * parent );
00239 virtual ~LeafNode() {}
00240
00241 virtual void insert( const QRectF& bb, const T& data, int id );
00242 virtual void remove( int index );
00243 virtual void remove( const T& data );
00244 virtual void move( Node * node, int index );
00245
00246 virtual LeafNode * chooseLeaf( const QRectF& bb );
00247 virtual NoneLeafNode * chooseNode( const QRectF& bb, int level );
00248
00249 virtual void intersects( const QRectF& rect, QMap<int,T> & result ) const;
00250 virtual void contains( const QPointF & point, QMap<int,T> & result ) const;
00251
00252 virtual void keys( QList<QRectF> & result ) const;
00253 virtual void values( QMap<int,T> & result ) const;
00254
00255 virtual const T& getData( int index ) const;
00256 virtual int getDataId( int index ) const;
00257
00258 virtual bool isLeaf() const { return true; }
00259
00260 #ifdef KOFFICE_RTREE_DEBUG
00261 virtual void debug( QString line ) const;
00262 virtual void paint( QPainter & p, int level ) const;
00263 #endif
00264 protected:
00265 QVector<T> m_data;
00266 QVector<int> m_dataIds;
00267 };
00268
00269
00270 virtual LeafNode* createLeafNode( int capacity, int level, Node * parent )
00271 {
00272 return new LeafNode( capacity, level, parent );
00273 }
00274 virtual NoneLeafNode* createNoneLeafNode( int capacity, int level, Node * parent )
00275 {
00276 return new NoneLeafNode( capacity, level, parent );
00277 }
00278
00279
00280 QPair<Node *, Node *> splitNode( Node * node );
00281 QPair<int, int> pickSeeds( Node * node );
00282 QPair<int, int> pickNext( Node * node, QVector<bool> & marker, Node * group1, Node * group2 );
00283 void adjustTree( Node * node1, Node * node2 );
00284 void insertHelper( const QRectF& bb, const T& data, int id );
00285
00286
00287 void insert( Node * node );
00288 void condenseTree( Node * node, QVector<Node *> & reinsert );
00289
00290 int m_capacity;
00291 int m_minimum;
00292 Node * m_root;
00293 QMap<T, LeafNode *> m_leafMap;
00294 };
00295
00296 template <typename T>
00297 KoRTree<T>::KoRTree( int capacity, int minimum )
00298 : m_capacity( capacity )
00299 , m_minimum( minimum )
00300 , m_root( createLeafNode( m_capacity + 1, 0, 0 ) )
00301 {
00302 if ( minimum > capacity / 2 )
00303 qFatal( "KoRTree::KoRTree minimum can be maximal capacity/2");
00304
00305 }
00306
00307 template <typename T>
00308 KoRTree<T>::~KoRTree()
00309 {
00310 delete m_root;
00311 }
00312
00313 template <typename T>
00314 void KoRTree<T>::insert( const QRectF& bb, const T& data )
00315 {
00316 insertHelper( bb, data, LeafNode::dataIdCounter++ );
00317 }
00318
00319 template <typename T>
00320 void KoRTree<T>::insertHelper( const QRectF& bb, const T& data, int id )
00321 {
00322 QRectF nbb( bb.normalized() );
00323
00324 if ( nbb.isNull() )
00325 {
00326 nbb.setWidth(0.0001);
00327 nbb.setHeight(0.0001);
00328 qWarning( "KoRTree::insert bouningBox isNull setting size to (%fx%f) ", nbb.width(), nbb.height() );
00329 }
00330
00331 LeafNode * leaf = m_root->chooseLeaf( nbb );
00332
00333
00334 if ( leaf->childCount() < m_capacity )
00335 {
00336 leaf->insert( nbb, data, id );
00337 m_leafMap[data] = leaf;
00338 adjustTree( leaf, 0 );
00339 }
00340 else
00341 {
00342 leaf->insert( nbb, data, id );
00343 m_leafMap[data] = leaf;
00344 QPair<Node *, Node *> newNodes = splitNode( leaf );
00345 LeafNode * l = dynamic_cast<LeafNode *>(newNodes.first);
00346 if ( l )
00347 for ( int i = 0; i < l->childCount(); ++i )
00348 m_leafMap[l->getData(i)] = l;
00349 l = dynamic_cast<LeafNode *>(newNodes.second);
00350 if ( l )
00351 for ( int i = 0; i < l->childCount(); ++i )
00352 m_leafMap[l->getData(i)] = l;
00353
00354 adjustTree( newNodes.first, newNodes.second );
00355 }
00356 }
00357
00358 template <typename T>
00359 void KoRTree<T>::insert( Node * node )
00360 {
00361 if ( node->level() == m_root->level() )
00362 {
00363 adjustTree( m_root, node );
00364 }
00365 else
00366 {
00367 QRectF bb( node->boundingBox() );
00368 NoneLeafNode * newParent = m_root->chooseNode( bb, node->level() + 1 );
00369
00370 newParent->insert( bb, node );
00371
00372 QPair<Node *, Node *> newNodes( node, 0 );
00373 if ( newParent->childCount() > m_capacity )
00374 {
00375 newNodes = splitNode( newParent );
00376 }
00377 adjustTree( newNodes.first, newNodes.second );
00378 }
00379 }
00380
00381 template <typename T>
00382 void KoRTree<T>::remove( const T&data )
00383 {
00384
00385 LeafNode * leaf = m_leafMap[data];
00386 if ( leaf == 0 )
00387 {
00388 qWarning( "KoRTree<T>::remove( const T&data) data not found" );
00389 return;
00390 }
00391 m_leafMap.remove(data);
00392 leaf->remove( data );
00393
00394 QVector<Node *> reinsert;
00395 condenseTree( leaf, reinsert );
00396
00397 for ( int i = 0; i < reinsert.size(); ++i )
00398 {
00399 if ( reinsert[i]->isLeaf() )
00400 {
00401 LeafNode * leaf = dynamic_cast<LeafNode *>( reinsert[i] );
00402 for ( int j = 0; j < leaf->childCount(); ++j )
00403 {
00404 insertHelper( leaf->childBoundingBox(j), leaf->getData( j ), leaf->getDataId( j ) );
00405 }
00406 delete leaf;
00407 }
00408 else
00409 {
00410 NoneLeafNode * node = dynamic_cast<NoneLeafNode *>( reinsert[i] );
00411 for ( int j = 0; j < node->childCount(); ++j )
00412 {
00413 insert( node->getNode( j ) );
00414 }
00415 delete node;
00416 }
00417 }
00418 }
00419
00420 template <typename T>
00421 QList<T> KoRTree<T>::intersects( const QRectF& rect ) const
00422 {
00423 QMap<int,T> found;
00424 m_root->intersects( rect, found );
00425 return found.values();
00426 }
00427
00428 template <typename T>
00429 QList<T> KoRTree<T>::contains( const QPointF &point ) const
00430 {
00431 QMap<int,T> found;
00432 m_root->contains( point, found );
00433 return found.values();
00434 }
00435
00436 template <typename T>
00437 QList<QRectF> KoRTree<T>::keys() const
00438 {
00439 QList<QRectF> found;
00440 m_root->keys( found );
00441 return found;
00442 }
00443
00444 template <typename T>
00445 QList<T> KoRTree<T>::values() const
00446 {
00447 QMap<int,T> found;
00448 m_root->values( found );
00449 return found.values();
00450 }
00451
00452 #ifdef KOFFICE_RTREE_DEBUG
00453 template <typename T>
00454 void KoRTree<T>::paint( QPainter & p ) const
00455 {
00456 if ( m_root )
00457 {
00458 m_root->paint( p, 0 );
00459 }
00460 }
00461
00462 template <typename T>
00463 void KoRTree<T>::debug() const
00464 {
00465 QString prefix( "" );
00466 m_root->debug( prefix );
00467 }
00468 #endif
00469
00470 template <typename T>
00471 QPair< typename KoRTree<T>::Node*, typename KoRTree<T>::Node* > KoRTree<T>::splitNode( KoRTree<T>::Node* node )
00472 {
00473
00474 Node * n1;
00475 Node * n2;
00476 if ( node->isLeaf() )
00477 {
00478 n1 = createLeafNode( m_capacity + 1, node->level(), node->parent() );
00479 n2 = createLeafNode( m_capacity + 1, node->level(), node->parent() );
00480 }
00481 else
00482 {
00483 n1 = createNoneLeafNode( m_capacity + 1, node->level(), node->parent() );
00484 n2 = createNoneLeafNode( m_capacity + 1, node->level(), node->parent() );
00485 }
00486
00487
00488
00489 QVector<bool> marker( m_capacity + 1 );
00490
00491 QPair<int, int> seeds( pickSeeds( node ) );
00492
00493 n1->move( node, seeds.first );
00494 n2->move( node, seeds.second );
00495
00496 marker[seeds.first] = true;
00497 marker[seeds.second] = true;
00498
00499
00500
00501 int remaining = m_capacity + 1 - 2;
00502
00503 while ( remaining > 0 )
00504 {
00505 if ( m_minimum - n1->childCount() == remaining )
00506 {
00507 for ( int i = 0; i < m_capacity + 1; ++i )
00508 {
00509 if ( !marker[i] )
00510 {
00511 n1->move( node, i );
00512 --remaining;
00513 }
00514 }
00515 }
00516 else if ( m_minimum - n2->childCount() == remaining )
00517 {
00518 for ( int i = 0; i < m_capacity + 1; ++i )
00519 {
00520 if ( !marker[i] )
00521 {
00522 n2->move( node, i );
00523 --remaining;
00524 }
00525 }
00526 }
00527 else
00528 {
00529 QPair<int, int> next( pickNext(node, marker, n1, n2 ) );
00530
00531 if ( next.first == 0 )
00532 {
00533 n1->move( node, next.second );
00534 }
00535 else
00536 {
00537 n2->move( node, next.second );
00538 }
00539 --remaining;
00540 }
00541 }
00542 Q_ASSERT( n1->childCount() + n2->childCount() == node->childCount() );
00543
00544
00545
00546 node->clear();
00547 for ( int i = 0; i < n1->childCount(); ++i )
00548 {
00549 node->move( n1, i );
00550 }
00551
00552
00553 delete n1;
00554 return qMakePair( node, n2 );
00555 }
00556
00557 template <typename T>
00558 QPair<int, int> KoRTree<T>::pickSeeds( Node *node )
00559 {
00560 int s1 = 0;
00561 int s2 = 1;
00562 double max = 0;
00563 for ( int i = 0; i < m_capacity + 1; ++i )
00564 {
00565 for ( int j = 0; j < m_capacity + 1; ++j )
00566 {
00567 if ( i !=j )
00568 {
00569 QRectF bb1( node->childBoundingBox(i) );
00570 QRectF bb2( node->childBoundingBox(j) );
00571 QRectF comp( node->childBoundingBox(i).unite( node->childBoundingBox(j) ) );
00572 double area = comp.width() * comp.height() - bb1.width() * bb1.height() - bb2.width() * bb2.height();
00573
00574 if ( area > max )
00575 {
00576 max = area;
00577 s1 = i;
00578 s2 = j;
00579 }
00580 }
00581 }
00582 }
00583 return qMakePair( s1, s2 );
00584 }
00585
00586 template <typename T>
00587 QPair<int, int> KoRTree<T>::pickNext( Node * node, QVector<bool> & marker, Node * group1, Node * group2 )
00588 {
00589
00590 double max = -1.0;
00591 int select = 0;
00592 int group = 0;
00593 for ( int i = 0; i < m_capacity + 1; ++i )
00594 {
00595 if ( marker[i] == false )
00596 {
00597 QRectF bb1 = group1->boundingBox().unite( node->childBoundingBox(i) );
00598 QRectF bb2 = group2->boundingBox().unite( node->childBoundingBox(i) );
00599 double d1 = bb1.width() * bb1.height() - group1->boundingBox().width() * group1->boundingBox().height();
00600 double d2 = bb2.width() * bb2.height() - group2->boundingBox().width() * group2->boundingBox().height();
00601 double diff = qAbs( d1 - d2 );
00602
00603 if ( diff > max )
00604 {
00605 max = diff;
00606 select = i;
00607
00608 if ( qAbs( d1 ) > qAbs( d2 ) )
00609 {
00610 group = 1;
00611 }
00612 else
00613 {
00614 group = 0;
00615 }
00616
00617 }
00618 }
00619 }
00620 marker[select] = true;
00621 return qMakePair( group, select );
00622 }
00623
00624 template <typename T>
00625 void KoRTree<T>::adjustTree( Node *node1, Node *node2 )
00626 {
00627
00628 if ( node1->isRoot() )
00629 {
00630
00631 if ( node2 )
00632 {
00633 NoneLeafNode * newRoot = createNoneLeafNode( m_capacity + 1, node1->level() + 1, 0 );
00634 newRoot->insert( node1->boundingBox(), node1 );
00635 newRoot->insert( node2->boundingBox(), node2 );
00636 m_root = newRoot;
00637
00638 }
00639 }
00640 else
00641 {
00642 NoneLeafNode * parent = dynamic_cast<NoneLeafNode *>( node1->parent() );
00643
00644 parent->setChildBoundingBox( node1->place(), node1->boundingBox() );
00645 parent->updateBoundingBox();
00646
00647
00648 if ( !node2 )
00649 {
00650
00651 adjustTree( parent, 0 );
00652 }
00653 else
00654 {
00655 if ( parent->childCount() < m_capacity )
00656 {
00657
00658 parent->insert( node2->boundingBox(), node2 );
00659 adjustTree( parent, 0 );
00660 }
00661 else
00662 {
00663
00664 parent->insert( node2->boundingBox(), node2 );
00665 QPair<Node *, Node *> newNodes = splitNode( parent );
00666 adjustTree( newNodes.first, newNodes.second );
00667 }
00668 }
00669 }
00670 }
00671
00672 template <typename T>
00673 void KoRTree<T>::condenseTree( Node *node, QVector<Node*> & reinsert )
00674 {
00675
00676 if ( !node->isRoot() )
00677 {
00678 Node * parent = node->parent();
00679
00680
00681 if ( node->childCount() < m_minimum )
00682 {
00683
00684 parent->remove( node->place() );
00685 reinsert.push_back( node );
00686 }
00687 else
00688 {
00689
00690 parent->setChildBoundingBox( node->place(), node->boundingBox() );
00691 parent->updateBoundingBox();
00692 }
00693 condenseTree( parent, reinsert );
00694 }
00695 else
00696 {
00697
00698 if ( node->childCount() == 1 && !node->isLeaf() )
00699 {
00700
00701 NoneLeafNode * n = dynamic_cast<NoneLeafNode *>( node );
00702 if ( n )
00703 {
00704 Node * kid = n->getNode( 0 );
00705 delete m_root;
00706 m_root = kid;
00707 m_root->setParent( 0 );
00708
00709 }
00710 else
00711 {
00712 qFatal( "KoRTree::condenseTree cast to NoneLeafNode failed" );
00713 }
00714 }
00715 }
00716
00717 }
00718
00719 #ifdef KOFFICE_RTREE_DEBUG
00720 template <typename T>
00721 QColor KoRTree<T>::Node::levelColor[] = {
00722 QColor(Qt::green),
00723 QColor(Qt::red),
00724 QColor(Qt::cyan),
00725 QColor(Qt::magenta),
00726 QColor(Qt::yellow),
00727 };
00728
00729 template <class T>
00730 int KoRTree<T>::Node::nodeIdCnt = 0;
00731 #endif
00732
00733 template <typename T>
00734 KoRTree<T>::Node::Node( int capacity, int level, Node * parent )
00735 : m_parent( parent )
00736 , m_childBoundingBox( capacity )
00737 , m_counter( 0 )
00738 #ifdef KOFFICE_RTREE_DEBUG
00739 , m_nodeId( nodeIdCnt++ )
00740 #endif
00741 , m_level( level )
00742 {
00743 }
00744
00745 template <typename T>
00746 void KoRTree<T>::Node::remove( int index )
00747 {
00748 for ( int i = index + 1; i < m_counter; ++i )
00749 {
00750 m_childBoundingBox[i-1] = m_childBoundingBox[i];
00751 }
00752 --m_counter;
00753 updateBoundingBox();
00754 }
00755
00756 template <typename T>
00757 void KoRTree<T>::Node::updateBoundingBox()
00758 {
00759 QRectF oldBB = m_boundingBox;
00760 m_boundingBox = QRectF();
00761 for ( int i = 0; i < m_counter; ++i )
00762 {
00763 m_boundingBox = m_boundingBox.unite( m_childBoundingBox[i] );
00764 }
00765 }
00766
00767 template <typename T>
00768 void KoRTree<T>::Node::clear()
00769 {
00770 m_counter = 0;
00771 m_boundingBox = QRectF();
00772 }
00773
00774 #ifdef KOFFICE_RTREE_DEBUG
00775 template <typename T>
00776 void KoRTree<T>::Node::paintRect( QPainter & p, int level ) const
00777 {
00778 QColor c( Qt::black );
00779 if ( level < int( sizeof(levelColor) / sizeof(QColor) ) )
00780 {
00781 c = levelColor[level];
00782 }
00783
00784 QPen pen( c );;
00785 p.setPen( pen );
00786
00787 QRectF bbdraw( this->m_boundingBox );
00788 bbdraw.adjust( level * 2, level * 2, -level * 2, -level * 2 );
00789 p.drawRect( bbdraw );
00790 }
00791 #endif
00792
00793 template <typename T>
00794 KoRTree<T>::NoneLeafNode::NoneLeafNode( int capacity, int level, Node * parent )
00795 : Node( capacity, level, parent )
00796 , m_childs( capacity )
00797 {
00798 }
00799
00800 template <typename T>
00801 void KoRTree<T>::NoneLeafNode::insert( const QRectF& bb, Node * data )
00802 {
00803 m_childs[this->m_counter] = data;
00804 data->setPlace( this->m_counter );
00805 data->setParent( this );
00806 this->m_childBoundingBox[this->m_counter] = bb;
00807 this->m_boundingBox = this->m_boundingBox.unite( bb );
00808
00809 ++this->m_counter;
00810 }
00811
00812 template <typename T>
00813 void KoRTree<T>::NoneLeafNode::remove( int index )
00814 {
00815 for ( int i = index + 1; i < this->m_counter; ++i )
00816 {
00817 m_childs[i-1] = m_childs[i];
00818 m_childs[i-1]->setPlace(i-1);
00819 }
00820 Node::remove( index );
00821 }
00822
00823 template <typename T>
00824 void KoRTree<T>::NoneLeafNode::move( Node * node, int index )
00825 {
00826
00827 NoneLeafNode * n = dynamic_cast<NoneLeafNode *>( node );
00828 if ( n )
00829 {
00830 QRectF bb = n->childBoundingBox( index );
00831 insert( bb, n->getNode( index ) );
00832 }
00833 }
00834
00835 template <typename T>
00836 typename KoRTree<T>::LeafNode * KoRTree<T>::NoneLeafNode::chooseLeaf( const QRectF& bb )
00837 {
00838 return getLeastEnlargement( bb )->chooseLeaf( bb );
00839 }
00840
00841 template <typename T>
00842 typename KoRTree<T>::NoneLeafNode * KoRTree<T>::NoneLeafNode::chooseNode( const QRectF& bb, int level )
00843 {
00844 if ( this->m_level > level )
00845 {
00846 return getLeastEnlargement( bb )->chooseNode( bb, level );
00847 }
00848 else
00849 {
00850 return this;
00851 }
00852
00853 }
00854
00855 template <typename T>
00856 void KoRTree<T>::NoneLeafNode::intersects( const QRectF& rect, QMap<int,T> & result ) const
00857 {
00858 for ( int i = 0; i < this->m_counter; ++i )
00859 {
00860 if ( this->m_childBoundingBox[i].intersects( rect ) )
00861 {
00862 m_childs[i]->intersects( rect, result );
00863 }
00864 }
00865 }
00866
00867 template <typename T>
00868 void KoRTree<T>::NoneLeafNode::contains( const QPointF & point, QMap<int,T> & result ) const
00869 {
00870 for ( int i = 0; i < this->m_counter; ++i )
00871 {
00872 if ( this->m_childBoundingBox[i].contains( point ) )
00873 {
00874 m_childs[i]->contains( point, result );
00875 }
00876 }
00877 }
00878
00879 template <typename T>
00880 void KoRTree<T>::NoneLeafNode::keys( QList<QRectF> & result ) const
00881 {
00882 for ( int i = 0; i < this->m_counter; ++i )
00883 {
00884 m_childs[i]->keys( result );
00885 }
00886 }
00887
00888 template <typename T>
00889 void KoRTree<T>::NoneLeafNode::values( QMap<int,T> & result ) const
00890 {
00891 for ( int i = 0; i < this->m_counter; ++i )
00892 {
00893 m_childs[i]->values( result );
00894 }
00895 }
00896
00897 template <typename T>
00898 typename KoRTree<T>::Node * KoRTree<T>::NoneLeafNode::getNode( int index ) const
00899 {
00900 return m_childs[index];
00901 }
00902
00903 template <typename T>
00904 typename KoRTree<T>::Node * KoRTree<T>::NoneLeafNode::getLeastEnlargement( const QRectF& bb ) const
00905 {
00906
00907 QVarLengthArray<double> area(this->m_counter);
00908 for ( int i = 0; i < this->m_counter; ++i )
00909 {
00910 QSizeF big( this->m_childBoundingBox[i].unite( bb ).size() );
00911 area[i] = big.width() * big.height() - this->m_childBoundingBox[i].width() * this->m_childBoundingBox[i].height();
00912 }
00913
00914 int minIndex = 0;
00915 double minArea = area[minIndex];
00916
00917
00918 for ( int i = 1; i < this->m_counter; ++i )
00919 {
00920 if ( area[i] < minArea )
00921 {
00922 minIndex = i;
00923 minArea = area[i];
00924
00925 }
00926 }
00927
00928 return m_childs[minIndex];
00929 }
00930
00931 #ifdef KOFFICE_RTREE_DEBUG
00932 template <typename T>
00933 void KoRTree<T>::NoneLeafNode::debug( QString line ) const
00934 {
00935 for ( int i = 0; i < this->m_counter; ++i )
00936 {
00937 qDebug( "%s %d %d", qPrintable( line ), this->nodeId(), i );
00938 m_childs[i]->debug( line + " " );
00939 }
00940 }
00941
00942 template <typename T>
00943 void KoRTree<T>::NoneLeafNode::paint( QPainter & p, int level ) const
00944 {
00945 this->paintRect( p, level );
00946 for ( int i = 0; i < this->m_counter; ++i )
00947 {
00948 m_childs[i]->paint( p, level + 1 );
00949 }
00950
00951 }
00952 #endif
00953
00954 template <class T>
00955 int KoRTree<T>::LeafNode::dataIdCounter = 0;
00956
00957 template <typename T>
00958 KoRTree<T>::LeafNode::LeafNode( int capacity, int level, Node * parent )
00959 : Node( capacity, level, parent )
00960 , m_data( capacity )
00961 , m_dataIds( capacity )
00962 {
00963 }
00964
00965 template <typename T>
00966 void KoRTree<T>::LeafNode::insert( const QRectF& bb, const T& data, int id )
00967 {
00968 m_data[this->m_counter] = data;
00969 m_dataIds[this->m_counter] = id;
00970 this->m_childBoundingBox[this->m_counter] = bb;
00971 this->m_boundingBox = this->m_boundingBox.unite( bb );
00972 ++this->m_counter;
00973 }
00974
00975 template <typename T>
00976 void KoRTree<T>::LeafNode::remove( int index )
00977 {
00978 for ( int i = index + 1; i < this->m_counter; ++i )
00979 {
00980 m_data[i-1] = m_data[i];
00981 m_dataIds[i-1] = m_dataIds[i];
00982 }
00983 Node::remove( index );
00984 }
00985
00986 template <typename T>
00987 void KoRTree<T>::LeafNode::remove( const T& data )
00988 {
00989 int old_counter = this->m_counter;
00990 for ( int i = 0; i < this->m_counter; ++i )
00991 {
00992 if ( m_data[i] == data )
00993 {
00994
00995 remove( i );
00996 break;
00997 }
00998 }
00999 if ( old_counter == this->m_counter )
01000 {
01001 qWarning( "LeafNode::remove( const T&data) data not found" );
01002 }
01003 }
01004
01005 template <typename T>
01006 void KoRTree<T>::LeafNode::move( Node * node, int index )
01007 {
01008 LeafNode * n = dynamic_cast<LeafNode*>( node );
01009 if ( n )
01010 {
01011
01012
01013 QRectF bb = n->childBoundingBox( index );
01014 insert( bb, n->getData( index ), n->getDataId( index ) );
01015 }
01016 }
01017
01018 template <typename T>
01019 typename KoRTree<T>::LeafNode * KoRTree<T>::LeafNode::chooseLeaf( const QRectF& bb )
01020 {
01021 Q_UNUSED( bb );
01022 return this;
01023 }
01024
01025 template <typename T>
01026 typename KoRTree<T>::NoneLeafNode * KoRTree<T>::LeafNode::chooseNode( const QRectF& bb, int level )
01027 {
01028 Q_UNUSED( bb );
01029 Q_UNUSED( level );
01030 qFatal("LeafNode::chooseNode called. This should not happen!");
01031 return 0;
01032 }
01033
01034 template <typename T>
01035 void KoRTree<T>::LeafNode::intersects( const QRectF& rect, QMap<int,T> & result ) const
01036 {
01037 for ( int i = 0; i < this->m_counter; ++i )
01038 {
01039 if ( this->m_childBoundingBox[i].intersects( rect ) )
01040 {
01041 result.insert( m_dataIds[i], m_data[i] );
01042 }
01043 }
01044 }
01045
01046 template <typename T>
01047 void KoRTree<T>::LeafNode::contains( const QPointF & point, QMap<int,T> & result ) const
01048 {
01049 for ( int i = 0; i < this->m_counter; ++i )
01050 {
01051 if ( this->m_childBoundingBox[i].contains( point ) )
01052 {
01053 result.insert( m_dataIds[i], m_data[i] );
01054 }
01055 }
01056 }
01057
01058 template <typename T>
01059 void KoRTree<T>::LeafNode::keys( QList<QRectF> & result ) const
01060 {
01061 for ( int i = 0; i < this->m_counter; ++i )
01062 {
01063 result.push_back( this->m_childBoundingBox[i] );
01064 }
01065 }
01066
01067 template <typename T>
01068 void KoRTree<T>::LeafNode::values( QMap<int,T> & result ) const
01069 {
01070 for ( int i = 0; i < this->m_counter; ++i )
01071 {
01072 result.insert( m_dataIds[i], m_data[i] );
01073 }
01074 }
01075
01076 template <typename T>
01077 const T& KoRTree<T>::LeafNode::getData( int index ) const
01078 {
01079 return m_data[ index ];
01080 }
01081
01082 template <typename T>
01083 int KoRTree<T>::LeafNode::getDataId( int index ) const
01084 {
01085 return m_dataIds[ index ];
01086 }
01087
01088 #ifdef KOFFICE_RTREE_DEBUG
01089 template <typename T>
01090 void KoRTree<T>::LeafNode::debug( QString line ) const
01091 {
01092 for ( int i = 0; i < this->m_counter; ++i )
01093 {
01094 qDebug( "%s %d %d %p", qPrintable( line ), this->nodeId(), i, &(m_data[i]) );
01095 qDebug() << this->m_childBoundingBox[i].toRect();
01096 }
01097 }
01098
01099 template <typename T>
01100 void KoRTree<T>::LeafNode::paint( QPainter & p, int level ) const
01101 {
01102 if ( this->m_counter )
01103 {
01104 this->paintRect( p, level );
01105 }
01106 }
01107 #endif
01108
01109 #endif