Changed LWGEOM structure to point to an actual BOX2DFLOAT4.
authorSandro Santilli <strk@keybit.net>
Fri, 8 Oct 2004 13:20:55 +0000 (13:20 +0000)
committerSandro Santilli <strk@keybit.net>
Fri, 8 Oct 2004 13:20:55 +0000 (13:20 +0000)
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

23 files changed:
lwgeom/liblwgeom.h
lwgeom/lwcollection.c
lwgeom/lwgeom.c
lwgeom/lwgeom_api.c
lwgeom/lwgeom_box2dfloat4.c
lwgeom/lwgeom_box3d.c
lwgeom/lwgeom_chip.c
lwgeom/lwgeom_estimate.c
lwgeom/lwgeom_functions_analytic.c
lwgeom/lwgeom_functions_basic.c
lwgeom/lwgeom_geos.c
lwgeom/lwgeom_geos_wrapper.cpp
lwgeom/lwgeom_gist.c
lwgeom/lwgeom_ogc.c
lwgeom/lwgeom_pg.h
lwgeom/lwline.c
lwgeom/lwmline.c
lwgeom/lwmpoint.c
lwgeom/lwmpoly.c
lwgeom/lwpoint.c
lwgeom/lwpoly.c
lwgeom/lwpostgis.sql.in
lwgeom/ptarray.c

index a9c10250686d3daceb628d29371bfab19f8d2de5..4817123a326f12f03fac360cba23fa358ed150aa 100644 (file)
@@ -1,12 +1,16 @@
 #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);
@@ -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);
index 5887a0781f90c6b2950d2706b063bb37c64714c8..4ccec4814a545dcb3657001d54bc161d73bbb691 100644 (file)
@@ -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; i<insp->ngeometries; 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; 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;
index 01226413ca581dde433ea70433dec752898910c5..38970967351787a94dfd510023098e8833fc3b9a 100644 (file)
@@ -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;
+}
index 1843813aa4b8a2d3da14faf0dcf89b0a21ecfc7a..817c64b927c233424c95713b4982bd5ab0139866 100644 (file)
@@ -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;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
index e673cb02a7007e9af7b91dabf935dd66c27863d2..3ebd58cebeacff785841262533ddd6af6d883c0f 100644 (file)
@@ -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);
index 6b83276fee48a26d561201ca827a3d079a5a861e..972be7dd79db14a5ac82413047dc69e6a7ae8e42 100644 (file)
@@ -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);
index c1e2c3a2da53fc0b512c44bc30831290964f652d..3ed77408dbec47ed37d4c21850313b5b6e10bd33 100644 (file)
@@ -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);
index 0db0dc1d58804d457cd0918bd6d3158bf0f1571a..47839585697e783e5b3c8a97d9fa99801cd9e0e8 100644 (file)
  * 
  **********************************************************************
  * $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;
index e859b032326fecc00053f2644b16065c4ee1795d..21cc6240093798de6b2e0956ab1df54548c514ac 100644 (file)
@@ -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;
 }
index 19b11a06c2e06b37227c065e5611a5479888dd99..509c5031ac48346607c21c74109510e642e2458a 100644 (file)
@@ -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 *)&cent, 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);
+}
+
index b6fdc925a87ddc8f9b4a8585b02ff50f3e30c49c..9eb7de1b6dff9f989777670b723dec8d3f14c23b 100644 (file)
@@ -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;
index a6ca4ae58726ae5eee352de26a53d6a5ee643a62..8be8739029a40e62f5ed4e06a4ef6fee54791457 100644 (file)
@@ -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;
        }
index 52eb7ae9b266845cf8b3ecfce5ae4ee787947fb9..d24782b426166e0b7c4745b5a84c9bc6d2b73bb6 100644 (file)
 //#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");
 
index 72b81b65dd1d12834ee70ad9b52f2e6e718d7ae8..5c186f638cfc423973ba7d00cbaba8ef2a8e3b1a 100644 (file)
@@ -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; i<inspected->ngeometries; 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);
index ed4631141e7a77859d2b83f26cbae051617cd858..f09a24382d5efd1c9626158b0d68c6e8c67c59e8 100644 (file)
@@ -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
index d10175ffcc48f355e927de5009418bf1871393e7..d58f77cd06a1509804e7116b121b785de7a50ba3 100644 (file)
@@ -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;
index fe5c0d06259bc914e73cc19d71c512c93b3ae00c..5a98c897aa1334e3a861da693285903d7546508c 100644 (file)
@@ -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; i<insp->ngeometries; 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;
index 5ac12bb2defb75a1a87e733f0ce27fe3ee71138f..a6562d233077ee41f807b64d5fe3eb6922aeeba1 100644 (file)
@@ -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; i<insp->ngeometries; 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;
index 5364c67f7a2d20a5e87de3f1a8db41d92b731015..1d1db25ca715530a034ebae5c8aacfd50dca6dda 100644 (file)
@@ -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; i<insp->ngeometries; 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;
index 67405b113495bcf481449f2fa5623efd57aaea69..25360e8375c6be571f1ed50f3b0239cda791d709 100644 (file)
@@ -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;
index 192b560db3c3a3c84d94d3eadfbbb48228f01a92..f88ca60ef5669439d8664a72064e527aa396a5f1 100644 (file)
@@ -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;
index 4790524449a608b10434a1dc62db86cf45cc98df..981d6491650abd09aa5694995e20f13d922c6119 100644 (file)
@@ -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') 
index e02cc361423d31d4ca1d9a99d9eeeb0b6731f076..90100cfaa4bddabcfa46fe95cd94bcf54b1452e6 100644 (file)
@@ -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;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;
+}