Пример #1
0
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);
}
Пример #2
0
Datum
spgist_geom_choose(PG_FUNCTION_ARGS)
{
	spgChooseIn *in = (spgChooseIn *) PG_GETARG_POINTER(0);
	spgChooseOut *out = (spgChooseOut *) PG_GETARG_POINTER(1);

        BOX2DF inputbox;
        BOX2DF *inputbox_p = &inputbox;
        BOX2DF *centroidbox_p;

        gserialized_datum_get_box2df_p(in->datum, inputbox_p);

	if (in->allTheSame)
	{
		out->resultType = spgMatchNode;
		/* nodeN will be set by core */
		out->result.matchNode.levelAdd = 0;
		out->result.matchNode.restDatum = in->datum;

		PG_RETURN_VOID();
	}

	Assert(in->hasPrefix);
	Assert(in->nNodes == 4);

        centroidbox_p = (BOX2DF *)in->prefixDatum;

	out->resultType = spgMatchNode;
	out->result.matchNode.nodeN = getQuadrant(centroidbox_p, inputbox_p) - 1;
	out->result.matchNode.levelAdd = 0;
	out->result.matchNode.restDatum = in->datum;

	PG_RETURN_VOID();
}
Пример #3
0
/**
* Support function. Based on two datums return true if
* they satisfy the predicate and false otherwise.
*/
static int 
gserialized_datum_predicate_2d(Datum gs1, Datum gs2, box2df_predicate predicate)
{
	BOX2DF b1, b2, *br1=NULL, *br2=NULL;
	POSTGIS_DEBUG(3, "entered function");

	if (gserialized_datum_get_box2df_p(gs1, &b1) == LW_SUCCESS) br1 = &b1;
	if (gserialized_datum_get_box2df_p(gs2, &b2) == LW_SUCCESS) br2 = &b2;

	if ( predicate(br1, br2) )
	{
		POSTGIS_DEBUGF(3, "got boxes %s and %s", br1 ? box2df_to_string(&b1) : "(null)", br2 ? box2df_to_string(&b2) : "(null)");
		return LW_TRUE;
	}
	return LW_FALSE;
}
Пример #4
0
/**
* Support function. Based on two datums return true if
* they satisfy the predicate and false otherwise.
*/
static int 
gserialized_datum_predicate_2d(Datum gs1, Datum gs2, box2df_predicate predicate)
{
	BOX2DF b1, b2;
	POSTGIS_DEBUG(3, "entered function");

	/* Must be able to build box for each argument (ie, not empty geometry)
	   and overlap boxes to return true. */
	if ( (gserialized_datum_get_box2df_p(gs1, &b1) == LW_SUCCESS) &&
	     (gserialized_datum_get_box2df_p(gs2, &b2) == LW_SUCCESS) &&
	      predicate(&b1, &b2) )
	{
		POSTGIS_DEBUGF(3, "got boxes %s and %s", box2df_to_string(&b1), box2df_to_string(&b2));
		return LW_TRUE;
	}
	return LW_FALSE;
}
Пример #5
0
Datum gserialized_gist_consistent_2d(PG_FUNCTION_ARGS)
{
	GISTENTRY *entry = (GISTENTRY*) PG_GETARG_POINTER(0);
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
	bool result;
	BOX2DF query_gbox_index;

#if POSTGIS_PGSQL_VERSION >= 84
	/* PostgreSQL 8.4 and later require the RECHECK flag to be set here,
	   rather than being supplied as part of the operator class definition */
	bool *recheck = (bool *) PG_GETARG_POINTER(4);

	/* We set recheck to false to avoid repeatedly pulling every "possibly matched" geometry
	   out during index scans. For cases when the geometries are large, rechecking
	   can make things twice as slow. */
	*recheck = false;
#endif

	POSTGIS_DEBUG(4, "[GIST] 'consistent' function called");

	/* Quick sanity check on query argument. */
	if ( DatumGetPointer(PG_GETARG_DATUM(1)) == NULL )
	{
		POSTGIS_DEBUG(4, "[GIST] null query pointer (!?!), returning false");
		PG_RETURN_BOOL(FALSE); /* NULL query! This is screwy! */
	}

	/* Quick sanity check on entry key. */
	if ( DatumGetPointer(entry->key) == NULL )
	{
		POSTGIS_DEBUG(4, "[GIST] null index entry, returning false");
		PG_RETURN_BOOL(FALSE); /* NULL entry! */
	}

	/* Null box should never make this far. */
	if ( gserialized_datum_get_box2df_p(PG_GETARG_DATUM(1), &query_gbox_index) == LW_FAILURE )
	{
		POSTGIS_DEBUG(4, "[GIST] null query_gbox_index!");
		PG_RETURN_BOOL(FALSE);
	}

	/* Treat leaf node tests different from internal nodes */
	if (GIST_LEAF(entry))
	{
		result = gserialized_gist_consistent_leaf_2d(
		             (BOX2DF*)DatumGetPointer(entry->key),
		             &query_gbox_index, strategy);
	}
	else
	{
		result = gserialized_gist_consistent_internal_2d(
		             (BOX2DF*)DatumGetPointer(entry->key),
		             &query_gbox_index, strategy);
	}

	PG_RETURN_BOOL(result);
}
Пример #6
0
Datum gserialized_distance_box_2d(PG_FUNCTION_ARGS)
{
	BOX2DF b1, b2;
	Datum gs1 = PG_GETARG_DATUM(0);
	Datum gs2 = PG_GETARG_DATUM(1);    
	
	POSTGIS_DEBUG(3, "entered function");

	/* Must be able to build box for each argument (ie, not empty geometry). */
	if ( (gserialized_datum_get_box2df_p(gs1, &b1) == LW_SUCCESS) &&
	     (gserialized_datum_get_box2df_p(gs2, &b2) == LW_SUCCESS) )
	{	    
		double distance = box2df_distance(&b1, &b2);
		POSTGIS_DEBUGF(3, "got boxes %s and %s", box2df_to_string(&b1), box2df_to_string(&b2));
		PG_RETURN_FLOAT8(distance);
	}
	PG_RETURN_FLOAT8(MAXFLOAT);
}
Пример #7
0
Datum
spgist_geom_picksplit(PG_FUNCTION_ARGS)
{
	spgPickSplitIn *in = (spgPickSplitIn *) PG_GETARG_POINTER(0);
	spgPickSplitOut *out = (spgPickSplitOut *) PG_GETARG_POINTER(1);
	int i;
        double x, y;
        BOX2DF *centroidbox_p;

	/* Use the average values of x and y as the centroid point */
        x = 0;
        y = 0;

	for (i = 0; i < in->nTuples; i++)
	{
          LWPOINT *apt = (LWPOINT *)lwgeom_from_gserialized((GSERIALIZED *)in->datums[i]);

          x += lwpoint_get_x(apt);
          y += lwpoint_get_y(apt);

          lwpoint_free(apt);
	}

	x /= in->nTuples;
	y /= in->nTuples;
        
        centroidbox_p = palloc(sizeof(BOX2DF));

        centroidbox_p->xmin = x;
        centroidbox_p->xmax = x;
        centroidbox_p->ymin = y;
        centroidbox_p->ymax = y;

	out->hasPrefix = true;
	out->prefixDatum = PointerGetDatum(centroidbox_p);

	out->nNodes = 4;
	out->nodeLabels = NULL;		/* we don't need node labels */

	out->mapTuplesToNodes = palloc(sizeof(int) * in->nTuples);
	out->leafTupleDatums = palloc(sizeof(Datum) * in->nTuples);

	for (i = 0; i < in->nTuples; i++)
	{
                BOX2DF box;
                gserialized_datum_get_box2df_p(in->datums[i], &box);

		int quadrant = getQuadrant(centroidbox_p, &box) - 1;

		out->leafTupleDatums[i] = PointerGetDatum(in->datums[i]);
		out->mapTuplesToNodes[i] = quadrant;
	}

	PG_RETURN_VOID();
}
Пример #8
0
Datum gserialized_gist_distance_2d(PG_FUNCTION_ARGS)
{
	GISTENTRY *entry = (GISTENTRY*) PG_GETARG_POINTER(0);
	BOX2DF query_box;
	BOX2DF *entry_box;
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
	double distance;

	POSTGIS_DEBUG(4, "[GIST] 'distance' function called");

    /* We are using '13' as the gist distance-betweeen-centroids strategy number 
    *  and '14' as the gist distance-between-boxes strategy number */
    if ( strategy != 13 && strategy != 14 ) {
        elog(ERROR, "unrecognized strategy number: %d", strategy);
		PG_RETURN_FLOAT8(MAXFLOAT);
	}

	/* Null box should never make this far. */
	if ( gserialized_datum_get_box2df_p(PG_GETARG_DATUM(1), &query_box) == LW_FAILURE )
	{
		POSTGIS_DEBUG(4, "[GIST] null query_gbox_index!");
		PG_RETURN_FLOAT8(MAXFLOAT);
	}

	/* Get the entry box */
    entry_box = (BOX2DF*)DatumGetPointer(entry->key);
	
	/* Box-style distance test */
	if ( strategy == 14 )
	{
		distance = (double)box2df_distance(entry_box, &query_box);
		PG_RETURN_FLOAT8(distance);
	}

	/* Treat leaf node tests different from internal nodes */
	if (GIST_LEAF(entry))
	{
	    /* Calculate distance to leaves */
		distance = (double)box2df_distance_leaf_centroid(entry_box, &query_box);
	}
	else
	{
	    /* Calculate distance for internal nodes */
		distance = (double)box2df_distance_node_centroid(entry_box, &query_box);
	}

	PG_RETURN_FLOAT8(distance);
}
Пример #9
0
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();
}
Пример #10
0
Datum WTBtree_consistent(PG_FUNCTION_ARGS)
{	
	printf("------------------consistent\n");

	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);	
	void	   *query = (void *) DatumGetTextP(PG_GETARG_DATUM(1));
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
	bool		result;	
	/* Oid		subtype = PG_GETARG_OID(3); */
	
