From: David Blasby Date: Mon, 26 Apr 2004 23:12:08 +0000 (+0000) Subject: inital version X-Git-Tag: pgis_0_8_2~50 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=158039c21784c5f536ae35dd222b49a737e50d9a;p=postgis inital version git-svn-id: http://svn.osgeo.org/postgis/trunk@509 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/lwgeom/lwgeom_box2dfloat4.c b/lwgeom/lwgeom_box2dfloat4.c new file mode 100644 index 000000000..02a1230b4 --- /dev/null +++ b/lwgeom/lwgeom_box2dfloat4.c @@ -0,0 +1,289 @@ +#include "postgres.h" + +#include +#include +#include +#include +#include + +#include "access/gist.h" +#include "access/itup.h" +#include "access/rtree.h" + +#include "fmgr.h" +#include "utils/elog.h" + + +#include "lwgeom.h" +#include "stringBuffer.h" + + +#define DEBUG + + + //forward defs +Datum BOX2DFLOAT4_in(PG_FUNCTION_ARGS); +Datum BOX2DFLOAT4_out(PG_FUNCTION_ARGS); +Datum LWGEOM_to_BOX2DFLOAT4(PG_FUNCTION_ARGS); + + + +PG_FUNCTION_INFO_V1(BOX2DFLOAT4_in); +Datum BOX2DFLOAT4_in(PG_FUNCTION_ARGS) +{ + char *str = PG_GETARG_CSTRING(0); + int nitems; + BOX2DFLOAT4 *box = (BOX2DFLOAT4 *) palloc(sizeof(BOX2DFLOAT4)); + + + +//printf( "box3d_in gets '%s'\n",str); + + if (strstr(str,"BOX(") != str ) + { + pfree(box); + elog(ERROR,"BOX2DFLOAT4 parser - doesnt start with BOX("); + PG_RETURN_NULL(); + } + nitems = sscanf(str,"BOX(%f %f,%f %f)", &box->xmin,&box->ymin,&box->xmax,&box->ymax); + if (nitems != 4) + { + pfree(box); + elog(ERROR,"BOX2DFLOAT4 parser - couldnt parse. It should look like: BOX(xmin ymin,xmax ymax)"); + PG_RETURN_NULL(); + } + + if (box->xmin > box->xmax) + { + float tmp = box->xmin; + box->xmin = box->xmax; + box->xmax = tmp; + } + if (box->ymin > box->ymax) + { + float tmp = box->ymin; + box->ymin = box->ymax; + box->ymax = tmp; + } + PG_RETURN_POINTER(box); +} + +PG_FUNCTION_INFO_V1(BOX2DFLOAT4_out); +Datum BOX2DFLOAT4_out(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + char tmp[500]; // big enough + char *result; + int size; + + size = sprintf(tmp,"BOX(%.15g %.15g,%.15g %.15g)", box->xmin, box->ymin, box->xmax, box->ymax); + + result= palloc(size+1); // +1= null term + + memcpy(result,tmp,size+1); + PG_RETURN_CSTRING(result); +} + + + +PG_FUNCTION_INFO_V1(LWGEOM_to_BOX2DFLOAT4); +Datum LWGEOM_to_BOX2DFLOAT4(PG_FUNCTION_ARGS) +{ + char *lwgeom = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + BOX2DFLOAT4 box, *result; + + box = getbox2d(lwgeom+4); + result = palloc(sizeof(BOX2DFLOAT4)); + memcpy(result,&box, sizeof(BOX2DFLOAT4)); + PG_RETURN_POINTER(result); +} + +/*---------------------------------------------------------- + * Relational operators for BOXes. + * <, >, <=, >=, and == are based on box area. + *---------------------------------------------------------*/ + +/* box_same - are two boxes identical? + */ +PG_FUNCTION_INFO_V1(box2d_same); +Datum box2d_same(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPeq(box1->xmax, box2->xmax) && + FPeq(box1->xmin, box2->xmin) && + FPeq(box1->ymax, box2->ymax) && + FPeq(box1->ymin, box2->ymin)); +} + +/* box_overlap - does box1 overlap box2? + */ +PG_FUNCTION_INFO_V1(box2d_overlap); +Datum box2d_overlap(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + bool result; + + + result = ((FPge(box1->xmax, box2->xmax) && + FPle(box1->xmin, box2->xmax)) || + (FPge(box2->xmax, box1->xmax) && + FPle(box2->xmin, box1->xmax))) + && + ((FPge(box1->ymax, box2->ymax) && + FPle(box1->ymin, box2->ymax)) || + (FPge(box2->ymax, box1->ymax) && + FPle(box2->ymin, box1->ymax))); + + PG_RETURN_BOOL(result); +} + + +/* box_overleft - is the right edge of box1 to the left of + * the right edge of box2? + * + * This is "less than or equal" for the end of a time range, + * when time ranges are stored as rectangles. + */ + PG_FUNCTION_INFO_V1(box2d_overleft); +Datum box2d_overleft(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPle(box1->xmax, box2->xmax)); +} + +/* box_left - is box1 strictly left of box2? + */ + PG_FUNCTION_INFO_V1(box2d_left); +Datum box2d_left(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPlt(box1->xmax, box2->xmin)); +} + +/* box_right - is box1 strictly right of box2? + */ + PG_FUNCTION_INFO_V1(box2d_right); +Datum box2d_right(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPgt(box1->xmin, box2->xmax)); +} + +/* box_overright - is the left edge of box1 to the right of + * the left edge of box2? + * + * This is "greater than or equal" for time ranges, when time ranges + * are stored as rectangles. + */ + PG_FUNCTION_INFO_V1(box2d_overright); +Datum box2d_overright(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPge(box1->xmin, box2->xmin)); +} + +/* box_contained - is box1 contained by box2? + */ + PG_FUNCTION_INFO_V1(box2d_contained); +Datum box2d_contained(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 =(BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPle(box1->xmax, box2->xmax) && + FPge(box1->xmin, box2->xmin) && + FPle(box1->ymax, box2->ymax) && + FPge(box1->ymin, box2->ymin)); +} + +/* box_contain - does box1 contain box2? + */ + PG_FUNCTION_INFO_V1(box2d_contain); +Datum box2d_contain(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *box1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *box2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(FPge(box1->xmax, box2->xmax) && + FPle(box1->xmin, box2->xmin) && + FPge(box1->ymax, box2->ymax) && + FPle(box1->ymin, box2->ymin)); + +} + +PG_FUNCTION_INFO_V1(box2d_inter); +Datum box2d_inter(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *a = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *b = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + BOX2DFLOAT4 *n; + + + n = (BOX2DFLOAT4 *) palloc(sizeof(BOX2DFLOAT4)); + + n->xmax = LWGEOM_Minf(a->xmax, b->xmax); + n->ymax = LWGEOM_Minf(a->ymax, b->ymax); + n->xmin = LWGEOM_Maxf(a->xmin, b->xmin); + n->ymin = LWGEOM_Maxf(a->ymin, b->ymin); + + + if (n->xmax < n->xmin || n->ymax < n->ymin) + { + pfree(n); + /* Indicate "no intersection" by returning NULL pointer */ + n = NULL; + } + + PG_RETURN_POINTER(n); +} + +PG_FUNCTION_INFO_V1(box2d_union); +Datum box2d_union(PG_FUNCTION_ARGS) +{ + BOX2DFLOAT4 *a = (BOX2DFLOAT4*) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *b = (BOX2DFLOAT4*) PG_GETARG_POINTER(1); + BOX2DFLOAT4 *n; + + n = (BOX2DFLOAT4 *) palloc(sizeof(BOX2DFLOAT4)); + + + n->xmax = LWGEOM_Maxf(a->xmax, b->xmax); + n->ymax = LWGEOM_Maxf(a->ymax, b->ymax); + n->xmin = LWGEOM_Minf(a->xmin, b->xmin); + n->ymin = LWGEOM_Minf(a->ymin, b->ymin); + + + PG_RETURN_POINTER(n); +} + + + +float LWGEOM_Minf(float a, float b) +{ + if (aa) + return b; + return a; +} + + + +