[GRASS-SVN] r38654 - grass/trunk/lib/vector/rtree

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Aug 9 11:56:35 EDT 2009


Author: mmetz
Date: 2009-08-09 11:56:35 -0400 (Sun, 09 Aug 2009)
New Revision: 38654

Modified:
   grass/trunk/lib/vector/rtree/index.c
   grass/trunk/lib/vector/rtree/index.h
   grass/trunk/lib/vector/rtree/node.c
   grass/trunk/lib/vector/rtree/split.c
Log:
use union in rtree

Modified: grass/trunk/lib/vector/rtree/index.c
===================================================================
--- grass/trunk/lib/vector/rtree/index.c	2009-08-09 12:00:27 UTC (rev 38653)
+++ grass/trunk/lib/vector/rtree/index.c	2009-08-09 15:56:35 UTC (rev 38654)
@@ -54,7 +54,7 @@
     new_rtree->min_node_fill = (new_rtree->nodecard - 1) / 2;
     new_rtree->min_leaf_fill = (new_rtree->leafcard - 1) / 2;
 
-    n = RTreeNewNode(new_rtree);
+    n = RTreeNewNode(new_rtree, 0);
     new_rtree->n_levels = n->level = 0;	/* leaf */
     new_rtree->root = n;
 
@@ -104,11 +104,11 @@
 	if (s[top].sn->level > 0) {	/* this is an internal node in the tree */
 	    found = 1;
 	    for (i = s[top].branch_id; i < t->nodecard; i++) {
-		if (s[top].sn->branch[i].child &&
+		if (s[top].sn->branch[i].child.ptr &&
 		    RTreeOverlap(r, &(s[top].sn->branch[i].rect), t)) {
 		    s[top++].branch_id = i + 1;
 		    /* add next node to stack */
-		    s[top].sn = n->branch[i].child;
+		    s[top].sn = n->branch[i].child.ptr;
 		    s[top].branch_id = 0;
 		    found = 0;
 		    break;
@@ -122,11 +122,11 @@
 	}
 	else {			/* this is a leaf node */
 	    for (i = 0; i < t->leafcard; i++) {
-		if (s[top].sn->branch[i].child &&
+		if (s[top].sn->branch[i].child.id &&
 		    RTreeOverlap(r, &(s[top].sn->branch[i].rect), t)) {
 		    hitCount++;
 		    if (shcb) {	/* call the user-provided callback */
-			if (!shcb((int)s[top].sn->branch[i].child, cbarg)) {
+			if (!shcb((int)s[top].sn->branch[i].child.id, cbarg)) {
 			    /* callback wants to terminate search early */
 			    return hitCount;
 			}
@@ -157,7 +157,7 @@
  * The level argument specifies the number of steps up from the leaf
  * level to insert; e.g. a data rectangle goes in at level = 0.
  */
-static int RTreeInsertRect2(struct Rect *r, struct Node *child, int level,
+static int RTreeInsertRect2(struct Rect *r, union Child child, int level,
 			    struct Node **newnode, struct RTree *t,
 			    struct ListBranch **ee, int *overflow)
 {
@@ -180,7 +180,7 @@
 	i = RTreePickBranch(r, n, t);
 	s[top++].branch_id = i;
 	/* add next node to stack */
-	s[top].sn = n->branch[i].child;
+	s[top].sn = n->branch[i].child.ptr;
     }
 
     /* Have reached level for insertion. Remove p rectangles or split */
@@ -218,8 +218,8 @@
 	    /* get node cover of previous node */
 	    s[top].sn->branch[i].rect = RTreeNodeCover(s[down].sn, t);
 	    /* add new branch for new node previously added by RTreeAddBranch() */
-	    b.child = n2;
-	    b.rect = RTreeNodeCover(b.child, t);
+	    b.child.ptr = n2;
+	    b.rect = RTreeNodeCover(b.child.ptr, t);
 
 	    /* add branch, may split node or remove branches */
 	    cover = &(s[top - 1].sn->branch[s[top - 1].branch_id].rect);
@@ -246,7 +246,7 @@
  * level to insert; e.g. a data rectangle goes in at level = 0.
  * RTreeInsertRect2 does the actual insertion.
  */
-static int RTreeInsertRect1(struct Rect *r, struct Node *child, int level,
+static int RTreeInsertRect1(struct Rect *r, union Child child, int level,
 			    struct RTree *t)
 {
     struct Node *newnode;
@@ -255,26 +255,28 @@
     struct ListBranch *reInsertList = NULL;
     struct ListBranch *e;
     int result;
-    int i, overflow[50];
+    int i, overflow[MAXLEVEL];
 
     /* R*-tree forced reinsertion: for each level only once */
-    for (i = 0; i < 50; i++)
+    for (i = 0; i < MAXLEVEL; i++)
 	overflow[i] = 1;
 
     result =
 	RTreeInsertRect2(r, child, level, &newnode, t, &reInsertList,
 			 overflow);
+			 
     if (result == 1) {		/* root split */
 	/* grow a new root, & tree taller */
-	newroot = RTreeNewNode(t);
-	newroot->level = ++t->n_levels;
+	t->n_levels++;
+	newroot = RTreeNewNode(t, t->n_levels);
+	newroot->level = t->n_levels;
 	/* branch for old root */
 	b.rect = RTreeNodeCover(t->root, t);
-	b.child = t->root;
+	b.child.ptr = t->root;
 	RTreeAddBranch(&b, newroot, NULL, NULL, NULL, NULL, t);
 	/* branch for new node created by RTreeInsertRect2() */
 	b.rect = RTreeNodeCover(newnode, t);
-	b.child = newnode;
+	b.child.ptr = newnode;
 	RTreeAddBranch(&b, newroot, NULL, NULL, NULL, NULL, t);
 	/* set new root node */
 	t->root = newroot;
@@ -295,15 +297,16 @@
 
 	    if (result == 1) {	/* root split */
 		/* grow a new root, & tree taller */
-		newroot = RTreeNewNode(t);
-		newroot->level = ++t->n_levels;
+		t->n_levels++;
+		newroot = RTreeNewNode(t, t->n_levels);
+		newroot->level = t->n_levels;
 		/* branch for old root */
 		b.rect = RTreeNodeCover(t->root, t);
-		b.child = t->root;
+		b.child.ptr = t->root;
 		RTreeAddBranch(&b, newroot, NULL, NULL, NULL, NULL, t);
 		/* branch for new node created by RTreeInsertRect2() */
 		b.rect = RTreeNodeCover(newnode, t);
-		b.child = newnode;
+		b.child.ptr = newnode;
 		RTreeAddBranch(&b, newroot, NULL, NULL, NULL, NULL, t);
 		/* set new root node */
 		t->root = newroot;
@@ -323,11 +326,14 @@
  */
 int RTreeInsertRect(struct Rect *r, int tid, struct RTree *t)
 {
+    union Child newchild;
     assert(r && t);
 
     t->n_leafs++;
 
-    return RTreeInsertRect1(r, (struct Node *)tid, 0, t);
+    newchild.id = tid;
+
+    return RTreeInsertRect1(r, newchild, 0, t);
 }
 
 /*
@@ -366,7 +372,7 @@
  * Returns 1 if record not found, 0 if success.
  */
 static int
-RTreeDeleteRect2(struct Rect *r, struct Node *child, struct RTree *t,
+RTreeDeleteRect2(struct Rect *r, union Child child, struct RTree *t,
 		 struct ListNode **ee)
 {
     int i, notfound = 1;
@@ -387,11 +393,11 @@
 	if (s[top].sn->level > 0) {
 	    n = s[top].sn;
 	    for (i = s[top].branch_id; i < t->nodecard; i++) {
-		if (n->branch[i].child &&
+		if (n->branch[i].child.ptr &&
 		    RTreeOverlap(r, &(n->branch[i].rect), t)) {
 		    s[top++].branch_id = i + 1;
 		    /* add next node to stack */
-		    s[top].sn = n->branch[i].child;
+		    s[top].sn = n->branch[i].child.ptr;
 		    s[top].branch_id = 0;
 
 		    notfound = 0;
@@ -408,7 +414,7 @@
 	}
 	else {
 	    for (i = 0; i < t->leafcard; i++) {
-		if (s[top].sn->branch[i].child && s[top].sn->branch[i].child == child) {	/* found item */
+		if (s[top].sn->branch[i].child.id && s[top].sn->branch[i].child.id == child.id) {	/* found item */
 		    RTreeDisconnectBranch(s[top].sn, i, t);
 		    t->n_leafs--;
 		    notfound = 0;
@@ -439,7 +445,7 @@
 	}
 	else {
 	    /* not enough entries in child, eliminate child node */
-	    RTreeReInsertNode(s[top].sn->branch[i].child, ee);
+	    RTreeReInsertNode(s[top].sn->branch[i].child.ptr, ee);
 	    RTreeDisconnectBranch(s[top].sn, i, t);
 	}
     }
@@ -455,7 +461,7 @@
  * Returns 1 if record not found, 0 if success.
  * RTreeDeleteRect1 provides for eliminating the root.
  */
-static int RTreeDeleteRect1(struct Rect *r, struct Node *child,
+static int RTreeDeleteRect1(struct Rect *r, union Child child,
 			    struct RTree *t)
 {
     int i, maxkids;
@@ -475,10 +481,18 @@
 	    n = reInsertList->node;
 	    maxkids = (n->level > 0 ? t->nodecard : t->leafcard);
 	    for (i = 0; i < maxkids; i++) {
-		if (n->branch[i].child) {
-		    RTreeInsertRect1(&(n->branch[i].rect),
-				     n->branch[i].child, n->level, t);
+		if (n->level > 0) {  /* reinsert node branches */
+		    if (n->branch[i].child.ptr) {
+			RTreeInsertRect1(&(n->branch[i].rect),
+					 n->branch[i].child, n->level, t);
+		    }
 		}
+		else {  /* reinsert leaf branches */
+		    if (n->branch[i].child.id) {
+			RTreeInsertRect1(&(n->branch[i].rect),
+					 n->branch[i].child, n->level, t);
+		    }
+		}
 	    }
 	    e = reInsertList;
 	    reInsertList = reInsertList->next;
@@ -491,10 +505,10 @@
 
 	if (n->count == 1 && n->level > 0) {
 	    for (i = 0; i < t->nodecard; i++) {
-		if (n->branch[i].child)
+		if (n->branch[i].child.ptr)
 		    break;
 	    }
-	    t->root = n->branch[i].child;
+	    t->root = n->branch[i].child.ptr;
 	    RTreeFreeNode(n);
 	}
 	return 0;
@@ -518,5 +532,9 @@
  */
 int RTreeDeleteRect(struct Rect *r, int tid, struct RTree *t)
 {
-    return RTreeDeleteRect1(r, (struct Node *)tid, t);
+    union Child child;
+
+    child.id = tid;
+    
+    return RTreeDeleteRect1(r, child, t);
 }

Modified: grass/trunk/lib/vector/rtree/index.h
===================================================================
--- grass/trunk/lib/vector/rtree/index.h	2009-08-09 12:00:27 UTC (rev 38653)
+++ grass/trunk/lib/vector/rtree/index.h	2009-08-09 15:56:35 UTC (rev 38654)
@@ -60,10 +60,16 @@
 
 struct Node;               /* node for memory based index */
 
+union Child
+{
+    int id;              /* child id */
+    struct Node *ptr;    /* pointer to child node */
+};
+
 struct Branch              /* branch for memory based index */
 {
     struct Rect rect;
-    struct Node *child;    /* pointer to child node */
+    union Child child;
 };
 
 struct Node             /* node for memory based index */
@@ -128,8 +134,8 @@
 extern struct RTree *RTreeNewIndex(int);
 void RTreeFreeIndex(struct RTree *);
 /* node.c */
-extern struct Node *RTreeNewNode(struct RTree *);
-extern void RTreeInitNode(struct Node *);
+extern struct Node *RTreeNewNode(struct RTree *, int);
+extern void RTreeInitNode(struct Node *, int);
 extern void RTreeFreeNode(struct Node *);
 extern void RTreeDestroyNode(struct Node *, int);
 extern struct Rect RTreeNodeCover(struct Node *, struct RTree *);

Modified: grass/trunk/lib/vector/rtree/node.c
===================================================================
--- grass/trunk/lib/vector/rtree/node.c	2009-08-09 12:00:27 UTC (rev 38653)
+++ grass/trunk/lib/vector/rtree/node.c	2009-08-09 15:56:35 UTC (rev 38654)
@@ -30,33 +30,51 @@
     RectReal distance;		/* distance to node center */
 };
 
-/* Initialize one branch cell in a node. */
-static void RTreeInitBranch(struct Branch *b)
+/* Initialize one branch cell in an internal node. */
+static void RTreeInitNodeBranch(struct Branch *b)
 {
     RTreeInitRect(&(b->rect));
-    b->child = NULL;
+    b->child.ptr = NULL;
 
 }
 
+/* Initialize one branch cell in a leaf node. */
+static void RTreeInitLeafBranch(struct Branch *b)
+{
+    RTreeInitRect(&(b->rect));
+    b->child.id = 0;
+
+}
+
+static void (*RTreeInitBranch[2]) () = {
+    RTreeInitLeafBranch, RTreeInitNodeBranch
+};
+
 /* Initialize a Node structure. */
-void RTreeInitNode(struct Node *n)
+void RTreeInitNode(struct Node *n, int level)
 {
     int i;
 
     n->count = 0;
     n->level = -1;
-    for (i = 0; i < MAXCARD; i++)
-	RTreeInitBranch(&(n->branch[i]));
+    if (level > 0) {
+	for (i = 0; i < MAXCARD; i++)
+	    RTreeInitNodeBranch(&(n->branch[i]));
+    }
+    else {
+	for (i = 0; i < MAXCARD; i++)
+	    RTreeInitLeafBranch(&(n->branch[i]));
+    }
 }
 
 /* Make a new node and initialize to have all branch cells empty. */
-struct Node *RTreeNewNode(struct RTree *t)
+struct Node *RTreeNewNode(struct RTree *t, int level)
 {
     struct Node *n;
 
     n = (struct Node *)malloc((size_t) t->nodesize);
     assert(n);
-    RTreeInitNode(n);
+    RTreeInitNode(n, level);
     return n;
 }
 
@@ -72,23 +90,36 @@
  */
 struct Rect RTreeNodeCover(struct Node *n, struct RTree *t)
 {
-    int i, first_time = 1, maxkids;
+    int i, first_time = 1;
     struct Rect r;
 
     assert(n);
 
-    maxkids = ((n)->level > 0 ? t->nodecard : t->leafcard);
-
     RTreeInitRect(&r);
-    for (i = 0; i < maxkids; i++)
-	if (n->branch[i].child) {
-	    if (first_time) {
-		r = n->branch[i].rect;
-		first_time = 0;
+    if ((n)->level > 0) { /* internal node */
+	for (i = 0; i < t->nodecard; i++) {
+	    if (n->branch[i].child.ptr) {
+		if (first_time) {
+		    r = n->branch[i].rect;
+		    first_time = 0;
+		}
+		else
+		    r = RTreeCombineRect(&r, &(n->branch[i].rect), t);
 	    }
-	    else
-		r = RTreeCombineRect(&r, &(n->branch[i].rect), t);
 	}
+    }
+    else {  /* leaf */
+	for (i = 0; i < t->leafcard; i++) {
+	    if (n->branch[i].child.id) {
+		if (first_time) {
+		    r = n->branch[i].rect;
+		    first_time = 0;
+		}
+		else
+		    r = RTreeCombineRect(&r, &(n->branch[i].rect), t);
+	    }
+	}
+    }
     return r;
 }
 
@@ -120,7 +151,7 @@
     /* get the branch that will overlap with the smallest number of 
      * sibling branches when including the new rectangle */
     for (i = 0; i < t->nodecard; i++) {
-	if (n->branch[i].child) {
+	if (n->branch[i].child.ptr) {
 	    rr = &n->branch[i].rect;
 	    tmp_rect = RTreeCombineRect(r, rr, t);
 	    area = RTreeRectSphericalVolume(rr, t);
@@ -180,7 +211,7 @@
 	return RTreePickBranch1(r, n, t);
 
     for (i = 0; i < t->nodecard; i++) {
-	if (n->branch[i].child) {
+	if (n->branch[i].child.ptr) {
 	    rr = &n->branch[i].rect;
 	    area = RTreeRectSphericalVolume(rr, t);
 	    tmp_rect = RTreeCombineRect(r, rr, t);
@@ -203,14 +234,17 @@
 /* Disconnect a dependent node. */
 void RTreeDisconnectBranch(struct Node *n, int i, struct RTree *t)
 {
-    int maxkids;
+    if ((n)->level > 0) {
+	assert(n && i >= 0 && i < t->nodecard);
+	assert(n->branch[i].child.ptr);
+	RTreeInitNodeBranch(&(n->branch[i]));
+    }
+    else {
+	assert(n && i >= 0 && i < t->leafcard);
+	assert(n->branch[i].child.id);
+	RTreeInitLeafBranch(&(n->branch[i]));
+    }
 
-    maxkids = ((n)->level > 0 ? t->nodecard : t->leafcard);
-
-    assert(n && i >= 0 && i < maxkids);
-    assert(n->branch[i].child);
-
-    RTreeInitBranch(&(n->branch[i]));
     n->count--;
 }
 
@@ -222,8 +256,8 @@
 
     if (n->level > 0) {		/* it is not leaf -> destroy childs */
 	for (i = 0; i < nodes; i++) {
-	    if (n->branch[i].child) {
-		RTreeDestroyNode(n->branch[i].child, nodes);
+	    if (n->branch[i].child.ptr) {
+		RTreeDestroyNode(n->branch[i].child.ptr, nodes);
 	    }
 	}
     }
@@ -395,12 +429,20 @@
 				struct ListBranch **ee, struct Rect *cover,
 				struct RTree *t)
 {
-    int i, j, maxkids;
+    int i, j, maxkids, is_node;
     RectReal center_n[NUMDIMS], center_r, delta;
     struct Branch branchbuf[MAXCARD + 1];
     struct dist rdist[MAXCARD + 1];
 
-    maxkids = t->nodecard;
+    if ((n)->level > 0) {
+	maxkids = t->nodecard;
+	is_node = 1;
+    }
+    else {
+	maxkids = t->leafcard;
+	is_node = 0;
+    }
+    maxkids = (n)->level > 0 ? t->nodecard : t->leafcard;
 
     assert(n->count == maxkids);	/* must be full */
 
@@ -422,7 +464,7 @@
 	    rdist[i].distance += delta * delta;
 	}
 
-	RTreeInitBranch(&(n->branch[i]));
+	RTreeInitBranch[is_node](&(n->branch[i]));
     }
 
     /* new branch */
@@ -433,7 +475,7 @@
     /* quicksort dist */
     RTreeQuicksortDist(rdist, maxkids);
 
-    /* put largest three in branch list */
+    /* put largest three in branch list, farthest from center first */
     for (i = 0; i < FORCECARD; i++) {
 	RTreeReInsertBranch(branchbuf[rdist[maxkids - i].id], n->level, ee);
     }
@@ -449,6 +491,7 @@
  * Returns 0 if node not split.  Old node updated.
  * Returns 1 if node split, sets *new_node to address of new node.
  * Old node updated, becomes one of two.
+ * Returns 2 if branches wereremoved for forced reinsertion
  */
 int RTreeAddBranch(struct Branch *b, struct Node *n,
 		   struct Node **new_node, struct ListBranch **ee,
@@ -462,14 +505,26 @@
     maxkids = ((n)->level > 0 ? t->nodecard : t->leafcard);
 
     if (n->count < maxkids) {	/* split won't be necessary */
-	for (i = 0; i < maxkids; i++) {	/* find empty branch */
-	    if (n->branch[i].child == 0) {
-		n->branch[i] = *b;
-		n->count++;
-		break;
+	if ((n)->level > 0) {   /* internal node */
+	    for (i = 0; i < t->nodecard; i++) {	/* find empty branch */
+		if (n->branch[i].child.ptr == NULL) {
+		    n->branch[i] = *b;
+		    n->count++;
+		    break;
+		}
 	    }
+	    return 0;
 	}
-	return 0;
+	else if ((n)->level == 0) {   /* leaf */
+	    for (i = 0; i < t->leafcard; i++) {	/* find empty branch */
+		if (n->branch[i].child.id == 0) {
+		    n->branch[i] = *b;
+		    n->count++;
+		    break;
+		}
+	    }
+	    return 0;
+	}
     }
     else {
 	if (n->level < t->n_levels && overflow[n->level]) {
@@ -479,11 +534,15 @@
 	    return 2;
 	}
 	else {
-	    *new_node = RTreeNewNode(t);
+	    *new_node = RTreeNewNode(t, (n)->level);
 	    RTreeSplitNode(n, b, *new_node, t);
 	    return 1;
 	}
     }
+
+    /* should not be reached */
+    assert(0);
+    return -1;
 }
 
 /*
@@ -501,7 +560,7 @@
 static void RTreePrintBranch(struct Branch *b, int depth, struct RTree *t)
 {
     RTreePrintRect(&(b->rect), depth);
-    RTreePrintNode(b->child, depth, t);
+    RTreePrintNode(b->child.ptr, depth, t);
 }
 
 /* Print out the data in a node. */
@@ -527,8 +586,8 @@
 	if (n->level == 0) {
 	    RTreeTabIn(depth);
 	    RTreePrintRect(&(n->branch[i].rect), depth);
-	    fprintf(stdout, "\t%d: data id = %o\n", i,
-		    (unsigned)n->branch[i].child);
+	    fprintf(stdout, "\t%d: data id = %d\n", i,
+		  n->branch[i].child.id);
 	}
 	else {
 	    RTreeTabIn(depth);

Modified: grass/trunk/lib/vector/rtree/split.c
===================================================================
--- grass/trunk/lib/vector/rtree/split.c	2009-08-09 12:00:27 UTC (rev 38653)
+++ grass/trunk/lib/vector/rtree/split.c	2009-08-09 15:56:35 UTC (rev 38654)
@@ -19,10 +19,15 @@
 
 #include <stdio.h>
 #include <assert.h>
+#include <float.h>
 #include "index.h"
 #include "card.h"
 #include "split.h"
 
+#ifndef DBL_MAX
+#define DBL_MAX 1.797693E308  /* DBL_MAX approximation */
+#endif
+
 struct Branch BranchBuf[MAXCARD + 1];
 int BranchCount;
 struct Rect CoverSplit;
@@ -37,18 +42,28 @@
 static void RTreeGetBranches(struct Node *n, struct Branch *b,
 			     struct RTree *t)
 {
-    int i, maxkids;
+    int i, maxkids = 0;
 
     assert(n);
     assert(b);
 
-    maxkids = ((n)->level > 0 ? t->nodecard : t->leafcard);
+    if ((n)->level > 0) {
+	maxkids = t->nodecard;
+	/* load the branch buffer */
+	for (i = 0; i < maxkids; i++) {
+	    assert(n->branch[i].child.ptr);	/* n should have every entry full */
+	    BranchBuf[i] = n->branch[i];
+	}
+    }
+    else {
+	maxkids = t->leafcard;
+	/* load the branch buffer */
+	for (i = 0; i < maxkids; i++) {
+	    assert(n->branch[i].child.id);	/* n should have every entry full */
+	    BranchBuf[i] = n->branch[i];
+	}
+    }
 
-    /* load the branch buffer */
-    for (i = 0; i < maxkids; i++) {
-	assert(n->branch[i].child);	/* n should have every entry full */
-	BranchBuf[i] = n->branch[i];
-    }
     BranchBuf[maxkids] = *b;
     BranchCount = maxkids + 1;
 
@@ -59,7 +74,7 @@
     }
     CoverSplitArea = RTreeRectSphericalVolume(&CoverSplit, t);
 
-    RTreeInitNode(n);
+    RTreeInitNode(n, n->level);
 }
 
 /*----------------------------------------------------------------------
@@ -463,6 +478,8 @@
 
     maxkids = (minfill == t->min_leaf_fill ? t->leafcard : t->nodecard);
 
+    margin = DBL_MAX;
+
     /* choose split axis */
     /* For each dimension, sort rectangles first by lower boundary then
      * by upper boundary. Get the smallest margin. */
@@ -471,8 +488,8 @@
 	best_cut[i] = 0;
 	best_side[i] = 0;
 
-	smallest_overlap = -1;
-	smallest_vol = -1;
+	smallest_overlap = DBL_MAX;
+	smallest_vol = DBL_MAX;
 
 	/* first lower then upper bounds for each axis */
 	for (s = 0; s < 2; s++) {
@@ -510,7 +527,7 @@
 				    t) + RTreeRectMargin(&testrect2, t);
 
 		/* remember best axis */
-		if (margin <= smallest_margin || first_time) {
+		if (margin <= smallest_margin) {
 		    smallest_margin = margin;
 		    best_axis = i;
 		    first_time = 0;
@@ -552,7 +569,7 @@
 				    t) + RTreeRectVolume(&testrect2, t);
 
 		/* get best cut for this axis */
-		if (overlap <= smallest_overlap || smallest_overlap < 0) {
+		if (overlap <= smallest_overlap) {
 		    smallest_overlap = overlap;
 		    smallest_vol = vol;
 		    best_cut[i] = j;
@@ -560,7 +577,7 @@
 		}
 		else if (overlap == smallest_overlap) {
 		    /* resolve ties by minimum volume */
-		    if (vol <= smallest_vol || smallest_vol < 0) {
+		    if (vol <= smallest_vol) {
 			smallest_vol = vol;
 			best_cut[i] = j;
 			best_side[i] = s;



More information about the grass-commit mailing list