/*
GBT_VARKEY *orge = (GBT_VARKEY *) DatumGetPointer(entry->key);
GBT_VARKEY_R ok;

ok = gbt_var_key_readable(orge);

printf("ok.lower : %s\n", ok.lower);
printf("VARDATA(ok.lower) : %s\n", VARDATA(ok.lower));
printf("VARDATA(ok.upper) : %s\n", VARDATA(ok.upper));

printf("VARDATA_4B(ok.lower) : %s\n", VARDATA_4B(ok.lower));
printf("VARDATA_4B(ok.upper) : %s\n", VARDATA_4B(ok.upper));

*/
printf("strategy : %d\n", strategy);


char* temp;
temp = (char*) palloc(12);

memcpy(temp, "wx4fccknzng3", 12);

GeoCoord gCoord = geohash_decode(temp);

printf("gCoord.north : %lf\n", gCoord.north);
printf("gCoord.east : %lf\n", gCoord.east);
printf("gCoord.south : %lf\n", gCoord.south);
printf("gCoord.west : %lf\n", gCoord.west);

BOX2DF* tbox;
tbox = (BOX2DF*) palloc(sizeof(BOX2DF));

tbox->xmin = (float) gCoord.west;
tbox->ymin = (float) gCoord.south;
tbox->xmax = (float) gCoord.east;
tbox->ymax = (float) gCoord.north;


