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