Ejemplo n.º 1
0
// Inserts a new data rectangle into the index structure.
// Recursively descends tree, propagates splits back up.
// Returns 0 if node was not split.  Old node updated.
// If node was split, returns 1 and sets the pointer pointed to by
// new_node to point to the new node.  Old node updated to become one of two.
// 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 Xastir_RTreeInsertRect2(struct Rect *r,
		void *tid, struct Node *n, struct Node **new_node, int level)
{
/*
	register struct Rect *r = R;
	register int tid = Tid;
	register struct Node *n = N, **new_node = New_node;
	register int level = Level;
*/

	register int i;
	struct Branch b;
	struct Node *n2;

	assert(r && n && new_node);
	assert(level >= 0 && level <= n->level);

	// Still above level for insertion, go down tree recursively
	//
	if (n->level > level)
	{
		i = Xastir_RTreePickBranch(r, n);
		if (!Xastir_RTreeInsertRect2(r, tid, n->branch[i].child, &n2, level))
		{
			// child was not split
			//
			n->branch[i].rect =
				Xastir_RTreeCombineRect(r,&(n->branch[i].rect));
			return 0;
		}
		else    // child was split
		{
			n->branch[i].rect = Xastir_RTreeNodeCover(n->branch[i].child);
			b.child = n2;
			b.rect = Xastir_RTreeNodeCover(n2);
			return Xastir_RTreeAddBranch(&b, n, new_node);
		}
	}

	// Have reached level for insertion. Add rect, split if necessary
	//
	else if (n->level == level)
	{
		b.rect = *r;
		b.child = (struct Node *) tid;
		/* child field of leaves contains tid of data record */
		return Xastir_RTreeAddBranch(&b, n, new_node);
	}
	else
	{
		/* Not supposed to happen */
		assert (FALSE);
		return 0;
	}
}
Ejemplo n.º 2
0
// Find the smallest rectangle that includes all rectangles in
// branches of a node.
//
struct Rect Xastir_RTreeNodeCover(struct Node *N)
{
	register struct Node *n = N;
	register int i, first_time=1;
	struct Rect r;
	assert(n);

	Xastir_RTreeInitRect(&r);
	for (i = 0; i < MAXKIDS(n); i++)
		if (n->branch[i].child)
		{
			if (first_time)
			{
				r = n->branch[i].rect;
				first_time = 0;
			}
			else
				r = Xastir_RTreeCombineRect(&r, &(n->branch[i].rect));
		}
	return r;
}
Ejemplo n.º 3
0
// Pick a branch.  Pick the one that will need the smallest increase
// in area to accomodate the new rectangle.  This will result in the
// least total area for the covering rectangles in the current node.
// In case of a tie, pick the one which was smaller before, to get
// the best resolution when searching.
//
int Xastir_RTreePickBranch(struct Rect *R, struct Node *N)
{
	register struct Rect *r = R;
	register struct Node *n = N;
	register struct Rect *rr;
	register int i, first_time=1;
        // Although it is impossible for bestArea and best to be used
        // unininitialized the way the code is structured, gcc complains 
        // about possible uninitialized usage.  Let's keep it happy.
        // Original superliminal.com had no initializers here.
	RectReal increase, bestIncr=(RectReal)-1, area, bestArea=0.0;
	int best=0;
	struct Rect tmp_rect;
	assert(r && n);

	for (i=0; i<MAXKIDS(n); i++)
	{
		if (n->branch[i].child)
		{
			rr = &n->branch[i].rect;
			area = Xastir_RTreeRectSphericalVolume(rr);
			tmp_rect = Xastir_RTreeCombineRect(r, rr);
			increase = Xastir_RTreeRectSphericalVolume(&tmp_rect) - area;
			if (increase < bestIncr || first_time)
			{
				best = i;
				bestArea = area;
				bestIncr = increase;
				first_time = 0;
			}
			else if (increase == bestIncr && area < bestArea)
			{
				best = i;
				bestArea = area;
				bestIncr = increase;
			}
		}
	}
	return best;
}