printf("temp : %s\n", temp);


BOX2DF query_gbox_index;
	gserialized_datum_get_box2df_p(query, &query_gbox_index);

	if (GIST_LEAF(entry))
	{
		result = gserialized_gist_consistent_leaf_2d(tbox,
		             &query_gbox_index, strategy);
	}
	else
	{
		result = gserialized_gist_consistent_internal_2d(tbox,
		             &query_gbox_index, strategy);
	}

/*
	BOX2DF query_gbox_index;
	gserialized_datum_get_box2df_p(query, &query_gbox_index);

	if (GIST_LEAF(entry))
	{
		result = gserialized_gist_consistent_leaf_2d(
		             (BOX2DF*)DatumGetPointer(entry->key),
		             &query_gbox_index, strategy);
	}
	else
	{
		result = gserialized_gist_consistent_internal_2d(
		             (BOX2DF*)DatumGetPointer(entry->key),
		             &query_gbox_index, strategy);
	}

*/

/*
	int size = 12;
	char *minPnt, *maxPnt, *cvtGeoHash;

	minPnt = (char*) palloc(size);
	maxPnt = (char*) palloc(size);
	cvtGeoHash = (char*) palloc(size);

	
	memcpy(minPnt, geohash_encode((double) query_gbox_index.ymin, (double) query_gbox_index.xmin, size), size);
	memcpy(maxPnt, geohash_encode((double) query_gbox_index.ymax, (double) query_gbox_index.xmax, size), size);

	cvtGeoHash = convert_GeoHash_from_box2d(minPnt, maxPnt, size);

	printf("-----------geohash_encode : %s\n", cvtGeoHash);	
*/
	/* PostgreSQL 8.4 and later require the RECHECK flag to be set here,
	   rather than being supplied as part of the operator class definition */

