19
20
#include <stdlib.h>
23
#include <grass/gis.h>
24
/* Initialize one branch cell in a node. */
25
static void RTreeInitBranch(struct Branch *b)
27
RTreeInitRect(&(b->rect));
28
/* rectangle distances for forced removal */
31
int id; /* branch id */
32
RectReal distance; /* distance to node center */
35
/* Initialize one branch cell in an internal node. */
36
static void RTreeInitNodeBranchM(struct RTree_Branch *b, struct RTree *t)
38
RTreeInitRect(&(b->rect), t);
39
memset(&(b->child), 0, sizeof(union RTree_Child));
43
/* Initialize one branch cell in an internal node. */
44
static void RTreeInitNodeBranchF(struct RTree_Branch *b, struct RTree *t)
46
RTreeInitRect(&(b->rect), t);
47
memset(&(b->child), 0, sizeof(union RTree_Child));
51
/* Initialize one branch cell in a leaf node. */
52
static void RTreeInitLeafBranch(struct RTree_Branch *b, struct RTree *t)
54
RTreeInitRect(&(b->rect), t);
55
memset(&(b->child), 0, sizeof(union RTree_Child));
59
static void (*RTreeInitBranch[3]) (struct RTree_Branch *b, struct RTree *t) = {
60
RTreeInitLeafBranch, RTreeInitNodeBranchM, RTreeInitNodeBranchF
31
63
/* Initialize a Node structure. */
32
void RTreeInitNode(struct Node *N)
64
/* type = 1: leaf, type = 2: internal, memory, type = 3: internal, file */
65
void RTreeInitNode(struct RTree *t, struct RTree_Node *n, int type)
34
register struct Node *n = N;
39
72
for (i = 0; i < MAXCARD; i++)
40
RTreeInitBranch(&(n->branch[i]));
73
RTreeInitBranch[type](&(n->branch[i]), t);
43
76
/* Make a new node and initialize to have all branch cells empty. */
44
struct Node *RTreeNewNode(void)
77
struct RTree_Node *RTreeAllocNode(struct RTree *t, int level)
46
register struct Node *n;
49
n = (struct Node *)malloc(sizeof(struct Node));
82
n = (struct RTree_Node *)malloc(sizeof(struct RTree_Node));
88
n->branch = malloc(MAXCARD * sizeof(struct RTree_Branch));
90
for (i = 0; i < MAXCARD; i++) {
91
n->branch[i].rect.boundary = RTreeAllocBoundary(t);
92
RTreeInitBranch[NODETYPE(level, t->fd)](&(n->branch[i]), t);
55
void RTreeFreeNode(struct Node *p)
62
static void RTreePrintBranch(struct Branch *b, int depth)
64
RTreePrintRect(&(b->rect), depth);
65
RTreePrintNode(b->child, depth);
68
extern void RTreeTabIn(int depth)
72
for (i = 0; i < depth; i++)
76
/* Print out the data in a node. */
77
void RTreePrintNode(struct Node *n, int depth)
98
void RTreeFreeNode(struct RTree_Node *n)
84
fprintf(stdout, "node");
86
fprintf(stdout, " LEAF");
87
else if (n->level > 0)
88
fprintf(stdout, " NONLEAF");
90
fprintf(stdout, " TYPE=?");
91
fprintf(stdout, " level=%d count=%d address=%o\n", n->level, n->count,
94
for (i = 0; i < n->count; i++) {
96
/* RTreeTabIn(depth); */
97
/* fprintf (stdout, "\t%d: data = %d\n", i, n->branch[i].child); */
101
fprintf(stdout, "branch %d\n", i);
102
RTreePrintBranch(&n->branch[i], depth + 1);
104
for (i = 0; i < MAXCARD; i++)
105
RTreeFreeBoundary(&(n->branch[i].rect));
111
/* copy node 2 to node 1 */
112
void RTreeCopyNode(struct RTree_Node *n1, struct RTree_Node *n2, struct RTree *t)
118
n1->count = n2->count;
119
n1->level = n2->level;
120
for (i = 0; i < MAXCARD; i++) {
121
RTreeCopyBranch(&(n1->branch[i]), &(n2->branch[i]), t);
125
/* copy branch 2 to branch 1 */
126
void RTreeCopyBranch(struct RTree_Branch *b1, struct RTree_Branch *b2, struct RTree *t)
128
b1->child = b2->child;
129
RTreeCopyRect(&(b1->rect), &(b2->rect), t);
108
133
* Find the smallest rectangle that includes all rectangles in
109
134
* branches of a node.
111
struct Rect RTreeNodeCover(struct Node *N)
113
register struct Node *n = N;
114
register int i, first_time = 1;
120
for (i = 0; i < MAXKIDS(n); i++)
121
if (n->branch[i].child) {
123
r = n->branch[i].rect;
127
r = RTreeCombineRect(&r, &(n->branch[i].rect));
136
void RTreeNodeCover(struct RTree_Node *n, struct RTree_Rect *r, struct RTree *t)
138
int i, first_time = 1;
140
if ((n)->level > 0) { /* internal node */
141
for (i = 0; i < t->nodecard; i++) {
142
if (t->valid_child(&(n->branch[i].child))) {
144
RTreeCopyRect(r, &(n->branch[i].rect), t);
148
RTreeExpandRect(r, &(n->branch[i].rect), t);
153
for (i = 0; i < t->leafcard; i++) {
154
if (n->branch[i].child.id) {
156
RTreeCopyRect(r, &(n->branch[i].rect), t);
160
RTreeExpandRect(r, &(n->branch[i].rect), t);
167
* Idea from R*-tree, modified: not overlap size but overlap number
169
* Pick a branch from leaf nodes (current node has level 1). Pick the
170
* one that will result in the smallest number of overlapping siblings.
171
* This will result in the least ambiguous node covering the new
172
* rectangle, improving search speed.
173
* In case of a tie, pick the one which needs the smallest increase in
174
* area to accomodate the new rectangle, then the smallest area before,
175
* to get the best resolution when searching.
178
static int RTreePickLeafBranch(struct RTree_Rect *r, struct RTree_Node *n, struct RTree *t)
180
struct RTree_Rect *rr;
182
RectReal increase, bestIncr = -1, area, bestArea = 0;
183
int best = 0, bestoverlap;
186
bestoverlap = t->nodecard + 1;
188
/* get the branch that will overlap with the smallest number of
189
* sibling branches when including the new rectangle */
190
for (i = 0; i < t->nodecard; i++) {
191
if (t->valid_child(&(n->branch[i].child))) {
192
rr = &n->branch[i].rect;
193
RTreeCombineRect(r, rr, &(t->orect), t);
194
area = RTreeRectSphericalVolume(rr, t);
195
increase = RTreeRectSphericalVolume(&(t->orect), t) - area;
198
for (j = 0; j < t->leafcard; j++) {
200
rr = &n->branch[j].rect;
201
overlap += RTreeOverlap(&(t->orect), rr, t);
205
if (overlap < bestoverlap) {
207
bestoverlap = overlap;
211
else if (overlap == bestoverlap) {
213
if (increase < bestIncr) {
218
else if (increase == bestIncr && area < bestArea) {
163
260
else if (increase == bestIncr && area < bestArea) {
174
* Add a branch to a node. Split the node if necessary.
175
* Returns 0 if node not split. Old node updated.
176
* Returns 1 if node split, sets *new_node to address of new node.
177
* Old node updated, becomes one of two.
179
int RTreeAddBranch(struct Branch *B, struct Node *N, struct Node **New_node)
181
register struct Branch *b = B;
182
register struct Node *n = N;
183
register struct Node **new_node = New_node;
189
if (n->count < MAXKIDS(n)) { /* split won't be necessary */
190
for (i = 0; i < MAXKIDS(n); i++) { /* find empty branch */
191
if (n->branch[i].child == NULL) {
201
RTreeSplitNode(n, b, new_node);
206
269
/* Disconnect a dependent node. */
207
void RTreeDisconnectBranch(struct Node *n, int i)
270
void RTreeDisconnectBranch(struct RTree_Node *n, int i, struct RTree *t)
209
assert(n && i >= 0 && i < MAXKIDS(n));
210
assert(n->branch[i].child);
272
if ((n)->level > 0) {
273
assert(n && i >= 0 && i < t->nodecard);
274
assert(t->valid_child(&(n->branch[i].child)));
276
RTreeInitNodeBranchM(&(n->branch[i]), t);
278
RTreeInitNodeBranchF(&(n->branch[i]), t);
281
assert(n && i >= 0 && i < t->leafcard);
282
assert(n->branch[i].child.id);
283
RTreeInitLeafBranch(&(n->branch[i]), t);
212
RTreeInitBranch(&(n->branch[i]));
216
289
/* Destroy (free) node recursively. */
217
void RTreeDestroyNode(struct Node *n)
290
/* NOTE: only needed for memory based index */
291
void RTreeDestroyNode(struct RTree_Node *n, int nodes)
221
295
if (n->level > 0) { /* it is not leaf -> destroy childs */
222
for (i = 0; i < NODECARD; i++) {
223
if (n->branch[i].child) {
224
RTreeDestroyNode(n->branch[i].child);
296
for (i = 0; i < nodes; i++) {
297
if (n->branch[i].child.ptr) {
298
RTreeDestroyNode(n->branch[i].child.ptr, nodes);
229
303
/* Free this node */
230
304
RTreeFreeNode(n);
309
/****************************************************************
311
* R*-tree: force remove FORCECARD branches for reinsertion *
313
****************************************************************/
318
static void RTreeSwapDist(struct dist *a, struct dist *b)
328
* check if dist is sorted ascending to distance
330
static int RTreeDistIsSorted(struct dist *d, int first, int last)
334
for (i = first; i < last; i++) {
335
if (d[i].distance > d[i + 1].distance)
343
* partition dist for quicksort on distance
345
static int RTreePartitionDist(struct dist *d, int first, int last)
347
int pivot, mid = ((first + last) >> 1);
350
if (last - first == 1) { /* only two items in list */
351
if (d[first].distance > d[last].distance) {
352
RTreeSwapDist(&(d[first]), &(d[last]));
358
larger = pivot = mid;
360
if (d[first].distance > d[mid].distance) {
361
larger = pivot = first;
365
if (d[larger].distance > d[last].distance) {
366
/* larger is largest, get the larger of smaller and last */
368
if (d[smaller].distance > d[last].distance) {
374
RTreeSwapDist(&(d[pivot]), &(d[last]));
379
while (first < last) {
380
if (d[first].distance <= d[last].distance) {
381
if (pivot != first) {
382
RTreeSwapDist(&(d[pivot]), &(d[first]));
390
RTreeSwapDist(&(d[pivot]), &(d[last]));
397
* quicksort dist struct ascending by distance
398
* n is last valid index
400
static void RTreeQuicksortDist(struct dist *d, int n)
402
int pivot, first, last;
403
int s_first[MAXCARD + 1], s_last[MAXCARD + 1], stacksize;
413
first = s_first[stacksize];
414
last = s_last[stacksize];
416
if (!RTreeDistIsSorted(d, first, last)) {
418
pivot = RTreePartitionDist(d, first, last);
420
s_first[stacksize] = first;
421
s_last[stacksize] = pivot - 1;
424
s_first[stacksize] = pivot + 1;
425
s_last[stacksize] = last;
433
* Allocate space for a branch in the list used in InsertRect to
434
* store branches of nodes that are too full.
436
static struct RTree_ListBranch *RTreeNewListBranch(struct RTree *t)
438
struct RTree_ListBranch *p =
439
(struct RTree_ListBranch *)malloc(sizeof(struct RTree_ListBranch));
442
p->b.rect.boundary = RTreeAllocBoundary(t);
448
* Add a branch to the reinsertion list. It will later
449
* be reinserted into the index structure.
451
static void RTreeReInsertBranch(struct RTree_Branch b, int level,
452
struct RTree_ListBranch **ee, struct RTree *t)
454
register struct RTree_ListBranch *l;
456
l = RTreeNewListBranch(t);
457
RTreeCopyBranch(&(l->b), &b, t);
464
* Remove branches from a node. Select the 2 branches whose rectangle
465
* center is farthest away from node cover center.
468
static void RTreeRemoveBranches(struct RTree_Node *n, struct RTree_Branch *b,
469
struct RTree_ListBranch **ee, struct RTree_Rect *cover,
472
int i, j, maxkids, type;
473
RectReal center_r, delta;
474
struct dist rdist[MAXCARD + 1];
476
struct RTree_Rect *new_cover = &(t->orect);
477
RectReal *center_n = t->center_n;
481
maxkids = MAXKIDS((n)->level, t);
482
type = NODETYPE((n)->level, t->fd);
484
assert(n->count == maxkids); /* must be full */
486
RTreeCombineRect(cover, &(b->rect), new_cover, t);
488
/* center coords of node cover */
489
for (j = 0; j < t->ndims; j++) {
490
center_n[j] = (new_cover->boundary[j + t->ndims_alloc] + new_cover->boundary[j]) / 2;
493
/* compute distances of child rectangle centers to node cover center */
494
for (i = 0; i < maxkids; i++) {
495
RTreeCopyBranch(&(t->BranchBuf[i]), &(n->branch[i]), t);
496
rdist[i].distance = 0;
498
for (j = 0; j < t->ndims; j++) {
500
(t->BranchBuf[i].rect.boundary[j + t->ndims_alloc] +
501
t->BranchBuf[i].rect.boundary[j]) / 2;
502
delta = center_n[j] - center_r;
503
rdist[i].distance += delta * delta;
506
RTreeInitBranch[type](&(n->branch[i]), t);
510
RTreeCopyBranch(&(t->BranchBuf[maxkids]), b, t);
511
rdist[maxkids].distance = 0;
512
for (j = 0; j < t->ndims; j++) {
514
(b->rect.boundary[j + t->ndims_alloc] +
515
b->rect.boundary[j]) / 2;
516
delta = center_n[j] - center_r;
517
rdist[maxkids].distance += delta * delta;
519
rdist[maxkids].id = maxkids;
522
RTreeQuicksortDist(rdist, maxkids);
524
/* put largest three in branch list, farthest from center first */
525
for (i = 0; i < FORCECARD; i++) {
526
RTreeReInsertBranch(t->BranchBuf[rdist[maxkids - i].id], n->level, ee, t);
528
/* put remaining in node, closest to center first */
529
for (i = 0; i < maxkids - FORCECARD + 1; i++) {
530
RTreeCopyBranch(&(n->branch[i]), &(t->BranchBuf[rdist[i].id]), t);
532
n->count = maxkids - FORCECARD + 1;
536
* Add a branch to a node. Split the node if necessary.
537
* Returns 0 if node not split. Old node updated.
538
* Returns 1 if node split, sets *new_node to address of new node.
539
* Old node updated, becomes one of two.
540
* Returns 2 if branches were removed for forced reinsertion
542
int RTreeAddBranch(struct RTree_Branch *b, struct RTree_Node *n,
543
struct RTree_Node **newnode, struct RTree_ListBranch **ee,
544
struct RTree_Rect *cover, char *overflow, struct RTree *t)
548
maxkids = MAXKIDS((n)->level, t);
550
if (n->count < maxkids) { /* split won't be necessary */
551
if ((n)->level > 0) { /* internal node */
552
for (i = 0; i < maxkids; i++) { /* find empty branch */
553
if (!t->valid_child(&(n->branch[i].child))) {
555
n->branch[i].child = b->child;
556
RTreeCopyRect(&(n->branch[i].rect), &(b->rect), t);
563
else if ((n)->level == 0) { /* leaf */
564
for (i = 0; i < maxkids; i++) { /* find empty branch */
565
if (n->branch[i].child.id == 0) {
567
n->branch[i].child = b->child;
568
RTreeCopyRect(&(n->branch[i].rect), &(b->rect), t);
577
if (n->level < t->rootlevel && overflow[n->level]) {
578
/* R*-tree forced reinsert */
579
RTreeRemoveBranches(n, b, ee, cover, t);
580
overflow[n->level] = 0;
585
RTreeInitNode(t, *newnode, NODETYPE(n->level, t->fd));
587
*newnode = RTreeAllocNode(t, (n)->level);
588
RTreeSplitNode(n, b, *newnode, t);
593
/* should not be reached */
599
* for debugging only: print items to stdout
602
void RTreeTabIn(int depth)
606
for (i = 0; i < depth; i++)
610
static void RTreePrintBranch(struct RTree_Branch *b, int depth, struct RTree *t)
612
RTreePrintRect(&(b->rect), depth, t);
613
RTreePrintNode(b->child.ptr, depth, t);
616
/* Print out the data in a node. */
617
void RTreePrintNode(struct RTree_Node *n, int depth, struct RTree *t)
623
maxkids = (n->level > 0 ? t->nodecard : t->leafcard);
625
fprintf(stdout, "node");
627
fprintf(stdout, " LEAF");
628
else if (n->level > 0)
629
fprintf(stdout, " NONLEAF");
631
fprintf(stdout, " TYPE=?");
632
fprintf(stdout, " level=%d count=%d", n->level, n->count);
634
for (i = 0; i < maxkids; i++) {
637
RTreePrintRect(&(n->branch[i].rect), depth, t);
638
fprintf(stdout, "\t%d: data id = %d\n", i,
639
n->branch[i].child.id);
643
fprintf(stdout, "branch %d\n", i);
644
RTreePrintBranch(&(n->branch[i]), depth + 1, t);