示例#1
0
文件: spgist.c 项目: ahinz/postgis
Datum
spgist_geom_leaf_consistent(PG_FUNCTION_ARGS)
{
	spgLeafConsistentIn *in = (spgLeafConsistentIn *) PG_GETARG_POINTER(0);
	spgLeafConsistentOut *out = (spgLeafConsistentOut *) PG_GETARG_POINTER(1);
	bool		res;
	int			i;
        BOX2DF datum;
        BOX2DF *datum_p = &datum;
        
        gserialized_datum_get_box2df_p(in->leafDatum, datum_p);

	/* all tests are exact */
	out->recheck = false;

	/* leafDatum is what it is... */
	out->leafValue = in->leafDatum;

	/* Perform the required comparison(s) */
	res = true;
	for (i = 0; i < in->nkeys; i++)
	{
                BOX2DF query;
                BOX2DF *query_p = &query;

                gserialized_datum_get_box2df_p(in->scankeys[i].sk_argument, query_p);

		switch (in->scankeys[i].sk_strategy)
		{
			case RTLeftStrategyNumber:
                                res = (bool) box2df_left(datum_p, query_p);
				break;
			case RTRightStrategyNumber:
                                res = (bool) box2df_right(datum_p, query_p);
				break;
			case RTSameStrategyNumber:
                                res = (bool) box2df_equals(datum_p, query_p);
				break;
			case RTBelowStrategyNumber:
                                res = (bool) box2df_below(datum_p, query_p);
				break;
			case RTAboveStrategyNumber:
                                res = (bool) box2df_above(datum_p, query_p);
				break;
			case RTContainedByStrategyNumber:
                                res = (bool) box2df_contains(query_p, datum_p);
				break;
			default:
				elog(ERROR, "unrecognized strategy number: %d",
					 in->scankeys[i].sk_strategy);
				break;
		}

		if (!res)
			break;
	}

	PG_RETURN_BOOL(res);
}
/**
* Calculate the box->box distance.
*/
static double box2df_distance(const BOX2DF *a, const BOX2DF *b)
{
    /* Check for overlap */
    if ( box2df_overlaps(a, b) )
        return 0.0;

    if ( box2df_left(a, b) )
    {
        if ( box2df_above(a, b) )
			return pt_distance(a->xmax, a->ymin, b->xmin, b->ymax);
		if ( box2df_below(a, b) )
			return pt_distance(a->xmax, a->ymax, b->xmin, b->ymin);
		else
			return b->xmin - a->xmax;
	}
	if ( box2df_right(a, b) )
	{
        if ( box2df_above(a, b) )
			return pt_distance(a->xmin, a->ymin, b->xmax, b->ymax);
		if ( box2df_below(a, b) )
			return pt_distance(a->xmin, a->ymax, b->xmax, b->ymin);
		else
			return a->xmin - b->xmax;
	}
	if ( box2df_above(a, b) )
	{
		if ( box2df_left(a, b) )
			return pt_distance(a->xmax, a->ymin, b->xmin, b->ymax);
		if ( box2df_right(a, b) )
			return pt_distance(a->xmin, a->ymin, b->xmax, b->ymax);
		else
			return a->ymin - b->ymax;
	}
	if ( box2df_below(a, b) )
	{
		if ( box2df_left(a, b) )
			return pt_distance(a->xmax, a->ymax, b->xmin, b->ymin);
		if ( box2df_right(a, b) )
			return pt_distance(a->xmin, a->ymax, b->xmax, b->ymin);
		else
			return b->ymin - a->ymax;
	}
	
	return MAXFLOAT;
}
示例#3
0
static inline bool gserialized_gist_consistent_leaf_2d(BOX2DF *key, BOX2DF *query, StrategyNumber strategy)
{
	bool retval;
	
	switch (strategy)
	{

	/* Basic overlaps */
	case RTOverlapStrategyNumber:
		retval = (bool) box2df_overlaps(key, query);
		break;
	case RTSameStrategyNumber:
		retval = (bool) box2df_equals(key, query);
		break;
	case RTContainsStrategyNumber:
	case RTOldContainsStrategyNumber:
		retval = (bool) box2df_contains(key, query);
		break;
	case RTContainedByStrategyNumber:
	case RTOldContainedByStrategyNumber:
		retval = (bool) box2df_contains(query, key);
		break;
		
	/* To one side */
	case RTAboveStrategyNumber:
		retval = (bool) box2df_above(key, query);
		break;
	case RTBelowStrategyNumber:
		retval = (bool) box2df_below(key, query);
		break;
	case RTRightStrategyNumber:
		retval = (bool) box2df_right(key, query);
		break;
	case RTLeftStrategyNumber:
		retval = (bool) box2df_left(key, query);
		break;

	/* Overlapping to one side */
	case RTOverAboveStrategyNumber:
		retval = (bool) box2df_overabove(key, query);
		break;
	case RTOverBelowStrategyNumber:
		retval = (bool) box2df_overbelow(key, query);
		break;
	case RTOverRightStrategyNumber:
		retval = (bool) box2df_overright(key, query);
		break;
	case RTOverLeftStrategyNumber:
		retval = (bool) box2df_overleft(key, query);
		break;		
		
	default:
		retval = FALSE;
	}

	return (retval);
}
示例#4
0
文件: spgist.c 项目: ahinz/postgis
Datum
spgist_geom_inner_consistent(PG_FUNCTION_ARGS)
{
	spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0);
	spgInnerConsistentOut *out = (spgInnerConsistentOut *) PG_GETARG_POINTER(1);
        BOX2DF *centroidbox_p;
	int which;
	int i;
   
	if (in->allTheSame)
	{
		/* Report that all nodes should be visited */
		out->nNodes = in->nNodes;
		out->nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes);
		for (i = 0; i < in->nNodes; i++)
			out->nodeNumbers[i] = i;
		PG_RETURN_VOID();
	}

	Assert(in->hasPrefix);

        centroidbox_p = (BOX2DF *)in->prefixDatum;

	Assert(in->nNodes == 4);

	/* "which" is a bitmask of quadrants that satisfy all constraints */
	which = (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4);

	for (i = 0; i < in->nkeys; i++)
	{
                BOX2DF box;
                BOX2DF *box_p = &box;
                gserialized_datum_get_box2df_p(in->scankeys[i].sk_argument, box_p);

		switch (in->scankeys[i].sk_strategy)
		{
			case RTLeftStrategyNumber:
                                if (box2df_left(box_p, centroidbox_p))
                                        which &= (1 << 3) | (1 << 4);
				break;
			case RTRightStrategyNumber:
                                if (box2df_right(box_p, centroidbox_p))
					which &= (1 << 1) | (1 << 2);
				break;
			/* case RTSameStrategyNumber: */
			/* 	which &= (1 << getQuadrant(centroidbox_p, box_p)); */
			/* 	break; */
			case RTBelowStrategyNumber:
                                if (box2df_below(centroidbox_p, box_p))
					which &= (1 << 2) | (1 << 3);
				break;
			case RTAboveStrategyNumber:
                                if (box2df_above(centroidbox_p, box_p))
					which &= (1 << 1) | (1 << 4);
				break;
			case RTContainedByStrategyNumber:

                                if (box2df_contains(box_p, centroidbox_p))
				{
					/* centroid is in box, so all quadrants are OK */
				}
				else
				{
					/* identify quadrant(s) containing all corners of box */
					POINT2D	p;
                                        BOX2DF b;
                                        BOX2DF *b_p = &b;
					int r = 0;

                                        b_p->xmin = b_p->xmax = box_p->xmin;
                                        b_p->ymin = b_p->ymax = box_p->ymin;

					r |= 1 << getQuadrant(centroidbox_p, b_p);

                                        b_p->xmin = b_p->xmax = box_p->xmax;
                                        b_p->ymin = b_p->ymax = box_p->ymin;

					r |= 1 << getQuadrant(centroidbox_p, b_p);

                                        b_p->xmin = b_p->xmax = box_p->xmax;
                                        b_p->ymin = b_p->ymax = box_p->ymax;

					r |= 1 << getQuadrant(centroidbox_p, b_p);

                                        b_p->xmin = b_p->xmax = box_p->xmin;
                                        b_p->ymin = b_p->ymax = box_p->ymax;

					r |= 1 << getQuadrant(centroidbox_p, b_p);

					which &= r;
				}
				break;
			default:
				elog(ERROR, "unrecognized strategy number: %d",
					 in->scankeys[i].sk_strategy);
				break;
		}

		if (which == 0)
			break;				/* no need to consider remaining conditions */
	}

	/* We must descend into the quadrant(s) identified by which */
	out->nodeNumbers = (int *) palloc(sizeof(int) * 4);
	out->nNodes = 0;
	for (i = 1; i <= 4; i++)
	{
		if (which & (1 << i))
			out->nodeNumbers[out->nNodes++] = i - 1;
	}

	PG_RETURN_VOID();
}