/*
	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);

	LEAF_KEY key;

	memcpy(key, DatumGetPointer(entry->key), KEY_SIZE);

	INTERNAL_KEY *ikey = leafKey_to_internaKey(key);	


	*recheck = false;
*/	


	PG_RETURN_BOOL(result);
}
Пример #11
0
Datum gserialized_gist_compress_2d(PG_FUNCTION_ARGS)
{
	GISTENTRY *entry_in = (GISTENTRY*)PG_GETARG_POINTER(0);
	GISTENTRY *entry_out = NULL;
	BOX2DF bbox_out;
	int result = LW_SUCCESS;

	POSTGIS_DEBUG(4, "[GIST] 'compress' function called");

	/*
	** Not a leaf key? There's nothing to do.
	** Return the input unchanged.
	*/
	if ( ! entry_in->leafkey )
	{
		POSTGIS_DEBUG(4, "[GIST] non-leafkey entry, returning input unaltered");
		PG_RETURN_POINTER(entry_in);
	}

	POSTGIS_DEBUG(4, "[GIST] processing leafkey input");
	entry_out = palloc(sizeof(GISTENTRY));

	/*
	** Null key? Make a copy of the input entry and
	** return.
	*/
	if ( DatumGetPointer(entry_in->key) == NULL )
	{
		POSTGIS_DEBUG(4, "[GIST] leafkey is null");
		gistentryinit(*entry_out, (Datum) 0, entry_in->rel,
		              entry_in->page, entry_in->offset, FALSE);
		POSTGIS_DEBUG(4, "[GIST] returning copy of input");
		PG_RETURN_POINTER(entry_out);
	}

	/* Extract our index key from the GiST entry. */
	result = gserialized_datum_get_box2df_p(entry_in->key, &bbox_out);

	/* Is the bounding box valid (non-empty, non-infinite)? If not, return input uncompressed. */
	if ( result == LW_FAILURE )
	{
		POSTGIS_DEBUG(4, "[GIST] empty geometry!");
		PG_RETURN_POINTER(entry_in);
	}

	POSTGIS_DEBUGF(4, "[GIST] got entry_in->key: %s", box2df_to_string(&bbox_out));

	/* Check all the dimensions for finite values */
	if ( ! finite(bbox_out.xmax) || ! finite(bbox_out.xmin) ||
	     ! finite(bbox_out.ymax) || ! finite(bbox_out.ymin) )
	{
		POSTGIS_DEBUG(4, "[GIST] infinite geometry!");
		PG_RETURN_POINTER(entry_in);
	}

	/* Enure bounding box has minimums below maximums. */
	box2df_validate(&bbox_out);

	/* Prepare GISTENTRY for return. */
	gistentryinit(*entry_out, PointerGetDatum(box2df_copy(&bbox_out)),
	              entry_in->rel, entry_in->page, entry_in->offset, FALSE);

	/* Return GISTENTRY. */
	POSTGIS_DEBUG(4, "[GIST] 'compress' function complete");
	PG_RETURN_POINTER(entry_out);
}