#ifndef _LIBLWGEOM_H
#define _LIBLWGEOM_H 1
+#include <stdio.h>
+
+#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);
typedef struct
{
unsigned char type;
+ BOX2DFLOAT4 *bbox;
uint32 SRID; // -1 == unneeded
void *data;
} LWGEOM;
// 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"
// LINETYPE
typedef struct
{
- int type; // LINETYPE
+ unsigned char type; // LINETYPE
+ BOX2DFLOAT4 *bbox;
uint32 SRID;
POINTARRAY *points; // array of POINT3D
} LWLINE; //"light-weight line"
// POLYGONTYPE
typedef struct
{
- int type; // POLYGONTYPE
+ unsigned char type; // POLYGONTYPE
+ BOX2DFLOAT4 *bbox;
uint32 SRID;
int nrings;
POINTARRAY **rings; // list of rings (list of points)
typedef struct
{
unsigned char type;
+ BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
LWPOINT **geoms;
typedef struct
{
unsigned char type;
+ BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
LWLINE **geoms;
typedef struct
{
unsigned char type;
+ BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
LWPOLY **geoms;
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
// 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)
//--------------------------------------------------------
-// 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.
//--------------------------------------------------------
-// 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.
// 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
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);
// 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);
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);
#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;
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;
}
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; i<insp->ngeometries; i++)
{
result->geoms[i] = lwgeom_deserialize(insp->sub_geoms[i]);
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);
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);
}
{
ret->geoms[i] = lwgeom_clone(g->geoms[i]);
}
+ if ( g->bbox && ! TYPE_HASBBOX(g->type) )
+ ret->bbox = box2d_clone(g->bbox);
return ret;
}
for (i=0; i<where; i++)
{
geoms[i] = lwgeom_clone(to->geoms[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; i<to->ngeoms; 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;
{
int type = lwgeom_getType(srl[0]);
+ lwnotice("lwgeom_deserialize got %s", lwgeom_typename(type));
+
switch (type)
{
case POINTTYPE:
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;
}
uint32 i;
LWCOLLECTION *col;
+#ifdef INTEGRITY_CHECKS
+ if ( ! lwgeom )
+ lwerror("lwgeom_release: someone called on 0x0");
+#endif
+
// Collection
if ( (col=lwgeom_as_lwcollection(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;
+}
// 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));
// 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)
{
// 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;
// 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;
// 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;
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)
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
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;t<pa->npoints;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
/* 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);
/* 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);
* 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);
/* 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);
/* 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);
* 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);
/* 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);
/* 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);
}
-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);
}
//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)
{
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);
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);
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);
*
**********************************************************************
* $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
*
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:
}
//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);
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))
{
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) ;
}
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) ;
}
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);
}
* 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);
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);
}
* 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;
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;
}
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;
}
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);
}
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);
}
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);
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);
+}
+
* 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
GEOSdeleteChar( (char*) pts);
// Construct LWPOINT
- point = lwpoint_construct(-1, 0, pa);
+ point = lwpoint_construct(-1, NULL, pa);
return point;
}
GEOSdeleteChar( (char*) pts);
// Construct LWPOINT
- line = lwline_construct(-1, 0, pa);
+ line = lwline_construct(-1, NULL, pa);
return line;
}
}
// Construct LWPOLY
- poly = lwpoly_construct(-1, 0, nrings+1, rings);
+ poly = lwpoly_construct(-1, NULL, nrings+1, rings);
return poly;
}
LWCOLLECTION *ret;
int type = GEOSGeometryTypeId(geom) ;
int SRID = GEOSGetSRID(geom);
- char wantbbox = 0;
int i;
ngeoms = GEOSGetNumGeometries(geom);
#endif
}
- ret = lwcollection_construct(type, SRID, wantbbox, ngeoms, geoms);
+ ret = lwcollection_construct(type, SRID, NULL, ngeoms, geoms);
return ret;
}
{
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;
#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;
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"
typedef struct
{
unsigned char type;
+ BOX2DFLOAT4 *bbox;
uint32 SRID;
POINTARRAY *points; // array of POINT3D
} LWLINE; //"light-weight line"
typedef struct
{
unsigned char type;
+ BOX2DFLOAT4 *bbox;
uint32 SRID;
int nrings;
POINTARRAY **rings; // list of rings (list of points)
extern "C" Geometry *GEOSGetCentroid(Geometry *g1);
-extern "C" void lwnotice(char *msg);
+extern "C" void NOTICE_MESSAGE(char *msg);
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete cl;
return NULL;
}
#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
{
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
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{
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
{
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
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
char buf[256];
sprintf(buf, "PostGIS2GEOS_collection: requested type %d, ngeoms: %d",
type, ngeoms);
- lwnotice(buf);
+ NOTICE_MESSAGE(buf);
#endif
try
g = geomFactory->createMultiPolygon(subGeos);
break;
default:
- lwnotice("Unsupported type request for PostGIS2GEOS_collection");
+ NOTICE_MESSAGE("Unsupported type request for PostGIS2GEOS_collection");
g = NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 2;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return -1;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
//return NULL;
}
}
catch (GEOSException *ge) // ???
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
//return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 0;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 0;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 0;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 0;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return NULL;
}
}
catch (GEOSException *ge)
{
- lwnotice((char *)ge->toString().c_str());
+ NOTICE_MESSAGE((char *)ge->toString().c_str());
delete ge;
return 0;
}
//#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);
// 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));
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);
}
-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));
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);
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));
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);
}
-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));
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);
}
-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));
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);
}
-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));
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);
}
-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));
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);
// 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
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)
}
#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));
//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) ||
#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);
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);
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;
}
}
-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
* 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!
}
//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))
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
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;
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) &&
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;
-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
* 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);
*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
** 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);
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));
*/
#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
/*
** 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);
** 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);
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;
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");
LWLINE *line;
char *serializedline;
PG_LWGEOM *result;
+ BOX2DFLOAT4 *bbox;
int i;
for (i=0; i<inspected->ngeometries; i++)
// 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);
LWLINE *line;
char *serializedline;
PG_LWGEOM *result;
+ BOX2DFLOAT4 *bbox = NULL;
int i;
wanted_index = PG_GETARG_INT32(1);
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);
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);
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);
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);
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
// 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));
TYPE_HASZ(points->dims),
TYPE_HASM(points->dims),
(SRID!=-1), LINETYPE,
- wantbbox);
+ 0);
result->SRID = SRID;
result->points = points;
+ result->bbox = bbox;
return result;
}
if (lwgeom_hasBBOX(type))
{
//lwnotice("line has bbox");
+ result->bbox = (BOX2DFLOAT4 *)loc;
loc += sizeof(BOX2DFLOAT4);
}
else
{
+ result->bbox = NULL;
//lwnotice("line has NO bbox");
}
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");
#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;
{
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;
}
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;
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; i<insp->ngeometries; i++)
{
result->geoms[i] = lwline_deserialize(insp->sub_geoms[i]);
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;
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; i<insp->ngeometries; i++)
{
result->geoms[i] = lwpoint_deserialize(insp->sub_geoms[i]);
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;
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; i<insp->ngeometries; i++)
{
result->geoms[i] = lwpoly_deserialize(insp->sub_geoms[i]);
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;
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);
}
// 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 ;
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;
}
#ifdef DEBUG
lwnotice("lwpoint_deserialize: input has bbox");
#endif
+ result->bbox = (BOX2DFLOAT4 *)loc;
loc += sizeof(BOX2DFLOAT4);
}
+ else
+ {
+ result->bbox = NULL;
+ }
if ( lwgeom_hasSRID(type))
{
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;
}
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;
// 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;
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;
}
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))
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);
}
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)",
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;
}
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;
#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
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 << (
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 << (
-- 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';
-------------------------------------------
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
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
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
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
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
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
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
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
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')
}
}
+
+// 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;t<pa->npoints;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;t<pa->npoints;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;
+}