From: Sandro Santilli Date: Fri, 8 Oct 2004 13:20:55 +0000 (+0000) Subject: Changed LWGEOM structure to point to an actual BOX2DFLOAT4. X-Git-Tag: pgis_1_0_0RC1~311 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b6bd12924666b43f612e1ed5e36d9847a4fa5dd8;p=postgis Changed LWGEOM structure to point to an actual BOX2DFLOAT4. Renamed most function to reflect a TYPE_method naming convention. (you'll need a dump/reload for it to work) Added more manipulation functions. git-svn-id: http://svn.osgeo.org/postgis/trunk@967 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/lwgeom/liblwgeom.h b/lwgeom/liblwgeom.h index a9c102506..4817123a3 100644 --- a/lwgeom/liblwgeom.h +++ b/lwgeom/liblwgeom.h @@ -1,12 +1,16 @@ #ifndef _LIBLWGEOM_H #define _LIBLWGEOM_H 1 +#include + +#define INTEGRITY_CHECKS 1 +//#define DEBUG_ALLOCS 1 + //liblwgeom.h //#define DEBUG 1 //#define DEBUG_CALLS 1 - typedef void* (*lwallocator)(size_t size); typedef void* (*lwreallocator)(void *mem, size_t size); typedef void (*lwfreeor)(void* mem); @@ -148,6 +152,7 @@ typedef struct typedef struct { unsigned char type; + BOX2DFLOAT4 *bbox; uint32 SRID; // -1 == unneeded void *data; } LWGEOM; @@ -155,7 +160,8 @@ typedef struct // POINTYPE typedef struct { - int type; // POINTTYPE + unsigned char type; // POINTTYPE + BOX2DFLOAT4 *bbox; uint32 SRID; POINTARRAY *point; // hide 2d/3d (this will be an array of 1 point) } LWPOINT; // "light-weight point" @@ -163,7 +169,8 @@ typedef struct // LINETYPE typedef struct { - int type; // LINETYPE + unsigned char type; // LINETYPE + BOX2DFLOAT4 *bbox; uint32 SRID; POINTARRAY *points; // array of POINT3D } LWLINE; //"light-weight line" @@ -171,7 +178,8 @@ typedef struct // POLYGONTYPE typedef struct { - int type; // POLYGONTYPE + unsigned char type; // POLYGONTYPE + BOX2DFLOAT4 *bbox; uint32 SRID; int nrings; POINTARRAY **rings; // list of rings (list of points) @@ -181,6 +189,7 @@ typedef struct typedef struct { unsigned char type; + BOX2DFLOAT4 *bbox; uint32 SRID; int ngeoms; LWPOINT **geoms; @@ -190,6 +199,7 @@ typedef struct typedef struct { unsigned char type; + BOX2DFLOAT4 *bbox; uint32 SRID; int ngeoms; LWLINE **geoms; @@ -199,6 +209,7 @@ typedef struct typedef struct { unsigned char type; + BOX2DFLOAT4 *bbox; uint32 SRID; int ngeoms; LWPOLY **geoms; @@ -208,28 +219,41 @@ typedef struct typedef struct { unsigned char type; + BOX2DFLOAT4 *bbox; uint32 SRID; int ngeoms; LWGEOM **geoms; } LWCOLLECTION; // Casts LWGEOM->LW* (return NULL if cast is illegal) -LWMPOLY *lwgeom_as_lwmpoly(LWGEOM *lwgeom); -LWMLINE *lwgeom_as_lwmline(LWGEOM *lwgeom); -LWMPOINT *lwgeom_as_lwmpoint(LWGEOM *lwgeom); -LWCOLLECTION *lwgeom_as_lwcollection(LWGEOM *lwgeom); -LWPOLY *lwgeom_as_lwpoly(LWGEOM *lwgeom); -LWLINE *lwgeom_as_lwline(LWGEOM *lwgeom); -LWPOINT *lwgeom_as_lwpoint(LWGEOM *lwgeom); +extern LWMPOLY *lwgeom_as_lwmpoly(LWGEOM *lwgeom); +extern LWMLINE *lwgeom_as_lwmline(LWGEOM *lwgeom); +extern LWMPOINT *lwgeom_as_lwmpoint(LWGEOM *lwgeom); +extern LWCOLLECTION *lwgeom_as_lwcollection(LWGEOM *lwgeom); +extern LWPOLY *lwgeom_as_lwpoly(LWGEOM *lwgeom); +extern LWLINE *lwgeom_as_lwline(LWGEOM *lwgeom); +extern LWPOINT *lwgeom_as_lwpoint(LWGEOM *lwgeom); // Casts LW*->LWGEOM (always cast) -LWGEOM *lwmpoly_as_lwgeom(LWMPOLY *obj); -LWGEOM *lwmline_as_lwgeom(LWMLINE *obj); -LWGEOM *lwmpoint_as_lwgeom(LWMPOINT *obj); -LWGEOM *lwcollection_as_lwgeom(LWCOLLECTION *obj); -LWGEOM *lwpoly_as_lwgeom(LWPOLY *obj); -LWGEOM *lwline_as_lwgeom(LWLINE *obj); -LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj); +extern LWGEOM *lwmpoly_as_lwgeom(LWMPOLY *obj); +extern LWGEOM *lwmline_as_lwgeom(LWMLINE *obj); +extern LWGEOM *lwmpoint_as_lwgeom(LWMPOINT *obj); +extern LWGEOM *lwcollection_as_lwgeom(LWCOLLECTION *obj); +extern LWGEOM *lwpoly_as_lwgeom(LWPOLY *obj); +extern LWGEOM *lwline_as_lwgeom(LWLINE *obj); +extern LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj); + +// Call this function everytime LWGEOM coordinates +// change so to invalidate bounding box +extern void lwgeom_changed(LWGEOM *lwgeom); + +// Call this function to drop BBOX and SRID +// from LWGEOM. If LWGEOM type is *not* flagged +// with the HASBBOX flag and has a bbox, it +// will be released. +extern void lwgeom_dropBBOX(LWGEOM *lwgeom); +extern void lwgeom_dropSRID(LWGEOM *lwgeom); + //------------------------------------------------------------- // copies a point from the point array into the parameter point @@ -400,10 +424,6 @@ extern size_t lwgeom_size_poly(const char *serialized_line); // bounding box finder and (TODO) serialized form size finder. //-------------------------------------------------------- -// construct a new point. point will NOT be copied -// use SRID=-1 for unknown SRID (will have 8bit type's S = 0) -extern LWPOINT *lwpoint_construct(int SRID, char wantbbox, POINTARRAY *point); - // given the LWPOINT serialized form (or a pointer into a muli* one) // construct a proper LWPOINT. // serialized_form should point to the 8bit type format (with type = 1) @@ -432,9 +452,6 @@ extern int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out); //-------------------------------------------------------- -// construct a new LWLINE. points will *NOT* be copied -// use SRID=-1 for unknown SRID (will have 8bit type's S = 0) -extern LWLINE *lwline_construct(int SRID, char wantbbox, POINTARRAY *points); // given the LWGEOM serialized form (or a pointer into a muli* one) // construct a proper LWLINE. @@ -458,9 +475,6 @@ extern BOX3D *lwline_findbbox(LWLINE *line); //-------------------------------------------------------- -// construct a new LWPOLY. arrays (points/points per ring) will NOT be copied -// use SRID=-1 for unknown SRID (will have 8bit type's S = 0) -extern LWPOLY *lwpoly_construct(int SRID, char wantbbox, unsigned int nrings, POINTARRAY **points); // given the LWPOLY serialized form (or a pointer into a muli* one) // construct a proper LWPOLY. @@ -693,20 +707,22 @@ extern BOX3D *combine_boxes(BOX3D *b1, BOX3D *b2); // WARNING! the EMPTY geom will result in a random BOX2D returned extern BOX2DFLOAT4 getbox2d(char *serialized_form); +// Returns a pointer to the BBOX internal to the serialized form. +// READ-ONLY! +// Or NULL if serialized form does not have a BBOX +extern BOX2DFLOAT4 *getbox2d_internal(char *serialized_form); + // this function writes to 'box' and returns 0 if serialized_form // does not have a bounding box (empty geom) extern int getbox2d_p(char *serialized_form, BOX2DFLOAT4 *box); -// this function returns a pointer to the 'internal' bounding -// box of a serialized-form geometry. If the geometry does -// not have an embedded bounding box the function returns NULL. -// READ-ONLY! -extern const BOX2DFLOAT4 * getbox2d_internal(char *serialized_form); - // Expand given box of 'd' units in all directions void expand_box2d(BOX2DFLOAT4 *box, double d); void expand_box3d(BOX3D *box, double d); +// Check if to boxes are equal (considering FLOAT approximations) +char box2d_same(BOX2DFLOAT4 *box1, BOX2DFLOAT4 *box2); + //**************************************************************** // memory management -- these only delete the memory associated // directly with the structure - NOT the stuff pointing into @@ -912,6 +928,7 @@ extern void lwgeom_forceRHR(LWGEOM *lwgeom); extern char *lwgeom_summary(LWGEOM *lwgeom, int offset); extern const char *lwgeom_typename(int type); extern int ptarray_compute_bbox_p(const POINTARRAY *pa, BOX2DFLOAT4 *result); +extern BOX2DFLOAT4 *ptarray_compute_bbox(const POINTARRAY *pa); extern int lwpoint_compute_bbox_p(LWPOINT *point, BOX2DFLOAT4 *box); extern int lwline_compute_bbox_p(LWLINE *line, BOX2DFLOAT4 *box); extern int lwpoly_compute_bbox_p(LWPOLY *poly, BOX2DFLOAT4 *box); @@ -923,12 +940,14 @@ extern BOX2DFLOAT4 *box2d_union(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2); // args may overlap ! extern int box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox); extern int lwgeom_compute_bbox_p(LWGEOM *lwgeom, BOX2DFLOAT4 *box); +// is lwgeom1 geometrically equal to lwgeom2 ? +char lwgeom_same(LWGEOM *lwgeom1, LWGEOM *lwgeom2); // Add 'what' to 'to' at position 'where'. // where=0 == prepend // where=-1 == append // Mix of dimensions is not allowed (TODO: allow it?). -// Returns a newly allocated LWGEOM +// Returns a newly allocated LWGEOM (with NO BBOX) extern LWGEOM *lwgeom_add(const LWGEOM *to, uint32 where, const LWGEOM *what); LWGEOM *lwpoint_add(const LWPOINT *to, uint32 where, const LWGEOM *what); @@ -939,14 +958,26 @@ LWGEOM *lwmline_add(const LWMLINE *to, uint32 where, const LWGEOM *what); LWGEOM *lwmpoint_add(const LWMPOINT *to, uint32 where, const LWGEOM *what); LWGEOM *lwcollection_add(const LWCOLLECTION *to, uint32 where, const LWGEOM *what); -// Clone an LWGEOM (pointarray are not copied) +// Clone an LWGEOM +// pointarray are not copied. +// BBOXes are copied only if HASBBOX flag is 0 (meaning bbox ownership) extern LWGEOM *lwgeom_clone(const LWGEOM *lwgeom); extern LWPOINT *lwpoint_clone(const LWPOINT *lwgeom); extern LWLINE *lwline_clone(const LWLINE *lwgeom); extern LWPOLY *lwpoly_clone(const LWPOLY *lwgeom); extern LWCOLLECTION *lwcollection_clone(const LWCOLLECTION *lwgeom); - -extern LWCOLLECTION *lwcollection_construct(unsigned int type, int SRID, char hasbbox, unsigned int ngeoms, LWGEOM **geoms); +extern BOX2DFLOAT4 *box2d_clone(const BOX2DFLOAT4 *lwgeom); + +// Geometry constructors +// Take ownership of arguments +extern LWPOINT *lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox, + POINTARRAY *point); +extern LWLINE *lwline_construct(int SRID, BOX2DFLOAT4 *bbox, + POINTARRAY *points); +extern LWPOLY *lwpoly_construct(int SRID, BOX2DFLOAT4 *bbox, + unsigned int nrings, POINTARRAY **points); +extern LWCOLLECTION *lwcollection_construct(unsigned int type, int SRID, + BOX2DFLOAT4 *bbox, unsigned int ngeoms, LWGEOM **geoms); // Return a char string with ASCII versionf of type flags extern const char *lwgeom_typeflags(unsigned char type); diff --git a/lwgeom/lwcollection.c b/lwgeom/lwcollection.c index 5887a0781..4ccec4814 100644 --- a/lwgeom/lwcollection.c +++ b/lwgeom/lwcollection.c @@ -8,7 +8,7 @@ #define CHECK_LWGEOM_ZM 1 LWCOLLECTION * -lwcollection_construct(unsigned int type, int SRID, char hasbbox, +lwcollection_construct(unsigned int type, int SRID, BOX2DFLOAT4 *bbox, unsigned int ngeoms, LWGEOM **geoms) { LWCOLLECTION *ret; @@ -37,10 +37,12 @@ lwcollection_construct(unsigned int type, int SRID, char hasbbox, ret = lwalloc(sizeof(LWCOLLECTION)); ret->type = lwgeom_makeType_full(hasz, hasm, (SRID!=-1), - type, hasbbox); + type, 0); ret->SRID = SRID; ret->ngeoms = ngeoms; ret->geoms = geoms; + ret->bbox = bbox; + return ret; } @@ -69,6 +71,11 @@ lwcollection_deserialize(char *srl) result->ngeoms = insp->ngeometries; result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries); + if (lwgeom_hasBBOX(srl[0])) + result->bbox = (BOX2DFLOAT4 *)(srl+1); + else result->bbox = NULL; + + for (i=0; ingeometries; i++) { result->geoms[i] = lwgeom_deserialize(insp->sub_geoms[i]); @@ -91,7 +98,7 @@ lwcollection_serialize_size(LWCOLLECTION *col) int i; if ( col->SRID != -1 ) size += 4; // SRID - if ( TYPE_HASBBOX(col->type) ) size += sizeof(BOX2DFLOAT4); + if ( col->bbox ) size += sizeof(BOX2DFLOAT4); #ifdef DEBUG_CALLS lwnotice("lwcollection_serialize_size[%p]: start size: %d", col, size); @@ -134,13 +141,13 @@ lwcollection_serialize_buf(LWCOLLECTION *coll, char *buf, size_t *retsize) buf[0] = (unsigned char) lwgeom_makeType_full( TYPE_HASZ(coll->type), TYPE_HASM(coll->type), - hasSRID, TYPE_GETTYPE(coll->type), TYPE_HASBBOX(coll->type)); + hasSRID, TYPE_GETTYPE(coll->type), coll->bbox ? 1 : 0); loc = buf+1; // Add BBOX if requested - if ( TYPE_HASBBOX(coll->type) ) + if ( coll->bbox ) { - lwgeom_compute_bbox_p((LWGEOM *)coll, (BOX2DFLOAT4 *)loc); + memcpy(loc, coll->bbox, sizeof(BOX2DFLOAT4)); size += sizeof(BOX2DFLOAT4); loc += sizeof(BOX2DFLOAT4); } @@ -200,6 +207,8 @@ lwcollection_clone(const LWCOLLECTION *g) { ret->geoms[i] = lwgeom_clone(g->geoms[i]); } + if ( g->bbox && ! TYPE_HASBBOX(g->type) ) + ret->bbox = box2d_clone(g->bbox); return ret; } @@ -229,16 +238,21 @@ lwcollection_add(const LWCOLLECTION *to, uint32 where, const LWGEOM *what) for (i=0; igeoms[i]); + lwgeom_dropSRID(geoms[i]); + lwgeom_dropBBOX(geoms[i]); } geoms[where] = lwgeom_clone(what); + lwgeom_dropSRID(geoms[where]); + lwgeom_dropBBOX(geoms[where]); for (i=where; ingeoms; i++) { geoms[i+1] = lwgeom_clone(to->geoms[i]); + lwgeom_dropSRID(geoms[i+1]); + lwgeom_dropBBOX(geoms[i+1]); } col = lwcollection_construct(COLLECTIONTYPE, - to->SRID, - ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->SRID, NULL, to->ngeoms+1, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwgeom.c b/lwgeom/lwgeom.c index 01226413c..389709673 100644 --- a/lwgeom/lwgeom.c +++ b/lwgeom/lwgeom.c @@ -13,6 +13,8 @@ lwgeom_deserialize(char *srl) { int type = lwgeom_getType(srl[0]); + lwnotice("lwgeom_deserialize got %s", lwgeom_typename(type)); + switch (type) { case POINTTYPE: @@ -219,7 +221,8 @@ lwgeom_as_lwpoly(LWGEOM *lwgeom) LWCOLLECTION * lwgeom_as_lwcollection(LWGEOM *lwgeom) { - if ( lwgeom->type >= MULTIPOINTTYPE ) return (LWCOLLECTION *)lwgeom; + if ( TYPE_GETTYPE(lwgeom->type) >= MULTIPOINTTYPE ) + return (LWCOLLECTION *)lwgeom; else return NULL; } @@ -258,6 +261,11 @@ lwgeom_release(LWGEOM *lwgeom) uint32 i; LWCOLLECTION *col; +#ifdef INTEGRITY_CHECKS + if ( ! lwgeom ) + lwerror("lwgeom_release: someone called on 0x0"); +#endif + // Collection if ( (col=lwgeom_as_lwcollection(lwgeom)) ) { @@ -342,3 +350,54 @@ lwgeom_to_wkt(LWGEOM *lwgeom) return ret; } +// geom1 same as geom2 +// iff +// + have same type // + have same # objects +// + have same bvol +// + each object in geom1 has a corresponding object in geom2 (see above) +// +char +lwgeom_same(LWGEOM *lwgeom1, LWGEOM *lwgeom2) +{ + if ( TYPE_GETTYPE(lwgeom1->type) != TYPE_GETTYPE(lwgeom2->type) ) + return 0; + + if ( TYPE_GETZM(lwgeom1->type) != TYPE_GETZM(lwgeom2->type) ) + return 0; + + // Check boxes if both already computed + if ( lwgeom1->bbox && lwgeom2->bbox ) + { + lwnotice("bbox1:%p, bbox2:%p", lwgeom1->bbox, lwgeom2->bbox); + if ( ! box2d_same(lwgeom1->bbox, lwgeom2->bbox) ) return 0; + } + + lwnotice("geometry_same only checked for type,dims and boxes"); + return 1; +} + +void +lwgeom_changed(LWGEOM *lwgeom) +{ + // HASBBOX flag on LWGEOM type means the BBOX is not + // owned by LWGEOM + if ( lwgeom->bbox && ! TYPE_HASBBOX(lwgeom->type) ) + lwfree(lwgeom->bbox); + lwgeom->bbox = NULL; + TYPE_SETHASBBOX(lwgeom->type, 0); +} + +void +lwgeom_dropBBOX(LWGEOM *lwgeom) +{ + if ( lwgeom->bbox && ! TYPE_HASBBOX(lwgeom->type) ) + lwfree(lwgeom->bbox); + lwgeom->bbox = NULL; +} + +void +lwgeom_dropSRID(LWGEOM *lwgeom) +{ + TYPE_SETHASSRID(lwgeom->type, 0); + lwgeom->SRID = -1; +} diff --git a/lwgeom/lwgeom_api.c b/lwgeom/lwgeom_api.c index 1843813aa..817c64b92 100644 --- a/lwgeom/lwgeom_api.c +++ b/lwgeom/lwgeom_api.c @@ -167,7 +167,8 @@ double nextUp_d(float d) // Convert BOX3D to BOX2D // returned box2d is allocated with 'lwalloc' -BOX2DFLOAT4 *box3d_to_box2df(BOX3D *box) +BOX2DFLOAT4 * +box3d_to_box2df(BOX3D *box) { BOX2DFLOAT4 *result = (BOX2DFLOAT4*) lwalloc(sizeof(BOX2DFLOAT4)); @@ -189,7 +190,8 @@ BOX2DFLOAT4 *box3d_to_box2df(BOX3D *box) // Convert BOX3D to BOX2D using pre-allocated BOX2D // returned box2d is allocated with 'lwalloc' // return 0 on error (NULL input box) -int box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *result) +int +box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *result) { if (box == NULL) { @@ -210,7 +212,8 @@ int box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *result) // convert BOX2D to BOX3D // zmin and zmax are set to 0.0 -BOX3D box2df_to_box3d(BOX2DFLOAT4 *box) +BOX3D +box2df_to_box3d(BOX2DFLOAT4 *box) { BOX3D result; @@ -230,7 +233,8 @@ BOX3D box2df_to_box3d(BOX2DFLOAT4 *box) // convert BOX2D to BOX3D, using pre-allocated BOX3D as output // Z values are set to 0.0. -void box2df_to_box3d_p(BOX2DFLOAT4 *box, BOX3D *out) +void +box2df_to_box3d_p(BOX2DFLOAT4 *box, BOX3D *out) { if (box == NULL) return; @@ -308,7 +312,8 @@ BOX3D *combine_boxes(BOX3D *b1, BOX3D *b2) // returns a real entity so it doesnt leak // if this has a pre-built BOX2d, then we use it, // otherwise we need to compute it. -BOX2DFLOAT4 getbox2d(char *serialized_form) +BOX2DFLOAT4 +getbox2d(char *serialized_form) { int type = (unsigned char) serialized_form[0]; char *loc; @@ -347,6 +352,15 @@ BOX2DFLOAT4 getbox2d(char *serialized_form) return result; } +// returns a pointer to internal storage, or NULL +// if the serialized form does not have a BBOX. +BOX2DFLOAT4 * +getbox2d_internal(char *srl) +{ + if (TYPE_HASBBOX(srl[0])) return (BOX2DFLOAT4 *)(srl+1); + else return NULL; +} + // same as getbox2d, but modifies box instead of returning result on the stack int getbox2d_p(char *serialized_form, BOX2DFLOAT4 *box) @@ -406,21 +420,6 @@ getbox2d_p(char *serialized_form, BOX2DFLOAT4 *box) return 1; } -// this function returns a pointer to the 'internal' bounding -// box of a serialized-form geometry. If the geometry does -// not have an embedded bounding box the function returns NULL. -// READ-ONLY! -const BOX2DFLOAT4 * -getbox2d_internal(char *serialized_form) -{ - unsigned char type = (unsigned char) serialized_form[0]; - - // No embedded bounding box ... - if (!lwgeom_hasBBOX(type)) return NULL; - - return (BOX2DFLOAT4 *)(serialized_form+1); -} - //************************************************************************ // POINTARRAY support functions @@ -753,35 +752,6 @@ pointArray_bbox(const POINTARRAY *pa) return result; } -// calculate the 2d bounding box of a set of points -// write result to the provided BOX2DFLOAT4 -// Return 0 if bounding box is NULL (empty geom) -int -ptarray_compute_bbox_p(const POINTARRAY *pa, BOX2DFLOAT4 *result) -{ - int t; - POINT2D *pt; - - if (pa->npoints == 0) return 0; - - pt = (POINT2D *)getPoint(pa, 0); - - result->xmin = pt->x; - result->xmax = pt->x; - result->ymin = pt->y; - result->ymax = pt->y; - - for (t=1;tnpoints;t++) - { - pt = (POINT2D *)getPoint(pa, t); - if (pt->x < result->xmin) result->xmin = pt->x; - if (pt->y < result->ymin) result->ymin = pt->y; - if (pt->x > result->xmax) result->xmax = pt->x; - if (pt->y > result->ymax) result->ymax = pt->y; - } - - return 1; -} //size of point represeneted in the POINTARRAY // 16 for 2d, 24 for 3d, 32 for 4d diff --git a/lwgeom/lwgeom_box2dfloat4.c b/lwgeom/lwgeom_box2dfloat4.c index e673cb02a..3ebd58ceb 100644 --- a/lwgeom/lwgeom_box2dfloat4.c +++ b/lwgeom/lwgeom_box2dfloat4.c @@ -118,8 +118,8 @@ Datum LWGEOM_to_BOX2DFLOAT4(PG_FUNCTION_ARGS) /* box_same - are two boxes identical? */ -PG_FUNCTION_INFO_V1(box2d_same); -Datum box2d_same(PG_FUNCTION_ARGS) +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); @@ -132,8 +132,8 @@ Datum box2d_same(PG_FUNCTION_ARGS) /* box_overlap - does box1 overlap box2? */ -PG_FUNCTION_INFO_V1(box2d_overlap); -Datum box2d_overlap(PG_FUNCTION_ARGS) +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); @@ -160,8 +160,8 @@ Datum box2d_overlap(PG_FUNCTION_ARGS) * 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) + 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); @@ -171,8 +171,8 @@ Datum box2d_overleft(PG_FUNCTION_ARGS) /* box_left - is box1 strictly left of box2? */ - PG_FUNCTION_INFO_V1(box2d_left); -Datum box2d_left(PG_FUNCTION_ARGS) + 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); @@ -182,8 +182,8 @@ Datum box2d_left(PG_FUNCTION_ARGS) /* box_right - is box1 strictly right of box2? */ - PG_FUNCTION_INFO_V1(box2d_right); -Datum box2d_right(PG_FUNCTION_ARGS) + 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); @@ -197,8 +197,8 @@ Datum box2d_right(PG_FUNCTION_ARGS) * 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) + 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); @@ -208,8 +208,8 @@ Datum box2d_overright(PG_FUNCTION_ARGS) /* box_contained - is box1 contained by box2? */ - PG_FUNCTION_INFO_V1(box2d_contained); -Datum box2d_contained(PG_FUNCTION_ARGS) + 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); @@ -222,8 +222,8 @@ Datum box2d_contained(PG_FUNCTION_ARGS) /* box_contain - does box1 contain box2? */ - PG_FUNCTION_INFO_V1(box2d_contain); -Datum box2d_contain(PG_FUNCTION_ARGS) + 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); @@ -235,30 +235,30 @@ Datum box2d_contain(PG_FUNCTION_ARGS) } -PG_FUNCTION_INFO_V1(box2d_inter); -Datum box2d_inter(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(BOX2D_intersects); +Datum BOX2D_intersects(PG_FUNCTION_ARGS) { - BOX2DFLOAT4 *a = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); - BOX2DFLOAT4 *b = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); - BOX2DFLOAT4 *n; + BOX2DFLOAT4 *a = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *b = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); + BOX2DFLOAT4 *n; - n = (BOX2DFLOAT4 *) palloc(sizeof(BOX2DFLOAT4)); + 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); + 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; - } + 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_RETURN_POINTER(n); } @@ -287,23 +287,10 @@ float LWGEOM_Minf(float a, float b) //max(a,b) float LWGEOM_Maxf(float a, float b) { - if (b>a) - return b; + if (b>a) return b; return a; } - -/* Expand given box of 'd' units in all directions */ -void -expand_box2d(BOX2DFLOAT4 *box, double d) -{ - box->xmin -= d; - box->ymin -= d; - - box->xmax += d; - box->ymax += d; -} - PG_FUNCTION_INFO_V1(BOX2DFLOAT4_expand); Datum BOX2DFLOAT4_expand(PG_FUNCTION_ARGS) { @@ -434,7 +421,7 @@ Datum BOX2DFLOAT4_to_LWGEOM(PG_FUNCTION_ARGS) pa[0]->npoints = 5; // Construct polygon - poly = lwpoly_construct(-1, wantbbox, 1, pa); + poly = lwpoly_construct(-1, NULL, 1, pa); // Serialize polygon ser = lwpoly_serialize(poly); diff --git a/lwgeom/lwgeom_box3d.c b/lwgeom/lwgeom_box3d.c index 6b83276fe..972be7dd7 100644 --- a/lwgeom/lwgeom_box3d.c +++ b/lwgeom/lwgeom_box3d.c @@ -180,7 +180,7 @@ Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS) pa[0]->npoints = 5; // Construct polygon - poly = lwpoly_construct(-1, wantbbox, 1, pa); + poly = lwpoly_construct(-1, NULL, 1, pa); // Serialize polygon ser = lwpoly_serialize(poly); diff --git a/lwgeom/lwgeom_chip.c b/lwgeom/lwgeom_chip.c index c1e2c3a2d..3ed77408d 100644 --- a/lwgeom/lwgeom_chip.c +++ b/lwgeom/lwgeom_chip.c @@ -180,7 +180,7 @@ Datum CHIP_to_LWGEOM(PG_FUNCTION_ARGS) pa[0]->npoints = 5; // Construct polygon - poly = lwpoly_construct(chip->SRID, wantbbox, 1, pa); + poly = lwpoly_construct(chip->SRID, NULL, 1, pa); // Serialize polygon ser = lwpoly_serialize(poly); diff --git a/lwgeom/lwgeom_estimate.c b/lwgeom/lwgeom_estimate.c index 0db0dc1d5..478395856 100644 --- a/lwgeom/lwgeom_estimate.c +++ b/lwgeom/lwgeom_estimate.c @@ -10,6 +10,12 @@ * ********************************************************************** * $Log$ + * Revision 1.9 2004/10/08 13:20:54 strk + * Changed LWGEOM structure to point to an actual BOX2DFLOAT4. + * Renamed most function to reflect a TYPE_method naming convention. + * (you'll need a dump/reload for it to work) + * Added more manipulation functions. + * * Revision 1.8 2004/10/05 21:54:48 strk * Yes another change in SPI_cursor_open * @@ -142,9 +148,9 @@ Datum create_lwhistogram2d(PG_FUNCTION_ARGS); Datum build_lwhistogram2d(PG_FUNCTION_ARGS); Datum explode_lwhistogram2d(PG_FUNCTION_ARGS); Datum estimate_lwhistogram2d(PG_FUNCTION_ARGS); -Datum lwgeom_gist_sel(PG_FUNCTION_ARGS); +Datum LWGEOM_gist_sel(PG_FUNCTION_ARGS); #if USE_VERSION >= 80 -Datum lwgeom_analyze(PG_FUNCTION_ARGS); +Datum LWGEOM_analyze(PG_FUNCTION_ARGS); #endif //text form of LWHISTOGRAM2D is: @@ -803,8 +809,8 @@ get_restriction_var(List *args, int varRelid, Var **var, } //restriction in the GiST && operator -PG_FUNCTION_INFO_V1(lwgeom_gist_sel); -Datum lwgeom_gist_sel(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_gist_sel); +Datum LWGEOM_gist_sel(PG_FUNCTION_ARGS) { Query *root = (Query *) PG_GETARG_POINTER(0); List *args = (List *) PG_GETARG_POINTER(2); @@ -832,7 +838,7 @@ Datum lwgeom_gist_sel(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(DEFAULT_GEOMETRY_SEL); #endif - //elog(NOTICE,"lwgeom_gist_sel was called"); + //elog(NOTICE,"LWGEOM_gist_sel was called"); if (!get_restriction_var(args, varRelid, &var, &other, &varonleft)) { @@ -881,7 +887,7 @@ Datum lwgeom_gist_sel(PG_FUNCTION_ARGS) SPIcode = SPI_connect(); if (SPIcode != SPI_OK_CONNECT) { - elog(NOTICE,"lwgeom_gist_sel: couldnt open a connection to SPI:%i",SPIcode); + elog(NOTICE,"LWGEOM_gist_sel: couldnt open a connection to SPI:%i",SPIcode); PG_RETURN_FLOAT8(DEFAULT_GEOMETRY_SEL) ; } @@ -891,14 +897,14 @@ Datum lwgeom_gist_sel(PG_FUNCTION_ARGS) if (SPIcode != SPI_OK_SELECT ) { SPI_finish(); - elog(NOTICE,"lwgeom_gist_sel: couldnt execute sql via SPI"); + elog(NOTICE,"LWGEOM_gist_sel: couldnt execute sql via SPI"); PG_RETURN_FLOAT8(DEFAULT_GEOMETRY_SEL) ; } if (SPI_processed !=1) { SPI_finish(); - //elog(NOTICE,"lwgeom_gist_sel: geometry_columns didnt return a unique value"); + //elog(NOTICE,"LWGEOM_gist_sel: geometry_columns didnt return a unique value"); PG_RETURN_FLOAT8(DEFAULT_GEOMETRY_SEL) ; } @@ -909,28 +915,28 @@ Datum lwgeom_gist_sel(PG_FUNCTION_ARGS) if (isnull) { SPI_finish(); - //elog(NOTICE,"lwgeom_gist_sel: geometry_columns returned a null histogram"); + //elog(NOTICE,"LWGEOM_gist_sel: geometry_columns returned a null histogram"); PG_RETURN_FLOAT8(DEFAULT_GEOMETRY_SEL) ; } -//elog(NOTICE,"lwgeom_gist_sel: checking against estimate_histogram2d"); +//elog(NOTICE,"LWGEOM_gist_sel: checking against estimate_histogram2d"); // now we have the histogram, and our search box - use the estimate_histogram2d(histo,box) to get the result! myest = DatumGetFloat8( DirectFunctionCall2( estimate_lwhistogram2d, datum, PointerGetDatum(&search_box) ) ); if ( (myest<0) || (myest!=myest) ) // <0? or NaN? { - //elog(NOTICE,"lwgeom_gist_sel: got something crazy back from estimate_histogram2d"); + //elog(NOTICE,"LWGEOM_gist_sel: got something crazy back from estimate_histogram2d"); PG_RETURN_FLOAT8(DEFAULT_GEOMETRY_SEL) ; } SPIcode =SPI_finish(); if (SPIcode != SPI_OK_FINISH ) { - //elog(NOTICE,"lwgeom_gist_sel: couldnt disconnect from SPI"); + //elog(NOTICE,"LWGEOM_gist_sel: couldnt disconnect from SPI"); PG_RETURN_FLOAT8(DEFAULT_GEOMETRY_SEL) ; } -//elog(NOTICE,"lwgeom_gist_sel: finished, returning with %lf",myest); +//elog(NOTICE,"LWGEOM_gist_sel: finished, returning with %lf",myest); PG_RETURN_FLOAT8(myest); } @@ -1182,8 +1188,8 @@ elog(NOTICE, " avg feat overlaps %f cells", avg_feat_cells); * This is the one used for PG version >= 7.5 * */ -PG_FUNCTION_INFO_V1(lwgeom_gist_sel); -Datum lwgeom_gist_sel(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_gist_sel); +Datum LWGEOM_gist_sel(PG_FUNCTION_ARGS) { Query *root = (Query *) PG_GETARG_POINTER(0); //Oid operator = PG_GETARG_OID(1); @@ -1200,14 +1206,14 @@ Datum lwgeom_gist_sel(PG_FUNCTION_ARGS) float8 selectivity=0; #if DEBUG_GEOMETRY_STATS - elog(NOTICE, "lwgeom_gist_sel called"); + elog(NOTICE, "LWGEOM_gist_sel called"); #endif /* Fail if not a binary opclause (probably shouldn't happen) */ if (list_length(args) != 2) { #if DEBUG_GEOMETRY_STATS - elog(NOTICE, "lwgeom_gist_sel: not a binary opclause"); + elog(NOTICE, "LWGEOM_gist_sel: not a binary opclause"); #endif PG_RETURN_FLOAT8(DEFAULT_GEOMETRY_SEL); } @@ -1851,8 +1857,8 @@ compute_geometry_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, * value for now. * */ -PG_FUNCTION_INFO_V1(lwgeom_analyze); -Datum lwgeom_analyze(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_analyze); +Datum LWGEOM_analyze(PG_FUNCTION_ARGS) { VacAttrStats *stats = (VacAttrStats *)PG_GETARG_POINTER(0); Form_pg_attribute attr = stats->attr; diff --git a/lwgeom/lwgeom_functions_analytic.c b/lwgeom/lwgeom_functions_analytic.c index e859b0323..21cc62400 100644 --- a/lwgeom/lwgeom_functions_analytic.c +++ b/lwgeom/lwgeom_functions_analytic.c @@ -175,7 +175,7 @@ simplify2d_lwline(LWLINE *iline, double dist) ipts = iline->points; opts = DP_simplify2d(ipts, dist); - oline = lwline_construct(iline->SRID, TYPE_HASBBOX(iline->type), opts); + oline = lwline_construct(iline->SRID, NULL, opts); return oline; } @@ -244,11 +244,7 @@ elog(NOTICE, "simplify_polygon3d: simplified polygon with %d rings", norings); if ( ! norings ) return NULL; - opoly = palloc(sizeof(LWPOLY)); - opoly->type = ipoly->type; - opoly->SRID = ipoly->SRID; - opoly->nrings = norings; - opoly->rings = orings; + opoly = lwpoly_construct(ipoly->SRID, NULL, norings, orings); return opoly; } diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index 19b11a06c..509c5031a 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -2627,13 +2627,13 @@ Datum LWGEOM_expand(PG_FUNCTION_ARGS) pa[0]->npoints = 5; // Construct polygon - poly = lwpoly_construct(SRID, lwgeom_hasBBOX(geom->type), 1, pa); + poly = lwpoly_construct(SRID, box2d_clone(&box), 1, pa); // Serialize polygon ser = lwpoly_serialize(poly); // Construct PG_LWGEOM - result = PG_LWGEOM_construct(ser, SRID, lwgeom_hasBBOX(geom->type)); + result = PG_LWGEOM_construct(ser, SRID, 1); PG_RETURN_POINTER(result); } @@ -2694,13 +2694,13 @@ Datum LWGEOM_envelope(PG_FUNCTION_ARGS) pa[0]->npoints = 5; // Construct polygon - poly = lwpoly_construct(SRID, lwgeom_hasBBOX(geom->type), 1, pa); + poly = lwpoly_construct(SRID, box2d_clone(&box), 1, pa); // Serialize polygon ser = lwpoly_serialize(poly); // Construct PG_LWGEOM - result = PG_LWGEOM_construct(ser, SRID, lwgeom_hasBBOX(geom->type)); + result = PG_LWGEOM_construct(ser, SRID, 1); PG_RETURN_POINTER(result); } @@ -2768,7 +2768,7 @@ Datum centroid(PG_FUNCTION_ARGS) pa = pointArray_construct((char *)¢, 1, 0, 1); // Construct LWPOINT - point = lwpoint_construct(SRID, wantbbox, pa); + point = lwpoint_construct(SRID, NULL, pa); // Serialize LWPOINT srl = lwpoint_serialize(point); @@ -2970,3 +2970,35 @@ Datum LWGEOM_zmflag(PG_FUNCTION_ARGS) if ( TYPE_HASM(type) ) ret += 1; PG_RETURN_INT16(ret); } + +// lwgeom_same(lwgeom1, lwgeom2) +PG_FUNCTION_INFO_V1(LWGEOM_same); +Datum LWGEOM_same(PG_FUNCTION_ARGS) +{ + PG_LWGEOM *g1 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + PG_LWGEOM *g2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + LWGEOM *lwg1, *lwg2; + bool result; + + if ( TYPE_GETTYPE(g1->type) != TYPE_GETTYPE(g2->type) ) + PG_RETURN_BOOL(FALSE); // different types + + if ( TYPE_GETZM(g1->type) != TYPE_GETZM(g2->type) ) + PG_RETURN_BOOL(FALSE); // different dimensions + + // ok, deserialize. + lwg1 = lwgeom_deserialize(SERIALIZED_FORM(g1)); + lwg2 = lwgeom_deserialize(SERIALIZED_FORM(g2)); + + // invoke appropriate function + result = lwgeom_same(lwg1, lwg2); + + // Relase memory + lwgeom_release(lwg1); + lwgeom_release(lwg2); + PG_FREE_IF_COPY(g1, 0); + PG_FREE_IF_COPY(g2, 1); + + PG_RETURN_BOOL(result); +} + diff --git a/lwgeom/lwgeom_geos.c b/lwgeom/lwgeom_geos.c index b6fdc925a..9eb7de1b6 100644 --- a/lwgeom/lwgeom_geos.c +++ b/lwgeom/lwgeom_geos.c @@ -43,7 +43,7 @@ Datum centroid(PG_FUNCTION_ARGS); * Define this to have have many notices printed * during postgis->geos and geos->postgis conversions */ -#undef DEBUG_CONVERTER +//#undef DEBUG_CONVERTER #ifdef DEBUG_CONVERTER #define DEBUG_POSTGIS2GEOS 1 #define DEBUG_GEOS2POSTGIS 1 @@ -1900,7 +1900,7 @@ lwpoint_from_geometry(Geometry *g, char want3d) GEOSdeleteChar( (char*) pts); // Construct LWPOINT - point = lwpoint_construct(-1, 0, pa); + point = lwpoint_construct(-1, NULL, pa); return point; } @@ -1940,7 +1940,7 @@ lwline_from_geometry(Geometry *g, char want3d) GEOSdeleteChar( (char*) pts); // Construct LWPOINT - line = lwline_construct(-1, 0, pa); + line = lwline_construct(-1, NULL, pa); return line; } @@ -2006,7 +2006,7 @@ lwpoly_from_geometry(Geometry *g, char want3d) } // Construct LWPOLY - poly = lwpoly_construct(-1, 0, nrings+1, rings); + poly = lwpoly_construct(-1, NULL, nrings+1, rings); return poly; } @@ -2020,7 +2020,6 @@ lwcollection_from_geometry(Geometry *geom, char want3d) LWCOLLECTION *ret; int type = GEOSGeometryTypeId(geom) ; int SRID = GEOSGetSRID(geom); - char wantbbox = 0; int i; ngeoms = GEOSGetNumGeometries(geom); @@ -2044,7 +2043,7 @@ lwcollection_from_geometry(Geometry *geom, char want3d) #endif } - ret = lwcollection_construct(type, SRID, wantbbox, ngeoms, geoms); + ret = lwcollection_construct(type, SRID, NULL, ngeoms, geoms); return ret; } @@ -2195,6 +2194,11 @@ POSTGIS2GEOS(PG_LWGEOM *geom) { Geometry *ret; LWGEOM *lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom)); + if ( ! lwgeom ) + { + lwerror("POSTGIS2GEOS: unable to deserialize input"); + return NULL; + } ret = LWGEOM2GEOS(lwgeom); lwgeom_release(lwgeom); return ret; diff --git a/lwgeom/lwgeom_geos_wrapper.cpp b/lwgeom/lwgeom_geos_wrapper.cpp index a6ca4ae58..8be873902 100644 --- a/lwgeom/lwgeom_geos_wrapper.cpp +++ b/lwgeom/lwgeom_geos_wrapper.cpp @@ -22,12 +22,10 @@ int MAXIMUM_ALIGNOF = -999999; // to be set during initialization - this will #define TYPEALIGN(ALIGNVAL,LEN) (((long)(LEN) + (ALIGNVAL-1)) & ~(ALIGNVAL-1)) #define MAXALIGN(LEN) TYPEALIGN(MAXIMUM_ALIGNOF, (LEN)) -typedef int int32; - - //---- Definitions found in lwgeom.h (and postgis) #define TYPE_NDIMS(t) ((((t)&0x20)>>5)+(((t)&0x10)>>4)+2) +#define TYPE_HASZ(t) ( ((t)&0x20)>>5 ) typedef unsigned int uint32; typedef int int32; @@ -38,18 +36,21 @@ typedef struct double xmax, ymax, zmax; } BOX3D; +typedef struct { float xmin, ymin, xmax, ymax; } BOX2DFLOAT4; + typedef struct { double x,y,z; } POINT3D; typedef struct { char *serialized_pointlist; - char ndims; + unsigned char dims; uint32 npoints; } POINTARRAY; typedef struct { unsigned char type; + BOX2DFLOAT4 *bbox; uint32 SRID; POINTARRAY *point; // hide 2d/3d (this will be an array of 1 point) } LWPOINT; // "light-weight point" @@ -58,6 +59,7 @@ typedef struct typedef struct { unsigned char type; + BOX2DFLOAT4 *bbox; uint32 SRID; POINTARRAY *points; // array of POINT3D } LWLINE; //"light-weight line" @@ -66,6 +68,7 @@ typedef struct typedef struct { unsigned char type; + BOX2DFLOAT4 *bbox; uint32 SRID; int nrings; POINTARRAY **rings; // list of rings (list of points) @@ -148,7 +151,7 @@ extern "C" Geometry *GEOSpointonSurface(Geometry *g1); extern "C" Geometry *GEOSGetCentroid(Geometry *g1); -extern "C" void lwnotice(char *msg); +extern "C" void NOTICE_MESSAGE(char *msg); @@ -203,7 +206,7 @@ Geometry *PostGIS2GEOS_box3d(BOX3D *box, int SRID) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete cl; return NULL; } @@ -223,18 +226,18 @@ Geometry *PostGIS2GEOS_point(const LWPOINT *lwpoint) #ifdef DEBUG_POSTGIS2GEOS char buf[256]; sprintf(buf, "PostGIS2GEOS_point got lwpoint[%p]", lwpoint); - lwnotice(buf); + NOTICE_MESSAGE(buf); #endif if ( lwpoint == NULL ) { - lwnotice("PostGIS2GEOS_point got a NULL lwpoint"); + NOTICE_MESSAGE("PostGIS2GEOS_point got a NULL lwpoint"); return NULL; } point = (POINT3D *)getPoint(lwpoint->point, 0); SRID = lwpoint->SRID; - is3d = lwpoint->point->ndims > 2 ? 1 : 0; + is3d = TYPE_HASZ(lwpoint->type); try { @@ -253,7 +256,7 @@ Geometry *PostGIS2GEOS_point(const LWPOINT *lwpoint) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -271,13 +274,13 @@ Geometry * PostGIS2GEOS_linestring(const LWLINE *lwline) { POINTARRAY *pa = lwline->points; - bool is3d = pa->ndims > 2 ? 1 : 0; + bool is3d = TYPE_HASZ(pa->dims); int SRID = lwline->SRID; #ifdef DEBUG_POSTGIS2GEOS char buf[256]; sprintf(buf, "PostGIS2GEOS_line got lwline[%p]", lwline); - lwnotice(buf); + NOTICE_MESSAGE(buf); #endif try{ @@ -338,7 +341,7 @@ PostGIS2GEOS_linestring(const LWLINE *lwline) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -353,12 +356,12 @@ Geometry *PostGIS2GEOS_polygon(const LWPOLY *lwpoly) { POINTARRAY *pa; int SRID = lwpoly->SRID; - bool is3d = TYPE_NDIMS(lwpoly->type) > 2 ? 1 : 0; + bool is3d = TYPE_HASZ(lwpoly->type); #ifdef DEBUG_POSTGIS2GEOS char buf[256]; sprintf(buf, "PostGIS2GEOS_poly got lwpoly[%p]", lwpoly); - lwnotice(buf); + NOTICE_MESSAGE(buf); #endif try @@ -491,7 +494,7 @@ Geometry *PostGIS2GEOS_polygon(const LWPOLY *lwpoly) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -528,7 +531,7 @@ Geometry *PostGIS2GEOS_multipoint(LWPOINT **geoms, uint32 ngeoms, int SRID, bool } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -565,7 +568,7 @@ Geometry *PostGIS2GEOS_multilinestring(LWLINE **geoms, uint32 ngeoms, int SRID, } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -602,7 +605,7 @@ Geometry *PostGIS2GEOS_multipolygon(LWPOLY **polygons, uint32 npolys, int SRID, } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -619,7 +622,7 @@ Geometry *PostGIS2GEOS_collection(int type, Geometry **geoms, int ngeoms, int SR char buf[256]; sprintf(buf, "PostGIS2GEOS_collection: requested type %d, ngeoms: %d", type, ngeoms); - lwnotice(buf); + NOTICE_MESSAGE(buf); #endif try @@ -648,7 +651,7 @@ Geometry *PostGIS2GEOS_collection(int type, Geometry **geoms, int ngeoms, int SR g = geomFactory->createMultiPolygon(subGeos); break; default: - lwnotice("Unsupported type request for PostGIS2GEOS_collection"); + NOTICE_MESSAGE("Unsupported type request for PostGIS2GEOS_collection"); g = NULL; } @@ -662,7 +665,7 @@ Geometry *PostGIS2GEOS_collection(int type, Geometry **geoms, int ngeoms, int SR } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -688,7 +691,7 @@ char GEOSrelateDisjoint(Geometry *g1, Geometry*g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -707,7 +710,7 @@ char GEOSrelateTouches(Geometry *g1, Geometry*g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -727,7 +730,7 @@ char GEOSrelateIntersects(Geometry *g1, Geometry*g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -747,7 +750,7 @@ char GEOSrelateCrosses(Geometry *g1, Geometry*g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -767,7 +770,7 @@ char GEOSrelateWithin(Geometry *g1, Geometry*g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -791,7 +794,7 @@ char GEOSrelateContains(Geometry *g1, Geometry*g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -811,7 +814,7 @@ char GEOSrelateOverlaps(Geometry *g1, Geometry*g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -837,7 +840,7 @@ char GEOSrelatePattern(Geometry *g1, Geometry*g2,char *pat) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -868,7 +871,7 @@ char *GEOSrelate(Geometry *g1, Geometry*g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -895,7 +898,7 @@ char GEOSisvalid(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -921,7 +924,7 @@ char GEOSequals(Geometry *g1, Geometry*g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -948,7 +951,7 @@ char *GEOSasText(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -967,7 +970,7 @@ char GEOSisEmpty(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -986,7 +989,7 @@ char GEOSisSimple(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -1005,7 +1008,7 @@ char GEOSisRing(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 2; } @@ -1033,7 +1036,7 @@ char *GEOSGeometryType(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1072,7 +1075,7 @@ int GEOSGeometryTypeId(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return -1; } @@ -1099,7 +1102,7 @@ Geometry *GEOSIntersection(Geometry *g1,Geometry *g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1119,7 +1122,7 @@ Geometry *GEOSBuffer(Geometry *g1,double width) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1139,7 +1142,7 @@ Geometry *GEOSConvexHull(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1159,7 +1162,7 @@ Geometry *GEOSDifference(Geometry *g1,Geometry *g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1179,7 +1182,7 @@ Geometry *GEOSBoundary(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1199,7 +1202,7 @@ Geometry *GEOSSymDifference(Geometry *g1,Geometry *g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1219,7 +1222,7 @@ Geometry *GEOSUnion(Geometry *g1,Geometry *g2) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1239,7 +1242,7 @@ Geometry *GEOSpointonSurface(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1267,7 +1270,7 @@ void GEOSdeleteGeometry(Geometry *a) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; //return NULL; } @@ -1285,7 +1288,7 @@ void GEOSdeleteChar(char *a) } catch (GEOSException *ge) // ??? { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; //return NULL; } @@ -1317,7 +1320,7 @@ POINT3D *GEOSGetCoordinate(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1360,7 +1363,7 @@ POINT3D *GEOSGetCoordinates(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1421,7 +1424,7 @@ POINT3D *GEOSGetCoordinates_Polygon(Polygon *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1443,7 +1446,7 @@ int GEOSGetNumCoordinate(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 0; } @@ -1462,7 +1465,7 @@ int GEOSGetNumInteriorRings(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 0; } @@ -1483,7 +1486,7 @@ int GEOSGetNumGeometries(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 0; } @@ -1504,7 +1507,7 @@ const Geometry *GEOSGetGeometryN(Geometry *g1, int n) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1525,7 +1528,7 @@ const Geometry *GEOSGetExteriorRing(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 0; } @@ -1545,7 +1548,7 @@ const Geometry *GEOSGetInteriorRingN(Geometry *g1,int n) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1563,7 +1566,7 @@ Geometry *GEOSGetCentroid(Geometry *g) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return NULL; } @@ -1582,7 +1585,7 @@ int GEOSGetSRID(Geometry *g1) } catch (GEOSException *ge) { - lwnotice((char *)ge->toString().c_str()); + NOTICE_MESSAGE((char *)ge->toString().c_str()); delete ge; return 0; } diff --git a/lwgeom/lwgeom_gist.c b/lwgeom/lwgeom_gist.c index 52eb7ae9b..d24782b42 100644 --- a/lwgeom/lwgeom_gist.c +++ b/lwgeom/lwgeom_gist.c @@ -27,14 +27,20 @@ //#define DEBUG_GIST5 //#define DEBUG_GIST6 -Datum lwgeom_same(PG_FUNCTION_ARGS); -Datum lwgeom_overlap(PG_FUNCTION_ARGS); -Datum lwgeom_overleft(PG_FUNCTION_ARGS); -Datum lwgeom_left(PG_FUNCTION_ARGS); -Datum lwgeom_right(PG_FUNCTION_ARGS); -Datum lwgeom_overright(PG_FUNCTION_ARGS); -Datum lwgeom_contained(PG_FUNCTION_ARGS); -Datum lwgeom_contain(PG_FUNCTION_ARGS); +Datum LWGEOM_overlap(PG_FUNCTION_ARGS); +Datum LWGEOM_overleft(PG_FUNCTION_ARGS); +Datum LWGEOM_left(PG_FUNCTION_ARGS); +Datum LWGEOM_right(PG_FUNCTION_ARGS); +Datum LWGEOM_overright(PG_FUNCTION_ARGS); +Datum LWGEOM_contained(PG_FUNCTION_ARGS); +Datum LWGEOM_contain(PG_FUNCTION_ARGS); +Datum LWGEOM_gist_compress(PG_FUNCTION_ARGS); +Datum LWGEOM_gist_consistent(PG_FUNCTION_ARGS); +Datum LWGEOM_gist_decompress(PG_FUNCTION_ARGS); +Datum LWGEOM_gist_union(PG_FUNCTION_ARGS); +Datum LWGEOM_gist_penalty(PG_FUNCTION_ARGS); +Datum LWGEOM_gist_same(PG_FUNCTION_ARGS); +Datum LWGEOM_gist_picksplit(PG_FUNCTION_ARGS); @@ -60,31 +66,8 @@ int counter_intern = 0; // 7. call the appropriate BOX2DFLOAT4 function // 8. return result; -// lwgeom_same(lwgeom1, lwgeom2) -PG_FUNCTION_INFO_V1(lwgeom_same); -Datum lwgeom_same(PG_FUNCTION_ARGS) -{ - char *lwgeom1 = (char *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - char *lwgeom2 = (char *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); - bool result; - BOX2DFLOAT4 box1 = getbox2d(lwgeom1+4); - BOX2DFLOAT4 box2 = getbox2d(lwgeom2+4); - -#ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_same --entry"); -#endif - - result = DatumGetBool(DirectFunctionCall2(box2d_same, - PointerGetDatum(&box1), PointerGetDatum(&box2))); - - PG_FREE_IF_COPY(lwgeom1, 0); - PG_FREE_IF_COPY(lwgeom2, 1); - - PG_RETURN_BOOL(result); -} - -PG_FUNCTION_INFO_V1(lwgeom_overlap); -Datum lwgeom_overlap(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_overlap); +Datum LWGEOM_overlap(PG_FUNCTION_ARGS) { char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); @@ -94,7 +77,7 @@ Datum lwgeom_overlap(PG_FUNCTION_ARGS) BOX2DFLOAT4 box2 = getbox2d(lwgeom2+4); - result = DatumGetBool(DirectFunctionCall2(box2d_overlap, + result = DatumGetBool(DirectFunctionCall2(BOX2D_overlap, PointerGetDatum(&box1), PointerGetDatum(&box2))); PG_FREE_IF_COPY(lwgeom1, 0); @@ -116,8 +99,8 @@ Datum lwgeom_overlap(PG_FUNCTION_ARGS) } -PG_FUNCTION_INFO_V1(lwgeom_overleft); -Datum lwgeom_overleft(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_overleft); +Datum LWGEOM_overleft(PG_FUNCTION_ARGS) { char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); @@ -126,10 +109,10 @@ Datum lwgeom_overleft(PG_FUNCTION_ARGS) BOX2DFLOAT4 box2 = getbox2d(lwgeom2+4); #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_overleft --entry"); + elog(NOTICE,"GIST: LWGEOM_overleft --entry"); #endif - result = DatumGetBool(DirectFunctionCall2(box2d_overleft, + result = DatumGetBool(DirectFunctionCall2(BOX2D_overleft, PointerGetDatum(&box1), PointerGetDatum(&box2))); PG_FREE_IF_COPY(lwgeom1, 0); @@ -138,8 +121,8 @@ Datum lwgeom_overleft(PG_FUNCTION_ARGS) PG_RETURN_BOOL(result); } -PG_FUNCTION_INFO_V1(lwgeom_left); -Datum lwgeom_left(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_left); +Datum LWGEOM_left(PG_FUNCTION_ARGS) { char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); @@ -149,10 +132,10 @@ Datum lwgeom_left(PG_FUNCTION_ARGS) BOX2DFLOAT4 box2 = getbox2d(lwgeom2+4); #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_left --entry"); + elog(NOTICE,"GIST: LWGEOM_left --entry"); #endif - result = DatumGetBool(DirectFunctionCall2(box2d_left, + result = DatumGetBool(DirectFunctionCall2(BOX2D_left, PointerGetDatum(&box1), PointerGetDatum(&box2))); PG_FREE_IF_COPY(lwgeom1, 0); @@ -162,8 +145,8 @@ Datum lwgeom_left(PG_FUNCTION_ARGS) } -PG_FUNCTION_INFO_V1(lwgeom_right); -Datum lwgeom_right(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_right); +Datum LWGEOM_right(PG_FUNCTION_ARGS) { char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); @@ -173,9 +156,9 @@ Datum lwgeom_right(PG_FUNCTION_ARGS) BOX2DFLOAT4 box2 = getbox2d(lwgeom2+4); #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_right --entry"); + elog(NOTICE,"GIST: LWGEOM_right --entry"); #endif - result = DatumGetBool(DirectFunctionCall2(box2d_right, + result = DatumGetBool(DirectFunctionCall2(BOX2D_right, PointerGetDatum(&box1), PointerGetDatum(&box2))); PG_FREE_IF_COPY(lwgeom1, 0); @@ -185,8 +168,8 @@ Datum lwgeom_right(PG_FUNCTION_ARGS) } -PG_FUNCTION_INFO_V1(lwgeom_overright); -Datum lwgeom_overright(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_overright); +Datum LWGEOM_overright(PG_FUNCTION_ARGS) { char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); @@ -196,10 +179,10 @@ Datum lwgeom_overright(PG_FUNCTION_ARGS) BOX2DFLOAT4 box2 = getbox2d(lwgeom2+4); #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_overright --entry"); + elog(NOTICE,"GIST: LWGEOM_overright --entry"); #endif - result = DatumGetBool(DirectFunctionCall2(box2d_overright, + result = DatumGetBool(DirectFunctionCall2(BOX2D_overright, PointerGetDatum(&box1), PointerGetDatum(&box2))); PG_FREE_IF_COPY(lwgeom1, 0); @@ -209,8 +192,8 @@ Datum lwgeom_overright(PG_FUNCTION_ARGS) } -PG_FUNCTION_INFO_V1(lwgeom_contained); -Datum lwgeom_contained(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_contained); +Datum LWGEOM_contained(PG_FUNCTION_ARGS) { char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); @@ -220,9 +203,9 @@ Datum lwgeom_contained(PG_FUNCTION_ARGS) BOX2DFLOAT4 box2 = getbox2d(lwgeom2+4); #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_contained --entry"); + elog(NOTICE,"GIST: LWGEOM_contained --entry"); #endif - result = DatumGetBool(DirectFunctionCall2(box2d_contained, + result = DatumGetBool(DirectFunctionCall2(BOX2D_contained, PointerGetDatum(&box1), PointerGetDatum(&box2))); PG_FREE_IF_COPY(lwgeom1, 0); @@ -232,8 +215,8 @@ Datum lwgeom_contained(PG_FUNCTION_ARGS) } -PG_FUNCTION_INFO_V1(lwgeom_contain); -Datum lwgeom_contain(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_contain); +Datum LWGEOM_contain(PG_FUNCTION_ARGS) { char *lwgeom1 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); char *lwgeom2 = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); @@ -243,10 +226,10 @@ Datum lwgeom_contain(PG_FUNCTION_ARGS) BOX2DFLOAT4 box2 = getbox2d(lwgeom2+4); #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_contain --entry"); + elog(NOTICE,"GIST: LWGEOM_contain --entry"); #endif - result = DatumGetBool(DirectFunctionCall2(box2d_contain, + result = DatumGetBool(DirectFunctionCall2(BOX2D_contain, PointerGetDatum(&box1), PointerGetDatum(&box2))); PG_FREE_IF_COPY(lwgeom1, 0); @@ -259,26 +242,26 @@ Datum lwgeom_contain(PG_FUNCTION_ARGS) // These functions are taken from the postgis_gist_72.c file -PG_FUNCTION_INFO_V1(gist_lwgeom_compress); -Datum gist_lwgeom_compress(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_gist_compress); +Datum LWGEOM_gist_compress(PG_FUNCTION_ARGS) { GISTENTRY *entry=(GISTENTRY*)PG_GETARG_POINTER(0); GISTENTRY *retval; #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: gist_lwgeom_compress called"); + elog(NOTICE,"GIST: LWGEOM_gist_compress called"); #endif if ( entry->leafkey) { #ifdef DEBUG_GIST4 - elog(NOTICE,"GIST: gist_lwgeom_compress got a leafkey"); + elog(NOTICE,"GIST: LWGEOM_gist_compress got a leafkey"); #endif retval = palloc(sizeof(GISTENTRY)); if ( DatumGetPointer(entry->key) != NULL ) { #ifdef DEBUG_GIST4 - elog(NOTICE,"GIST: gist_lwgeom_compress got a non-NULL key"); + elog(NOTICE,"GIST: LWGEOM_gist_compress got a non-NULL key"); #endif char *in; // lwgeom serialized @@ -288,7 +271,7 @@ Datum gist_lwgeom_compress(PG_FUNCTION_ARGS) in = (char*)PG_DETOAST_DATUM(entry->key); #ifdef DEBUG_GIST4 - elog(NOTICE,"GIST: gist_lwgeom_compress detoasted entry->key: %s", unparse_WKT(SERIALIZED_FORM(in), malloc, free)); + elog(NOTICE,"GIST: LWGEOM_gist_compress detoasted entry->key: %s", unparse_WKT(SERIALIZED_FORM(in), malloc, free)); #endif if (in == NULL) @@ -303,7 +286,7 @@ Datum gist_lwgeom_compress(PG_FUNCTION_ARGS) } #ifdef DEBUG_GIST4 - elog(NOTICE,"GIST: gist_lwgeom_compress got numgeometries"); + elog(NOTICE,"GIST: LWGEOM_gist_compress got numgeometries"); #endif rr = (BOX2DFLOAT4*) palloc(sizeof(BOX2DFLOAT4)); @@ -319,7 +302,7 @@ Datum gist_lwgeom_compress(PG_FUNCTION_ARGS) //memcpy(rr,&r,sizeof(BOX2DFLOAT4)); #ifdef DEBUG_GIST4 - elog(NOTICE,"GIST: gist_lwgeom_compress got box2d"); + elog(NOTICE,"GIST: LWGEOM_gist_compress got box2d"); #endif if ( ! finite(rr->xmin) || @@ -334,7 +317,7 @@ Datum gist_lwgeom_compress(PG_FUNCTION_ARGS) #ifdef DEBUG_GIST2 - elog(NOTICE,"GIST: gist_lwgeom_compress -- got box2d BOX(%.15g %.15g,%.15g %.15g)", rr->xmin, rr->ymin, rr->xmax, rr->ymax); + elog(NOTICE,"GIST: LWGEOM_gist_compress -- got box2d BOX(%.15g %.15g,%.15g %.15g)", rr->xmin, rr->ymin, rr->xmax, rr->ymax); #endif //r = convert_box3d_to_box(&in->bvol); @@ -352,7 +335,7 @@ Datum gist_lwgeom_compress(PG_FUNCTION_ARGS) else { #ifdef DEBUG_GIST4 - elog(NOTICE,"GIST: gist_lwgeom_compress got a NULL key"); + elog(NOTICE,"GIST: LWGEOM_gist_compress got a NULL key"); #endif gistentryinit(*retval, (Datum) 0, entry->rel, entry->page, entry->offset, 0, FALSE); @@ -361,7 +344,7 @@ Datum gist_lwgeom_compress(PG_FUNCTION_ARGS) else { #ifdef DEBUG_GIST4 - elog(NOTICE,"GIST: gist_lwgeom_compress got a non-leafkey"); + elog(NOTICE,"GIST: LWGEOM_gist_compress got a non-leafkey"); #endif retval = entry; } @@ -370,8 +353,8 @@ Datum gist_lwgeom_compress(PG_FUNCTION_ARGS) } -PG_FUNCTION_INFO_V1(gist_lwgeom_consistent); -Datum gist_lwgeom_consistent(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_gist_consistent); +Datum LWGEOM_gist_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY*) PG_GETARG_POINTER(0); char *query ; // lwgeom serialized form @@ -385,12 +368,12 @@ Datum gist_lwgeom_consistent(PG_FUNCTION_ARGS) * else use rtree_leaf_consistent */ #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: gist_lwgeom_consistent called"); + elog(NOTICE,"GIST: LWGEOM_gist_consistent called"); #endif if ( ((Pointer *) PG_GETARG_DATUM(1)) == NULL ) { - //elog(NOTICE,"gist_lwgeom_consistent:: got null query!"); + //elog(NOTICE,"LWGEOM_gist_consistent:: got null query!"); PG_RETURN_BOOL(false); // null query - this is screwy! } @@ -404,7 +387,7 @@ Datum gist_lwgeom_consistent(PG_FUNCTION_ARGS) //thebox = box3d_to_box2df(box3d); //pfree(box3d); //convert_box3d_to_box_p( &(query->bvol) , &thebox); - //thebox = getBOX2D_cache(query); + //thebox = getbox2d_cache(query); getbox2d_p(query+4, &box); if (GIST_LEAF(entry)) @@ -434,7 +417,7 @@ lwgeom_rtree_internal_consistent(BOX2DFLOAT4 *key, BOX2DFLOAT4 *query, switch(strategy) { case RTLeftStrategyNumber: case RTOverLeftStrategyNumber: - retval = DatumGetBool( DirectFunctionCall2( box2d_overleft, PointerGetDatum(key), PointerGetDatum(query) ) ); + retval = DatumGetBool( DirectFunctionCall2( BOX2D_overleft, PointerGetDatum(key), PointerGetDatum(query) ) ); break; case RTOverlapStrategyNumber: //optimized for speed @@ -469,14 +452,14 @@ elog(NOTICE,"%i:(int)<%.8g %.8g,%.8g %.8g>&&<%.8g %.8g,%.8g %.8g> %i",counter_in break; case RTOverRightStrategyNumber: case RTRightStrategyNumber: - retval = DatumGetBool( DirectFunctionCall2( box2d_overright, PointerGetDatum(key), PointerGetDatum(query) ) ); + retval = DatumGetBool( DirectFunctionCall2( BOX2D_overright, PointerGetDatum(key), PointerGetDatum(query) ) ); break; case RTSameStrategyNumber: case RTContainsStrategyNumber: - retval = DatumGetBool( DirectFunctionCall2( box2d_contain, PointerGetDatum(key), PointerGetDatum(query) ) ); + retval = DatumGetBool( DirectFunctionCall2( BOX2D_contain, PointerGetDatum(key), PointerGetDatum(query) ) ); break; case RTContainedByStrategyNumber: - retval = DatumGetBool( DirectFunctionCall2( box2d_overlap, PointerGetDatum(key), PointerGetDatum(query) ) ); + retval = DatumGetBool( DirectFunctionCall2( BOX2D_overlap, PointerGetDatum(key), PointerGetDatum(query) ) ); break; default: retval = FALSE; @@ -498,10 +481,10 @@ lwgeom_rtree_leaf_consistent(BOX2DFLOAT4 *key, switch (strategy) { case RTLeftStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box2d_left, PointerGetDatum(key), PointerGetDatum(query))); + retval = DatumGetBool(DirectFunctionCall2(BOX2D_left, PointerGetDatum(key), PointerGetDatum(query))); break; case RTOverLeftStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box2d_overleft, PointerGetDatum(key), PointerGetDatum(query))); + retval = DatumGetBool(DirectFunctionCall2(BOX2D_overleft, PointerGetDatum(key), PointerGetDatum(query))); break; case RTOverlapStrategyNumber://optimized for speed retval = (((key->xmax>= query->xmax) && @@ -523,19 +506,19 @@ lwgeom_rtree_leaf_consistent(BOX2DFLOAT4 *key, return(retval); break; case RTOverRightStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box2d_overright, PointerGetDatum(key), PointerGetDatum(query))); + retval = DatumGetBool(DirectFunctionCall2(BOX2D_overright, PointerGetDatum(key), PointerGetDatum(query))); break; case RTRightStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box2d_right, PointerGetDatum(key), PointerGetDatum(query))); + retval = DatumGetBool(DirectFunctionCall2(BOX2D_right, PointerGetDatum(key), PointerGetDatum(query))); break; case RTSameStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box2d_same, PointerGetDatum(key), PointerGetDatum(query))); + retval = DatumGetBool(DirectFunctionCall2(BOX2D_same, PointerGetDatum(key), PointerGetDatum(query))); break; case RTContainsStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box2d_contain, PointerGetDatum(key), PointerGetDatum(query))); + retval = DatumGetBool(DirectFunctionCall2(BOX2D_contain, PointerGetDatum(key), PointerGetDatum(query))); break; case RTContainedByStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box2d_contained, PointerGetDatum(key), PointerGetDatum(query))); + retval = DatumGetBool(DirectFunctionCall2(BOX2D_contained, PointerGetDatum(key), PointerGetDatum(query))); break; default: retval = FALSE; @@ -545,12 +528,12 @@ lwgeom_rtree_leaf_consistent(BOX2DFLOAT4 *key, -PG_FUNCTION_INFO_V1(gist_rtree_decompress); -Datum gist_rtree_decompress(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_gist_decompress); +Datum LWGEOM_gist_decompress(PG_FUNCTION_ARGS) { #ifdef DEBUG_CALLS static unsigned int counter2 = 0; - elog(NOTICE,"GIST: gist_rtree_decompress called %i",counter2); + elog(NOTICE,"GIST: LWGEOM_gist_decompress called %i",counter2); counter2++; #endif @@ -563,8 +546,8 @@ Datum gist_rtree_decompress(PG_FUNCTION_ARGS) * The GiST Union method for boxes * returns the minimal bounding box that encloses all the entries in entryvec */ -PG_FUNCTION_INFO_V1(lwgeom_box_union); -Datum lwgeom_box_union(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_gist_union); +Datum LWGEOM_gist_union(PG_FUNCTION_ARGS) { #if USE_VERSION < 80 bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); @@ -578,7 +561,7 @@ Datum lwgeom_box_union(PG_FUNCTION_ARGS) *pageunion; #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_box_union called\n"); + elog(NOTICE,"GIST: LWGEOM_gist_union called\n"); #endif #if USE_VERSION < 80 @@ -698,8 +681,8 @@ static double size_box2d_double(Datum box2d) ** The GiST Penalty method for boxes ** As in the R-tree paper, we use change in area as our penalty metric */ -PG_FUNCTION_INFO_V1(lwgeom_box_penalty); -Datum lwgeom_box_penalty(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_gist_penalty); +Datum LWGEOM_gist_penalty(PG_FUNCTION_ARGS) { GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); @@ -708,12 +691,12 @@ Datum lwgeom_box_penalty(PG_FUNCTION_ARGS) double tmp1; #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_box_penalty called"); + elog(NOTICE,"GIST: LWGEOM_gist_penalty called"); #endif ud = DirectFunctionCall2(BOX2D_union, origentry->key, newentry->key); - //ud = box2d_union(origentry->key, newentry->key); + //ud = BOX2D_union(origentry->key, newentry->key); tmp1 = size_box2d_double(ud); if (DatumGetPointer(ud) != NULL) pfree(DatumGetPointer(ud)); @@ -728,17 +711,17 @@ Datum lwgeom_box_penalty(PG_FUNCTION_ARGS) */ #ifdef DEBUG_GIST6 - elog(NOTICE,"GIST: lwgeom_box_penalty called and returning %.15g", *result); + elog(NOTICE,"GIST: LWGEOM_gist_penalty called and returning %.15g", *result); if (*result<0) { BOX2DFLOAT4 *a, *b,*c; a = (BOX2DFLOAT4*) DatumGetPointer(origentry->key); b = (BOX2DFLOAT4*) DatumGetPointer(newentry->key); - //c = (BOX2DFLOAT4*) DatumGetPointer(DirectFunctionCall2(box2d_union, origentry->key, newentry->key)); - c = box2d_union(origentry->key, newentry->key); - //elog(NOTICE,"lwgeom_box_penalty -- a = <%.16g %.16g,%.16g %.16g>", a->xmin, a->ymin, a->xmax, a->ymax); - //elog(NOTICE,"lwgeom_box_penalty -- b = <%.16g %.16g,%.16g %.16g>", b->xmin, b->ymin, b->xmax, b->ymax); - //elog(NOTICE,"lwgeom_box_penalty -- c = <%.16g %.16g,%.16g %.16g>", c->xmin, c->ymin, c->xmax, c->ymax); + //c = (BOX2DFLOAT4*) DatumGetPointer(DirectFunctionCall2(BOX2D_union, origentry->key, newentry->key)); + c = BOX2D_union(origentry->key, newentry->key); + //elog(NOTICE,"LWGEOM_gist_penalty -- a = <%.16g %.16g,%.16g %.16g>", a->xmin, a->ymin, a->xmax, a->ymax); + //elog(NOTICE,"LWGEOM_gist_penalty -- b = <%.16g %.16g,%.16g %.16g>", b->xmin, b->ymin, b->xmax, b->ymax); + //elog(NOTICE,"LWGEOM_gist_penalty -- c = <%.16g %.16g,%.16g %.16g>", c->xmin, c->ymin, c->xmax, c->ymax); } #endif @@ -764,19 +747,19 @@ compare_KB(const void* a, const void* b) { /* ** Equality method */ -PG_FUNCTION_INFO_V1(lwgeom_gbox_same); -Datum lwgeom_gbox_same(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_gist_same); +Datum LWGEOM_gist_same(PG_FUNCTION_ARGS) { BOX2DFLOAT4 *b1 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(0); BOX2DFLOAT4 *b2 = (BOX2DFLOAT4 *) PG_GETARG_POINTER(1); bool *result = (bool *) PG_GETARG_POINTER(2); #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_gbox_same called"); + elog(NOTICE,"GIST: LWGEOM_gist_same called"); #endif if (b1 && b2) - *result = DatumGetBool(DirectFunctionCall2(box2d_same, PointerGetDatum(b1), PointerGetDatum(b2))); + *result = DatumGetBool(DirectFunctionCall2(BOX2D_same, PointerGetDatum(b1), PointerGetDatum(b2))); else *result = (b1 == NULL && b2 == NULL) ? TRUE : FALSE; PG_RETURN_POINTER(result); @@ -790,8 +773,8 @@ Datum lwgeom_gbox_same(PG_FUNCTION_ARGS) ** New linear algorithm, see 'New Linear Node Splitting Algorithm for R-tree', ** C.H.Ang and T.C.Tan */ -PG_FUNCTION_INFO_V1(lwgeom_gbox_picksplit); -Datum lwgeom_gbox_picksplit(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_gist_picksplit); +Datum LWGEOM_gist_picksplit(PG_FUNCTION_ARGS) { #if USE_VERSION < 80 bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); @@ -820,7 +803,7 @@ Datum lwgeom_gbox_picksplit(PG_FUNCTION_ARGS) int nbytes; #ifdef DEBUG_CALLS - elog(NOTICE,"GIST: lwgeom_gbox_picksplit called"); + elog(NOTICE,"GIST: LWGEOM_gist_picksplit called"); #endif posL = posR = posB = posT = 0; @@ -1009,14 +992,11 @@ elog(NOTICE," unionB is: <%.16g %.16g,%.16g %.16g>", unionB->xmin, unionB->ymi direction = 'y'; else { - Datum interLR = DirectFunctionCall2(box2d_inter, - PointerGetDatum(unionL), - PointerGetDatum(unionR)); - Datum interBT = DirectFunctionCall2(box2d_inter, - PointerGetDatum(unionB), - PointerGetDatum(unionT)); - float sizeLR, - sizeBT; + Datum interLR = DirectFunctionCall2(BOX2D_intersects, + PointerGetDatum(unionL), PointerGetDatum(unionR)); + Datum interBT = DirectFunctionCall2(BOX2D_intersects, + PointerGetDatum(unionB), PointerGetDatum(unionT)); + float sizeLR, sizeBT; //elog(NOTICE,"direction is abigeous"); diff --git a/lwgeom/lwgeom_ogc.c b/lwgeom/lwgeom_ogc.c index 72b81b65d..5c186f638 100644 --- a/lwgeom/lwgeom_ogc.c +++ b/lwgeom/lwgeom_ogc.c @@ -322,6 +322,7 @@ Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS) LWLINE *line; char *serializedline; PG_LWGEOM *result; + BOX2DFLOAT4 *bbox; int i; for (i=0; ingeometries; i++) @@ -335,15 +336,20 @@ Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS) // Ok, now we have a polygon. Here is its exterior ring. extring = poly->rings[0]; + // If the input geom has a bbox, use it for + // the output geom, as exterior ring makes it up ! + bbox = getbox2d_internal(SERIALIZED_FORM(geom)); + if ( bbox ) bbox = box2d_clone(bbox); + // This is a LWLINE constructed by exterior ring POINTARRAY - line = lwline_construct(poly->SRID, lwgeom_hasBBOX(geom->type), extring); + line = lwline_construct(poly->SRID, bbox, extring); // Now we serialized it (copying data) serializedline = lwline_serialize(line); // And we construct the line (copy again) result = PG_LWGEOM_construct(serializedline, lwgeom_getSRID(geom), - lwgeom_hasBBOX(geom->type)); + bbox?1:0); pfree(serializedline); pfree(line); @@ -391,6 +397,7 @@ Datum LWGEOM_interiorringn_polygon(PG_FUNCTION_ARGS) LWLINE *line; char *serializedline; PG_LWGEOM *result; + BOX2DFLOAT4 *bbox = NULL; int i; wanted_index = PG_GETARG_INT32(1); @@ -418,15 +425,19 @@ Datum LWGEOM_interiorringn_polygon(PG_FUNCTION_ARGS) ring = poly->rings[wanted_index+1]; - // This is a LWLINE constructed by exterior ring POINTARRAY - line = lwline_construct(poly->SRID, lwgeom_hasBBOX(geom->type), ring); + // If input geometry did have a bounding box + // compute the new one + if ( TYPE_HASBBOX(geom->type) ) bbox = ptarray_compute_bbox(ring); + + // This is a LWLINE constructed by interior ring POINTARRAY + line = lwline_construct(poly->SRID, bbox, ring); // Now we serialized it (copying data) serializedline = lwline_serialize(line); // And we construct the line (copy again) result = PG_LWGEOM_construct(serializedline, lwgeom_getSRID(geom), - lwgeom_hasBBOX(geom->type)); + bbox?1:0); pfree(serializedline); pfree(line); @@ -478,14 +489,16 @@ Datum LWGEOM_pointn_linestring(PG_FUNCTION_ARGS) TYPE_HASZ(line->type), TYPE_HASM(line->type), 1); // Construct an LWPOINT - point = lwpoint_construct(lwgeom_getSRID(geom), lwgeom_hasBBOX(geom->type), pts); + point = lwpoint_construct(lwgeom_getSRID(geom), + NULL, pts); // Serialized the point serializedpoint = lwpoint_serialize(point); - // And we construct the line (copy again) - result = PG_LWGEOM_construct(serializedpoint, lwgeom_getSRID(geom), - lwgeom_hasBBOX(geom->type)); + // And we construct the line + // TODO: use serialize_buf above, instead .. + result = PG_LWGEOM_construct(serializedpoint, + lwgeom_getSRID(geom), 0); pfree(point); pfree(serializedpoint); @@ -620,14 +633,14 @@ Datum LWGEOM_startpoint_linestring(PG_FUNCTION_ARGS) TYPE_HASM(line->type), 1); // Construct an LWPOINT - point = lwpoint_construct(lwgeom_getSRID(geom), lwgeom_hasBBOX(geom->type), pts); + point = lwpoint_construct(lwgeom_getSRID(geom), NULL, pts); // Serialized the point serializedpoint = lwpoint_serialize(point); // And we construct the line (copy again) result = PG_LWGEOM_construct(serializedpoint, lwgeom_getSRID(geom), - lwgeom_hasBBOX(geom->type)); + 0); pfree(point); pfree(serializedpoint); @@ -671,14 +684,14 @@ Datum LWGEOM_endpoint_linestring(PG_FUNCTION_ARGS) TYPE_HASM(line->type), 1); // Construct an LWPOINT - point = lwpoint_construct(lwgeom_getSRID(geom), lwgeom_hasBBOX(geom->type), pts); + point = lwpoint_construct(lwgeom_getSRID(geom), NULL, pts); // Serialized the point serializedpoint = lwpoint_serialize(point); // And we construct the line (copy again) result = PG_LWGEOM_construct(serializedpoint, lwgeom_getSRID(geom), - lwgeom_hasBBOX(geom->type)); + 0); pfree(point); pfree(serializedpoint); diff --git a/lwgeom/lwgeom_pg.h b/lwgeom/lwgeom_pg.h index ed4631141..f09a24382 100644 --- a/lwgeom/lwgeom_pg.h +++ b/lwgeom/lwgeom_pg.h @@ -19,25 +19,20 @@ void init_pg_func(void); extern BOX2DFLOAT4 *box_to_box2df(BOX *box); // postgresql standard type extern BOX box2df_to_box(BOX2DFLOAT4 *box); extern void box2df_to_box_p(BOX2DFLOAT4 *box, BOX *out); // postgresql standard type + // PG-exposed -Datum box2d_same(PG_FUNCTION_ARGS); -Datum box2d_overlap(PG_FUNCTION_ARGS); -Datum box2d_overleft(PG_FUNCTION_ARGS); -Datum box2d_left(PG_FUNCTION_ARGS); -Datum box2d_right(PG_FUNCTION_ARGS); -Datum box2d_overright(PG_FUNCTION_ARGS); -Datum box2d_contained(PG_FUNCTION_ARGS); -Datum box2d_contain(PG_FUNCTION_ARGS); -Datum box2d_inter(PG_FUNCTION_ARGS); +Datum BOX2D_same(PG_FUNCTION_ARGS); +Datum BOX2D_overlap(PG_FUNCTION_ARGS); +Datum BOX2D_overleft(PG_FUNCTION_ARGS); +Datum BOX2D_left(PG_FUNCTION_ARGS); +Datum BOX2D_right(PG_FUNCTION_ARGS); +Datum BOX2D_overright(PG_FUNCTION_ARGS); +Datum BOX2D_contained(PG_FUNCTION_ARGS); +Datum BOX2D_contain(PG_FUNCTION_ARGS); +Datum BOX2D_intersects(PG_FUNCTION_ARGS); Datum BOX2D_union(PG_FUNCTION_ARGS); -Datum gist_lwgeom_compress(PG_FUNCTION_ARGS); -Datum gist_lwgeom_consistent(PG_FUNCTION_ARGS); -Datum gist_rtree_decompress(PG_FUNCTION_ARGS); -Datum lwgeom_box_union(PG_FUNCTION_ARGS); -Datum lwgeom_box_penalty(PG_FUNCTION_ARGS); -Datum lwgeom_gbox_same(PG_FUNCTION_ARGS); -Datum lwgeom_gbox_picksplit(PG_FUNCTION_ARGS); +Datum LWGEOM_same(PG_FUNCTION_ARGS); #endif // !defined _LWGEOM_PG_H 1 diff --git a/lwgeom/lwline.c b/lwgeom/lwline.c index d10175ffc..d58f77cd0 100644 --- a/lwgeom/lwline.c +++ b/lwgeom/lwline.c @@ -11,7 +11,7 @@ // construct a new LWLINE. points will *NOT* be copied // use SRID=-1 for unknown SRID (will have 8bit type's S = 0) LWLINE * -lwline_construct(int SRID, char wantbbox, POINTARRAY *points) +lwline_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points) { LWLINE *result; result = (LWLINE*) lwalloc(sizeof(LWLINE)); @@ -20,9 +20,10 @@ lwline_construct(int SRID, char wantbbox, POINTARRAY *points) TYPE_HASZ(points->dims), TYPE_HASM(points->dims), (SRID!=-1), LINETYPE, - wantbbox); + 0); result->SRID = SRID; result->points = points; + result->bbox = bbox; return result; } @@ -56,10 +57,12 @@ lwline_deserialize(char *serialized_form) if (lwgeom_hasBBOX(type)) { //lwnotice("line has bbox"); + result->bbox = (BOX2DFLOAT4 *)loc; loc += sizeof(BOX2DFLOAT4); } else { + result->bbox = NULL; //lwnotice("line has NO bbox"); } @@ -134,16 +137,18 @@ lwline_serialize_buf(LWLINE *line, char *buf, size_t *retsize) hasSRID = (line->SRID != -1); - buf[0] = line->type; + buf[0] = (unsigned char) lwgeom_makeType_full( + TYPE_HASZ(line->type), TYPE_HASM(line->type), + hasSRID, LINETYPE, line->bbox ? 1 : 0); loc = buf+1; #ifdef DEBUG lwnotice("lwline_serialize_buf added type (%d)", line->type); #endif - if (TYPE_HASBBOX(line->type)) + if (line->bbox) { - lwgeom_compute_bbox_p((LWGEOM *)line, (BOX2DFLOAT4 *)loc); + memcpy(loc, line->bbox, sizeof(BOX2DFLOAT4)); loc += sizeof(BOX2DFLOAT4); #ifdef DEBUG lwnotice("lwline_serialize_buf added BBOX"); @@ -211,7 +216,7 @@ lwline_serialize_size(LWLINE *line) #endif if ( line->SRID != -1 ) size += 4; // SRID - if ( TYPE_HASBBOX(line->type) ) size += sizeof(BOX2DFLOAT4); + if ( line->bbox ) size += sizeof(BOX2DFLOAT4); size += 4; // npoints size += pointArray_ptsize(line->points)*line->points->npoints; @@ -294,6 +299,8 @@ lwline_clone(const LWLINE *g) { LWLINE *ret = lwalloc(sizeof(LWLINE)); memcpy(ret, g, sizeof(LWLINE)); + if ( g->bbox && ! TYPE_HASBBOX(g->type) ) + ret->bbox = box2d_clone(g->bbox); return ret; } @@ -340,8 +347,7 @@ lwline_add(const LWLINE *to, uint32 where, const LWGEOM *what) else newtype = COLLECTIONTYPE; col = lwcollection_construct(newtype, - to->SRID, - ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->SRID, NULL, 2, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwmline.c b/lwgeom/lwmline.c index fe5c0d062..5a98c897a 100644 --- a/lwgeom/lwmline.c +++ b/lwgeom/lwmline.c @@ -26,6 +26,11 @@ lwmline_deserialize(char *srl) result->ngeoms = insp->ngeometries; result->geoms = lwalloc(sizeof(LWLINE *)*insp->ngeometries); + if (lwgeom_hasBBOX(srl[0])) + result->bbox = (BOX2DFLOAT4 *)(srl+1); + else result->bbox = NULL; + + for (i=0; ingeometries; i++) { result->geoms[i] = lwline_deserialize(insp->sub_geoms[i]); @@ -80,8 +85,7 @@ lwmline_add(const LWMLINE *to, uint32 where, const LWGEOM *what) else newtype = COLLECTIONTYPE; col = lwcollection_construct(newtype, - to->SRID, - ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->SRID, NULL, to->ngeoms+1, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwmpoint.c b/lwgeom/lwmpoint.c index 5ac12bb2d..a6562d233 100644 --- a/lwgeom/lwmpoint.c +++ b/lwgeom/lwmpoint.c @@ -26,6 +26,10 @@ lwmpoint_deserialize(char *srl) result->ngeoms = insp->ngeometries; result->geoms = lwalloc(sizeof(LWPOINT *)*result->ngeoms); + if (lwgeom_hasBBOX(srl[0])) + result->bbox = (BOX2DFLOAT4 *)(srl+1); + else result->bbox = NULL; + for (i=0; ingeometries; i++) { result->geoms[i] = lwpoint_deserialize(insp->sub_geoms[i]); @@ -80,8 +84,7 @@ lwmpoint_add(const LWMPOINT *to, uint32 where, const LWGEOM *what) else newtype = COLLECTIONTYPE; col = lwcollection_construct(newtype, - to->SRID, - ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->SRID, NULL, to->ngeoms+1, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwmpoly.c b/lwgeom/lwmpoly.c index 5364c67f7..1d1db25ca 100644 --- a/lwgeom/lwmpoly.c +++ b/lwgeom/lwmpoly.c @@ -32,6 +32,10 @@ lwmpoly_deserialize(char *srl) result->ngeoms = insp->ngeometries; result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries); + if (lwgeom_hasBBOX(srl[0])) + result->bbox = (BOX2DFLOAT4 *)(srl+1); + else result->bbox = NULL; + for (i=0; ingeometries; i++) { result->geoms[i] = lwpoly_deserialize(insp->sub_geoms[i]); @@ -86,8 +90,7 @@ lwmpoly_add(const LWMPOLY *to, uint32 where, const LWGEOM *what) else newtype = COLLECTIONTYPE; col = lwcollection_construct(newtype, - to->SRID, - ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->SRID, NULL, to->ngeoms+1, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwpoint.c b/lwgeom/lwpoint.c index 67405b113..25360e837 100644 --- a/lwgeom/lwpoint.c +++ b/lwgeom/lwpoint.c @@ -44,18 +44,18 @@ lwpoint_serialize_buf(LWPOINT *point, char *buf, size_t *retsize) hasSRID = (point->SRID != -1); if (hasSRID) size +=4; //4 byte SRID - if (TYPE_HASBBOX(point->type)) size += sizeof(BOX2DFLOAT4); // bvol + if (point->bbox) size += sizeof(BOX2DFLOAT4); // bvol size += sizeof(double)*TYPE_NDIMS(point->type); buf[0] = (unsigned char) lwgeom_makeType_full( TYPE_HASZ(point->type), TYPE_HASM(point->type), - hasSRID, POINTTYPE, TYPE_HASBBOX(point->type)); + hasSRID, POINTTYPE, point->bbox?1:0); loc = buf+1; - if (TYPE_HASBBOX(point->type)) + if (point->bbox) { - lwgeom_compute_bbox_p((LWGEOM *)point, (BOX2DFLOAT4 *)loc); + memcpy(loc, point->bbox, sizeof(BOX2DFLOAT4)); loc += sizeof(BOX2DFLOAT4); } @@ -154,7 +154,7 @@ lwpoint_serialize_size(LWPOINT *point) // construct a new point. point will not be copied // use SRID=-1 for unknown SRID (will have 8bit type's S = 0) LWPOINT * -lwpoint_construct(int SRID, char wantbbox, POINTARRAY *point) +lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *point) { LWPOINT *result ; @@ -162,10 +162,10 @@ lwpoint_construct(int SRID, char wantbbox, POINTARRAY *point) return NULL; // error result = lwalloc(sizeof(LWPOINT)); - result->type = lwgeom_makeType_full(TYPE_HASZ(point->dims), TYPE_HASM(point->dims), (SRID!=-1), - POINTTYPE, wantbbox); + result->type = lwgeom_makeType_full(TYPE_HASZ(point->dims), TYPE_HASM(point->dims), (SRID!=-1), POINTTYPE, 0); result->SRID = SRID; result->point = point; + result->bbox = bbox; return result; } @@ -200,8 +200,13 @@ lwpoint_deserialize(char *serialized_form) #ifdef DEBUG lwnotice("lwpoint_deserialize: input has bbox"); #endif + result->bbox = (BOX2DFLOAT4 *)loc; loc += sizeof(BOX2DFLOAT4); } + else + { + result->bbox = NULL; + } if ( lwgeom_hasSRID(type)) { @@ -256,6 +261,8 @@ lwpoint_clone(const LWPOINT *g) lwnotice("lwpoint_clone called"); #endif memcpy(ret, g, sizeof(LWPOINT)); + if ( g->bbox && ! TYPE_HASBBOX(g->type) ) + ret->bbox = box2d_clone(g->bbox); return ret; } @@ -292,19 +299,17 @@ lwpoint_add(const LWPOINT *to, uint32 where, const LWGEOM *what) geoms[1] = lwgeom_clone((LWGEOM *)to); } // reset SRID and wantbbox flag from component types - geoms[0]->SRID = geoms[1]->SRID = -1; - TYPE_SETHASSRID(geoms[0]->type, 0); - TYPE_SETHASSRID(geoms[1]->type, 0); - TYPE_SETHASBBOX(geoms[0]->type, 0); - TYPE_SETHASBBOX(geoms[1]->type, 0); + lwgeom_dropSRID(geoms[0]); + lwgeom_dropBBOX(geoms[0]); + lwgeom_dropSRID(geoms[1]); + lwgeom_dropBBOX(geoms[1]); // Find appropriate geom type if ( TYPE_GETTYPE(what->type) == POINTTYPE ) newtype = MULTIPOINTTYPE; else newtype = COLLECTIONTYPE; col = lwcollection_construct(newtype, - to->SRID, - ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->SRID, NULL, 2, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwpoly.c b/lwgeom/lwpoly.c index 192b560db..f88ca60ef 100644 --- a/lwgeom/lwpoly.c +++ b/lwgeom/lwpoly.c @@ -12,7 +12,7 @@ // construct a new LWPOLY. arrays (points/points per ring) will NOT be copied // use SRID=-1 for unknown SRID (will have 8bit type's S = 0) LWPOLY * -lwpoly_construct(int SRID, char wantbbox, unsigned int nrings, POINTARRAY **points) +lwpoly_construct(int SRID, BOX2DFLOAT4 *bbox, unsigned int nrings, POINTARRAY **points) { LWPOLY *result; int hasz, hasm; @@ -37,10 +37,11 @@ lwpoly_construct(int SRID, char wantbbox, unsigned int nrings, POINTARRAY **poin result = (LWPOLY*) lwalloc(sizeof(LWPOLY)); result->type = lwgeom_makeType_full(hasz, hasm, (SRID!=-1), POLYGONTYPE, - wantbbox); + 0); result->SRID = SRID; result->nrings = nrings; result->rings = points; + result->bbox = bbox; return result; } @@ -88,9 +89,11 @@ lwpoly_deserialize(char *serialized_form) loc = serialized_form+1; - if (lwgeom_hasBBOX(type)) - { + if (lwgeom_hasBBOX(type)) { + result->bbox = (BOX2DFLOAT4 *)loc; loc += sizeof(BOX2DFLOAT4); + } else { + result->bbox = NULL; } if ( lwgeom_hasSRID(type)) @@ -173,12 +176,12 @@ lwpoly_serialize_buf(LWPOLY *poly, char *buf, size_t *retsize) buf[0] = (unsigned char) lwgeom_makeType_full( TYPE_HASZ(poly->type), TYPE_HASM(poly->type), - hasSRID, POLYGONTYPE, TYPE_HASBBOX(poly->type)); + hasSRID, POLYGONTYPE, poly->bbox ? 1 : 0); loc = buf+1; - if (TYPE_HASBBOX(poly->type)) + if (poly->bbox) { - lwgeom_compute_bbox_p((LWGEOM *)poly, (BOX2DFLOAT4 *)loc); + memcpy(loc, poly->bbox, sizeof(BOX2DFLOAT4)); size += sizeof(BOX2DFLOAT4); // bvol loc += sizeof(BOX2DFLOAT4); } @@ -349,7 +352,7 @@ lwpoly_serialize_size(LWPOLY *poly) uint32 i; if ( poly->SRID != -1 ) size += 4; // SRID - if ( TYPE_HASBBOX(poly->type) ) size += sizeof(BOX2DFLOAT4); + if ( poly->bbox ) size += sizeof(BOX2DFLOAT4); #ifdef DEBUG_CALLS lwnotice("lwpoly_serialize_size called with poly[%p] (%d rings)", @@ -424,6 +427,8 @@ lwpoly_clone(const LWPOLY *g) memcpy(ret, g, sizeof(LWPOLY)); ret->rings = lwalloc(sizeof(POINTARRAY *)*g->nrings); memcpy(ret->rings, g->rings, sizeof(POINTARRAY *)*g->nrings); + if ( g->bbox && ! TYPE_HASBBOX(g->type) ) + ret->bbox = box2d_clone(g->bbox); return ret; } @@ -470,8 +475,7 @@ lwpoly_add(const LWPOLY *to, uint32 where, const LWGEOM *what) else newtype = COLLECTIONTYPE; col = lwcollection_construct(newtype, - to->SRID, - ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->SRID, NULL, 2, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwpostgis.sql.in b/lwgeom/lwpostgis.sql.in index 479052444..981d64916 100644 --- a/lwgeom/lwpostgis.sql.in +++ b/lwgeom/lwpostgis.sql.in @@ -95,7 +95,7 @@ CREATEFUNCTION geometry_out(geometry) #if USE_VERSION >= 80 CREATEFUNCTION geometry_analyze(internal) RETURNS bool - AS '@MODULE_FILENAME@', 'lwgeom_analyze' + AS '@MODULE_FILENAME@', 'LWGEOM_analyze' LANGUAGE 'C' WITH (isstrict); #endif @@ -242,42 +242,47 @@ CREATE TYPE box2d ( CREATEFUNCTION box2d_overleft(box2d, box2d) RETURNS bool - AS '@MODULE_FILENAME@' + AS '@MODULE_FILENAME@', 'BOX2D_overleft' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION box2d_overright(box2d, box2d) RETURNS bool - AS '@MODULE_FILENAME@' + AS '@MODULE_FILENAME@', 'BOX2D_overright' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION box2d_left(box2d, box2d) RETURNS bool - AS '@MODULE_FILENAME@' + AS '@MODULE_FILENAME@', 'BOX2D_left' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION box2d_right(box2d, box2d) RETURNS bool - AS '@MODULE_FILENAME@' + AS '@MODULE_FILENAME@', 'BOX2D_right' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION box2d_contain(box2d, box2d) RETURNS bool - AS '@MODULE_FILENAME@' + AS '@MODULE_FILENAME@', 'BOX2D_contain' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION box2d_contained(box2d, box2d) RETURNS bool - AS '@MODULE_FILENAME@' + AS '@MODULE_FILENAME@', 'BOX2D_contained' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION box2d_overlap(box2d, box2d) RETURNS bool - AS '@MODULE_FILENAME@' + AS '@MODULE_FILENAME@', 'BOX2D_overlap' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION box2d_same(box2d, box2d) RETURNS bool - AS '@MODULE_FILENAME@' + AS '@MODULE_FILENAME@', 'BOX2D_same' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATEFUNCTION box2d_intersects(box2d, box2d) + RETURNS bool + AS '@MODULE_FILENAME@', 'BOX2D_intersects' LANGUAGE 'C' WITH (isstrict,iscachable); CREATE OPERATOR << ( @@ -442,47 +447,47 @@ CREATEFUNCTION postgis_gist_sel(opaque, oid, opaque, int4) CREATEFUNCTION postgis_gist_sel (internal, oid, internal, int4) #endif RETURNS float8 - AS '@MODULE_FILENAME@', 'lwgeom_gist_sel' + AS '@MODULE_FILENAME@', 'LWGEOM_gist_sel' LANGUAGE 'C'; CREATEFUNCTION geometry_overleft(geometry, geometry) RETURNS bool - AS '@MODULE_FILENAME@', 'lwgeom_overleft' + AS '@MODULE_FILENAME@', 'LWGEOM_overleft' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION geometry_overright(geometry, geometry) RETURNS bool - AS '@MODULE_FILENAME@', 'lwgeom_overright' + AS '@MODULE_FILENAME@', 'LWGEOM_overright' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION geometry_left(geometry, geometry) RETURNS bool - AS '@MODULE_FILENAME@', 'lwgeom_left' + AS '@MODULE_FILENAME@', 'LWGEOM_left' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION geometry_right(geometry, geometry) RETURNS bool - AS '@MODULE_FILENAME@', 'lwgeom_right' + AS '@MODULE_FILENAME@', 'LWGEOM_right' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION geometry_contain(geometry, geometry) RETURNS bool - AS '@MODULE_FILENAME@', 'lwgeom_contain' + AS '@MODULE_FILENAME@', 'LWGEOM_contain' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION geometry_contained(geometry, geometry) RETURNS bool - AS '@MODULE_FILENAME@', 'lwgeom_contained' + AS '@MODULE_FILENAME@', 'LWGEOM_contained' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION geometry_overlap(geometry, geometry) RETURNS bool - AS '@MODULE_FILENAME@', 'lwgeom_overlap' + AS '@MODULE_FILENAME@', 'LWGEOM_overlap' LANGUAGE 'C' WITH (isstrict,iscachable); CREATEFUNCTION geometry_same(geometry, geometry) RETURNS bool - AS '@MODULE_FILENAME@', 'lwgeom_same' + AS '@MODULE_FILENAME@', 'LWGEOM_same' LANGUAGE 'C' WITH (isstrict,iscachable); CREATE OPERATOR << ( @@ -537,39 +542,39 @@ CREATE OPERATOR ~ ( -- gist support functions -CREATEFUNCTION gist_lwgeom_consistent(internal,geometry,int4) +CREATEFUNCTION LWGEOM_gist_consistent(internal,geometry,int4) RETURNS bool - AS '@MODULE_FILENAME@' ,'gist_lwgeom_consistent' + AS '@MODULE_FILENAME@' ,'LWGEOM_gist_consistent' LANGUAGE 'C'; -CREATEFUNCTION gist_lwgeom_compress(internal) +CREATEFUNCTION LWGEOM_gist_compress(internal) RETURNS internal - AS '@MODULE_FILENAME@','gist_lwgeom_compress' + AS '@MODULE_FILENAME@','LWGEOM_gist_compress' LANGUAGE 'C'; -CREATEFUNCTION gist_lwgeom_penalty(internal,internal,internal) +CREATEFUNCTION LWGEOM_gist_penalty(internal,internal,internal) RETURNS internal - AS '@MODULE_FILENAME@' ,'lwgeom_box_penalty' + AS '@MODULE_FILENAME@' ,'LWGEOM_gist_penalty' LANGUAGE 'C'; -CREATEFUNCTION gist_lwgeom_picksplit(internal, internal) +CREATEFUNCTION LWGEOM_gist_picksplit(internal, internal) RETURNS internal - AS '@MODULE_FILENAME@' ,'lwgeom_gbox_picksplit' + AS '@MODULE_FILENAME@' ,'LWGEOM_gist_picksplit' LANGUAGE 'C'; -CREATEFUNCTION gist_lwgeom_union(bytea, internal) +CREATEFUNCTION LWGEOM_gist_union(bytea, internal) RETURNS internal - AS '@MODULE_FILENAME@' ,'lwgeom_box_union' + AS '@MODULE_FILENAME@' ,'LWGEOM_gist_union' LANGUAGE 'C'; -CREATEFUNCTION gist_lwgeom_same(box2d, box2d, internal) +CREATEFUNCTION LWGEOM_gist_same(box2d, box2d, internal) RETURNS internal - AS '@MODULE_FILENAME@' ,'lwgeom_gbox_same' + AS '@MODULE_FILENAME@' ,'LWGEOM_gist_same' LANGUAGE 'C'; -CREATEFUNCTION gist_lwgeom_decompress(internal) +CREATEFUNCTION LWGEOM_gist_decompress(internal) RETURNS internal - AS '@MODULE_FILENAME@' ,'gist_rtree_decompress' + AS '@MODULE_FILENAME@' ,'LWGEOM_gist_decompress' LANGUAGE 'C'; ------------------------------------------- @@ -654,43 +659,43 @@ INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) SELECT am.oid, opcl.oid, pro.oid, 1 FROM pg_am am, pg_opclass opcl, pg_proc pro WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' - AND proname = 'gist_lwgeom_consistent'; + AND proname = 'LWGEOM_gist_consistent'; INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) SELECT am.oid, opcl.oid, pro.oid, 2 FROM pg_am am, pg_opclass opcl, pg_proc pro WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' - AND proname = 'gist_lwgeom_union'; + AND proname = 'LWGEOM_gist_union'; INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) SELECT am.oid, opcl.oid, pro.oid, 3 FROM pg_am am, pg_opclass opcl, pg_proc pro WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' - AND proname = 'gist_lwgeom_compress'; + AND proname = 'LWGEOM_gist_compress'; INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) SELECT am.oid, opcl.oid, pro.oid, 4 FROM pg_am am, pg_opclass opcl, pg_proc pro WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' - AND proname = 'gist_lwgeom_decompress'; + AND proname = 'LWGEOM_gist_decompress'; INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) SELECT am.oid, opcl.oid, pro.oid, 5 FROM pg_am am, pg_opclass opcl, pg_proc pro WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' - AND proname = 'gist_lwgeom_penalty'; + AND proname = 'LWGEOM_gist_penalty'; INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) SELECT am.oid, opcl.oid, pro.oid, 6 FROM pg_am am, pg_opclass opcl, pg_proc pro WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' - AND proname = 'gist_lwgeom_picksplit'; + AND proname = 'LWGEOM_gist_picksplit'; INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum) SELECT am.oid, opcl.oid, pro.oid, 7 FROM pg_am am, pg_opclass opcl, pg_proc pro WHERE amname = 'gist' AND opcname = 'gist_geometry_ops' - AND proname = 'gist_lwgeom_same'; + AND proname = 'LWGEOM_gist_same'; #elsif USE_VERSION == 72 @@ -796,7 +801,7 @@ INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_geometry_ops' - and proname = 'gist_lwgeom_consistent'; + and proname = 'LWGEOM_gist_consistent'; INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) SELECT opcl.oid, 2, pro.oid @@ -804,7 +809,7 @@ INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_geometry_ops' - and proname = 'gist_lwgeom_union'; + and proname = 'LWGEOM_gist_union'; INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) SELECT opcl.oid, 3, pro.oid @@ -812,7 +817,7 @@ INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_geometry_ops' - and proname = 'gist_lwgeom_compress'; + and proname = 'LWGEOM_gist_compress'; INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) SELECT opcl.oid, 4, pro.oid @@ -820,7 +825,7 @@ INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_geometry_ops' - and proname = 'gist_lwgeom_decompress'; + and proname = 'LWGEOM_gist_decompress'; INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) SELECT opcl.oid, 5, pro.oid @@ -828,7 +833,7 @@ INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_geometry_ops' - and proname = 'gist_lwgeom_penalty'; + and proname = 'LWGEOM_gist_penalty'; INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) SELECT opcl.oid, 6, pro.oid @@ -836,7 +841,7 @@ INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_geometry_ops' - and proname = 'gist_lwgeom_picksplit'; + and proname = 'LWGEOM_gist_picksplit'; INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) SELECT opcl.oid, 7, pro.oid @@ -844,7 +849,7 @@ INSERT INTO pg_amproc (amopclaid, amprocnum, amproc) WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') and opcname = 'gist_geometry_ops' - and proname = 'gist_lwgeom_same'; + and proname = 'LWGEOM_gist_same'; #else // USE_VERSION >= 73 @@ -862,13 +867,13 @@ CREATE OPERATOR CLASS gist_geometry_ops OPERATOR 6 ~= RECHECK, OPERATOR 7 ~ RECHECK, OPERATOR 8 @ RECHECK, - FUNCTION 1 gist_lwgeom_consistent (internal, geometry, int4), - FUNCTION 2 gist_lwgeom_union (bytea, internal), - FUNCTION 3 gist_lwgeom_compress (internal), - FUNCTION 4 gist_lwgeom_decompress (internal), - FUNCTION 5 gist_lwgeom_penalty (internal, internal, internal), - FUNCTION 6 gist_lwgeom_picksplit (internal, internal), - FUNCTION 7 gist_lwgeom_same (box2d, box2d, internal); + FUNCTION 1 LWGEOM_gist_consistent (internal, geometry, int4), + FUNCTION 2 LWGEOM_gist_union (bytea, internal), + FUNCTION 3 LWGEOM_gist_compress (internal), + FUNCTION 4 LWGEOM_gist_decompress (internal), + FUNCTION 5 LWGEOM_gist_penalty (internal, internal, internal), + FUNCTION 6 LWGEOM_gist_picksplit (internal, internal), + FUNCTION 7 LWGEOM_gist_same (box2d, box2d, internal); UPDATE pg_opclass SET opckeytype = (select oid from pg_type where typname = 'box2d') diff --git a/lwgeom/ptarray.c b/lwgeom/ptarray.c index e02cc3614..90100cfaa 100644 --- a/lwgeom/ptarray.c +++ b/lwgeom/ptarray.c @@ -59,3 +59,65 @@ ptarray_reverse(POINTARRAY *pa) } } + +// calculate the 2d bounding box of a set of points +// write result to the provided BOX2DFLOAT4 +// Return 0 if bounding box is NULL (empty geom) +int +ptarray_compute_bbox_p(const POINTARRAY *pa, BOX2DFLOAT4 *result) +{ + int t; + POINT2D *pt; + + if (pa->npoints == 0) return 0; + + pt = (POINT2D *)getPoint(pa, 0); + + result->xmin = pt->x; + result->xmax = pt->x; + result->ymin = pt->y; + result->ymax = pt->y; + + for (t=1;tnpoints;t++) + { + pt = (POINT2D *)getPoint(pa, t); + if (pt->x < result->xmin) result->xmin = pt->x; + if (pt->y < result->ymin) result->ymin = pt->y; + if (pt->x > result->xmax) result->xmax = pt->x; + if (pt->y > result->ymax) result->ymax = pt->y; + } + + return 1; +} + +// calculate the 2d bounding box of a set of points +// return allocated BOX2DFLOAT4 or NULL (for empty array) +BOX2DFLOAT4 * +ptarray_compute_bbox(const POINTARRAY *pa) +{ + int t; + POINT2D *pt; + BOX2DFLOAT4 *result; + + if (pa->npoints == 0) return NULL; + + result = lwalloc(sizeof(BOX2DFLOAT4)); + + pt = (POINT2D *)getPoint(pa, 0); + + result->xmin = pt->x; + result->xmax = pt->x; + result->ymin = pt->y; + result->ymax = pt->y; + + for (t=1;tnpoints;t++) + { + pt = (POINT2D *)getPoint(pa, t); + if (pt->x < result->xmin) result->xmin = pt->x; + if (pt->y < result->ymin) result->ymin = pt->y; + if (pt->x > result->xmax) result->xmax = pt->x; + if (pt->y > result->ymax) result->ymax = pt->y; + } + + return result; +}