]> granicus.if.org Git - postgis/commitdiff
Made GEOS<->LWGEOM converters keep geometry structures.
authorSandro Santilli <strk@keybit.net>
Sun, 3 Oct 2004 15:52:23 +0000 (15:52 +0000)
committerSandro Santilli <strk@keybit.net>
Sun, 3 Oct 2004 15:52:23 +0000 (15:52 +0000)
Fixed bug in serializers.
Added noop(geometry) for deserialize/serialize debugging.

git-svn-id: http://svn.osgeo.org/postgis/trunk@920 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/liblwgeom.h
lwgeom/lwcollection.c
lwgeom/lwgeom.c
lwgeom/lwgeom_api.c
lwgeom/lwgeom_functions_basic.c
lwgeom/lwgeom_geos.c
lwgeom/lwgeom_geos_wrapper.cpp
lwgeom/lwline.c
lwgeom/lwpoint.c
lwgeom/lwpoly.c
lwgeom/lwpostgis.sql.in

index 031187d665d12f1e6499006aeda1ce95a4e30ef7..bd500e06815ff06d1168df6501a1f632e1734936 100644 (file)
@@ -416,7 +416,7 @@ extern size_t lwpoint_serialize_size(LWPOINT *point);
 extern char  *lwpoint_serialize(LWPOINT *point);
 
 // same as above, writes to buf
-extern void lwpoint_serialize_buf(LWPOINT *point, char *buf, int *size);
+extern void lwpoint_serialize_buf(LWPOINT *point, char *buf, size_t *size);
 
 // find bounding box (standard one)  zmin=zmax=0 if 2d (might change to NaN)
 extern BOX3D *lwpoint_findbbox(LWPOINT *point);
@@ -446,7 +446,7 @@ extern size_t lwline_serialize_size(LWLINE *line);
 extern char  *lwline_serialize(LWLINE *line);
 
 // same as above, writes to buf
-extern void lwline_serialize_buf(LWLINE *line, char *buf, int *size);
+extern void lwline_serialize_buf(LWLINE *line, char *buf, size_t *size);
 
 // find bounding box (standard one)  zmin=zmax=0 if 2d (might change to NaN)
 extern BOX3D *lwline_findbbox(LWLINE *line);
@@ -472,7 +472,7 @@ extern size_t lwpoly_serialize_size(LWPOLY *poly);
 extern char *lwpoly_serialize(LWPOLY *poly);
 
 // same as above, writes to buf
-extern void lwpoly_serialize_buf(LWPOLY *poly, char *buf, int *size);
+extern void lwpoly_serialize_buf(LWPOLY *poly, char *buf, size_t *size);
 
 // find bounding box (standard one)  zmin=zmax=0 if 2d (might change to NaN)
 extern BOX3D *lwpoly_findbbox(LWPOLY *poly);
@@ -482,9 +482,9 @@ extern BOX3D *lwpoly_findbbox(LWPOLY *poly);
 
 extern size_t lwgeom_serialize_size(LWGEOM *geom);
 extern size_t lwcollection_serialize_size(LWCOLLECTION *coll);
-extern void lwgeom_serialize_buf(LWGEOM *geom, char *buf, int *size);
+extern void lwgeom_serialize_buf(LWGEOM *geom, char *buf, size_t *size);
 extern char *lwgeom_serialize(LWGEOM *geom);
-extern void lwcollection_serialize_buf(LWCOLLECTION *mcoll, char *buf, int *size);
+extern void lwcollection_serialize_buf(LWCOLLECTION *mcoll, char *buf, size_t *size);
 
 //-----------------------------------------------------
 
@@ -578,7 +578,7 @@ extern uint32 lwexploded_findlength(LWGEOM_EXPLODED *exp, int wantbbox);
 extern char *lwexploded_serialize(LWGEOM_EXPLODED *exploded, int wantbbox);
 
 // Same as lwexploded_serialize but writing to pre-allocated space
-extern void lwexploded_serialize_buf(LWGEOM_EXPLODED *exploded, int wantbbox, char *buf, int *retsize);
+extern void lwexploded_serialize_buf(LWGEOM_EXPLODED *exploded, int wantbbox, char *buf, size_t *retsize);
 
 // note - for a simple type (ie. point), this will have sub_geom[0] = serialized_form.
 // for multi-geomtries sub_geom[0] will be a few bytes into the serialized form
index 2e4cf94051ab20c276fa1691c013375bae67d60a..967b8c8755bd458e82f09eae31e00931aa5db18e 100644 (file)
@@ -3,6 +3,8 @@
 #include <string.h>
 #include "liblwgeom.h"
 
+//#define DEBUG_CALLS 1
+
 LWCOLLECTION *
 lwcollection_deserialize(char *srl)
 {
@@ -53,8 +55,22 @@ lwcollection_serialize_size(LWCOLLECTION *col)
        if ( col->SRID != -1 ) size += 4; // SRID
        if ( col->hasbbox ) size += sizeof(BOX2DFLOAT4);
 
+#ifdef DEBUG_CALLS
+       lwnotice("lwcollection_serialize_size[%p]: start size: %d", col, size);
+#endif
+
+
        for (i=0; i<col->ngeoms; i++)
+       {
                size += lwgeom_serialize_size(lwcollection_getsubgeom(col, i));
+#ifdef DEBUG_CALLS
+               lwnotice("lwcollection_serialize_size[%p]: with geom%d: %d", col, i, size);
+#endif
+       }
+
+#ifdef DEBUG_CALLS
+       lwnotice("lwcollection_serialize_size[%p]:  returning %d", col, size);
+#endif
 
        return size; 
 }
@@ -63,7 +79,7 @@ lwcollection_serialize_size(LWCOLLECTION *col)
 // the given buffer, and returning number of bytes written into
 // the given int pointer.
 void
-lwcollection_serialize_buf(LWCOLLECTION *coll, char *buf, int *retsize)
+lwcollection_serialize_buf(LWCOLLECTION *coll, char *buf, size_t *retsize)
 {
        int size=1; // type 
        int subsize=0;
@@ -73,8 +89,8 @@ lwcollection_serialize_buf(LWCOLLECTION *coll, char *buf, int *retsize)
 
        hasSRID = (coll->SRID != -1);
 
-       buf[0] = (unsigned char) lwgeom_makeType(coll->ndims,
-               hasSRID, COLLECTIONTYPE);
+       buf[0] = (unsigned char) lwgeom_makeType_full(coll->ndims,
+               hasSRID, coll->type, coll->hasbbox);
        loc = buf+1;
 
        // Add BBOX if requested
@@ -103,6 +119,7 @@ lwcollection_serialize_buf(LWCOLLECTION *coll, char *buf, int *retsize)
        {
                lwgeom_serialize_buf(coll->geoms[i], loc, &subsize);
                size += subsize;
+               loc += subsize;
        }
 
        if (retsize) *retsize = size;
index 7cf950c4d993e60c3e9a27027b5500cc066bd298..57ebe24081392e5710c2f89df72fac33348fe049 100644 (file)
@@ -5,6 +5,8 @@
 #include "lwgeom_pg.h"
 #include "liblwgeom.h"
 
+//#define DEBUG_CALLS 1
+
 LWGEOM *
 lwgeom_deserialize(char *srl)
 {
@@ -37,34 +39,39 @@ size_t
 lwgeom_serialize_size(LWGEOM *lwgeom)
 {
        int type = lwgeom->type;
-       size_t size;
+
+#ifdef DEBUG_CALLS
+       lwnotice("lwgeom_serialize_size called");
+#endif
 
        switch (type)
        {
                case POINTTYPE:
-                       size = lwpoint_serialize_size((LWPOINT *)lwgeom);
+                       return lwpoint_serialize_size((LWPOINT *)lwgeom);
                case LINETYPE:
-                       size = lwline_serialize_size((LWLINE *)lwgeom);
+                       return lwline_serialize_size((LWLINE *)lwgeom);
                case POLYGONTYPE:
-                       size = lwpoly_serialize_size((LWPOLY *)lwgeom);
+                       return lwpoly_serialize_size((LWPOLY *)lwgeom);
                case MULTIPOINTTYPE:
                case MULTILINETYPE:
                case MULTIPOLYGONTYPE:
                case COLLECTIONTYPE:
-                       size = lwcollection_serialize_size((LWCOLLECTION *)lwgeom);
+                       return lwcollection_serialize_size((LWCOLLECTION *)lwgeom);
                default:
                        lwerror("Unknown geometry type: %d", type);
                        return 0;
        }
-
-       return size;
 }
 
 void
-lwgeom_serialize_buf(LWGEOM *lwgeom, char *buf, int *retsize)
+lwgeom_serialize_buf(LWGEOM *lwgeom, char *buf, size_t *retsize)
 {
        int type = lwgeom->type;
 
+#ifdef DEBUG_CALLS 
+       lwnotice("lwgeom_serialize_buf called with a %s",
+                       lwgeom_typename(type));
+#endif
        switch (type)
        {
                case POINTTYPE:
@@ -318,3 +325,4 @@ lwgeom_add(const LWGEOM *to, uint32 where, const LWGEOM *what)
                        return NULL;
        }
 }
+
index dea11b88b6e44775f937cf51069a67b7cac83b6a..111e041607e95db095074f72ad3f30521d5b86bd 100644 (file)
@@ -2222,9 +2222,9 @@ lwexploded_serialize(LWGEOM_EXPLODED *exploded, int wantbbox)
  */
 void
 lwexploded_serialize_buf(LWGEOM_EXPLODED *exploded, int wantbbox,
-       char *buf, int *retsize)
+       char *buf, size_t *retsize)
 {
-       unsigned int size=0;
+       size_t size=0;
        int i;
        int ntypes = 0;
        int ngeoms = 0;
index dd166832e1a40e9870b946e57425c942d6f8eb2e..d269d76650bbe98e8406cad0b937daa4d99c76fa 100644 (file)
@@ -2731,3 +2731,30 @@ Datum LWGEOM_forceRHR_poly(PG_FUNCTION_ARGS)
 
        PG_RETURN_POINTER(geom);
 }
+
+// Test deserialize/serialize operations
+PG_FUNCTION_INFO_V1(LWGEOM_noop);
+Datum LWGEOM_noop(PG_FUNCTION_ARGS)
+{
+       PG_LWGEOM *in, *out;
+       LWGEOM *lwgeom;
+       size_t size, retsize;
+
+       in = (PG_LWGEOM *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
+
+       lwgeom = lwgeom_deserialize(SERIALIZED_FORM(in));
+
+       lwnotice("Deserialized: %s", lwgeom_summary(lwgeom, 0));
+
+       size = lwgeom_serialize_size(lwgeom);
+       out = palloc(size+4);
+       out->size = size+4;
+       lwgeom_serialize_buf(lwgeom, SERIALIZED_FORM(out), &retsize);
+
+       if ( size != retsize )
+       {
+               lwerror ("lwgeom_serialize_buf returned size(%d) != lwgeom_serialize_size (%d)", retsize, size);
+       }
+
+       PG_RETURN_POINTER(out);
+}
index 9991d4f5d56c772c659a881078acd517b70997eb..9da7a115d439d07da9708dd3921856ddc2593dec 100644 (file)
@@ -44,8 +44,10 @@ Datum centroid(PG_FUNCTION_ARGS);
  * during postgis->geos and geos->postgis conversions
  */
 #undef DEBUG_CONVERTER
-#undef DEBUG_POSTGIS2GEOS 
-#undef DEBUG_GEOS2POSTGIS 
+#ifdef DEBUG_CONVERTER
+#define DEBUG_POSTGIS2GEOS 1
+#define DEBUG_GEOS2POSTGIS 1
+#endif // DEBUG_CONVERTER
 
 typedef  struct Geometry Geometry;
 
@@ -96,19 +98,20 @@ extern int      GEOSGetNumGeometries(Geometry *g1);
 extern Geometry *PostGIS2GEOS_point(const LWPOINT *point);
 extern Geometry *PostGIS2GEOS_linestring(const LWLINE *line);
 extern Geometry *PostGIS2GEOS_polygon(const LWPOLY *polygon);
-extern Geometry *PostGIS2GEOS_multipolygon(LWPOLY *const *const geoms, uint32 ngeoms, int SRID, int is3d);
-extern Geometry *PostGIS2GEOS_multilinestring(LWLINE *const *const geoms, uint32 ngeoms, int SRID, int is3d);
-extern Geometry *PostGIS2GEOS_multipoint(LWPOINT *const *const geoms, uint32 ngeoms, int SRID, int is3d);
-extern Geometry *PostGIS2GEOS_collection(Geometry **geoms, int ngeoms, int SRID, bool is3d);
+extern Geometry *PostGIS2GEOS_multipolygon(LWPOLY **geoms, uint32 ngeoms, int SRID, int is3d);
+extern Geometry *PostGIS2GEOS_multilinestring(LWLINE **geoms, uint32 ngeoms, int SRID, int is3d);
+extern Geometry *PostGIS2GEOS_multipoint(LWPOINT **geoms, uint32 ngeoms, int SRID, int is3d);
+extern Geometry *PostGIS2GEOS_collection(int type, Geometry **geoms, int ngeoms, int SRID, bool is3d);
 
 void NOTICE_MESSAGE(char *msg);
 PG_LWGEOM *GEOS2POSTGIS(Geometry *geom, char want3d);
 Geometry * POSTGIS2GEOS(PG_LWGEOM *g);
 void errorIfGeometryCollection(PG_LWGEOM *g1, PG_LWGEOM *g2);
-char *PointFromGeometry(Geometry *g, char want3d);
-char *LineFromGeometry(Geometry *g, char want3d);
-char *PolyFromGeometry(Geometry *g, char want3d);
-void addToExploded_recursive(Geometry *geom, LWGEOM_EXPLODED *exp);
+LWPOINT *lwpoint_from_geometry(Geometry *g, char want3d);
+LWLINE *lwline_from_geometry(Geometry *g, char want3d);
+LWPOLY *lwpoly_from_geometry(Geometry *g, char want3d);
+LWCOLLECTION *lwcollection_from_geometry(Geometry *geom, char want3d);
+LWGEOM *lwgeom_from_geometry(Geometry *g, char want3d);
 
 void NOTICE_MESSAGE(char *msg)
 {
@@ -1870,14 +1873,20 @@ Datum isring(PG_FUNCTION_ARGS)
 
 //= GEOS <=> POSTGIS CONVERSION =========================
 
-// Return a serialized line from a GEOS geometry (no SRID, no BBOX)
-char *PointFromGeometry(Geometry *g, char want3d)
+//-----=GEOS2POSTGIS=
+
+// Return a LWPOINT from a GEOS Point.
+LWPOINT *
+lwpoint_from_geometry(Geometry *g, char want3d)
 {
        POINTARRAY *pa;
        LWPOINT *point;
-       char *srl;
        POINT3D *pts;
-       int ptsize = want3d ? sizeof(POINT3D) : sizeof(POINT2D);
+       size_t ptsize = want3d ? sizeof(POINT3D) : sizeof(POINT2D);
+
+#ifdef DEBUG_GEOS2POSTGIS
+       elog(NOTICE, "lwpoint_from_geometry: point size %d", ptsize);
+#endif
 
        // Construct point array
        pa = (POINTARRAY *)palloc(sizeof(POINTARRAY));
@@ -1885,7 +1894,7 @@ char *PointFromGeometry(Geometry *g, char want3d)
        pa->npoints = 1;
 
        // Fill point array
-       pa->serialized_pointlist = palloc(ptsize);
+       pa->serialized_pointlist = lwalloc(ptsize);
        pts = GEOSGetCoordinates(g);
        memcpy(pa->serialized_pointlist, pts, ptsize);
        GEOSdeleteChar( (char*) pts);
@@ -1893,23 +1902,24 @@ char *PointFromGeometry(Geometry *g, char want3d)
        // Construct LWPOINT
        point = lwpoint_construct(pa->ndims, -1, pa);
 
-       // Serialize LWPOINT
-       srl = lwpoint_serialize(point);
-
-       return srl;
+       return point;
 }
 
-// Return a serialized line from a GEOS geometry (no SRID no BBOX)
-char *LineFromGeometry(Geometry *g, char want3d)
+// Return a LWLINE from a GEOS linestring
+LWLINE *
+lwline_from_geometry(Geometry *g, char want3d)
 {
        POINTARRAY *pa;
        LWLINE *line;
        int npoints;
-       char *srl;
        POINT3D *pts, *ip, *op;
        int ptsize = want3d ? sizeof(POINT3D) : sizeof(POINT2D);
        int i;
 
+#ifdef DEBUG_GEOS2POSTGIS
+       elog(NOTICE, "lwline_from_geometry: point size %d", ptsize);
+#endif
+
        npoints = GEOSGetNumCoordinate(g);
        if (npoints <2) return NULL;
 
@@ -1932,14 +1942,12 @@ char *LineFromGeometry(Geometry *g, char want3d)
        // Construct LWPOINT
        line = lwline_construct(pa->ndims, -1, pa);
 
-       // Serialize LWPOINT
-       srl = lwline_serialize(line);
-
-       return srl;
+       return line;
 }
 
-// Return a serialized polygon from a GEOS geometry (no SRID no BBOX)
-char *PolyFromGeometry(Geometry *g, char want3d)
+// Return a LWPOLY from a GEOS polygon
+LWPOLY *
+lwpoly_from_geometry(Geometry *g, char want3d)
 {
        POINTARRAY **rings, *pa;
        LWPOLY *poly;
@@ -1947,10 +1955,13 @@ char *PolyFromGeometry(Geometry *g, char want3d)
        int nrings;
        int npoints;
        int i, j;
-       char *srl;
        POINT3D *pts, *ip, *op;
        int ptoff=0; // point offset inside POINT3D *
-       int ptsize = 8*ndims;
+       int ptsize = sizeof(double)*ndims;
+
+#ifdef DEBUG_GEOS2POSTGIS
+       elog(NOTICE, "lwpoly_from_geometry: point size %d", ptsize);
+#endif
 
        // Get number of rings, and pointlist
        pts = GEOSGetCoordinates(g);
@@ -1997,32 +2008,58 @@ char *PolyFromGeometry(Geometry *g, char want3d)
        // Construct LWPOLY
        poly = lwpoly_construct(pa->ndims, -1, nrings+1, rings);
 
-       // Serialize LWPOLY
-       srl = lwpoly_serialize(poly);
+       return poly;
+}
 
-       // Get rid of GEOS points...
-       GEOSdeleteChar( (char*) pts);
+// Return a lwcollection from a GEOS multi*
+LWCOLLECTION *
+lwcollection_from_geometry(Geometry *geom, char want3d)
+{
+       uint32 ngeoms;
+       LWGEOM **geoms;
+       LWCOLLECTION *ret;
+       int ndims = want3d ? 3 : 2;
+       int type = GEOSGeometryTypeId(geom) ;
+       int SRID = GEOSGetSRID(geom);
+       char wantbbox = 0;
+       int i;
 
-       return srl;
-}
+       ngeoms = GEOSGetNumGeometries(geom);
 
-//-----=GEOS2POSTGIS=
+#ifdef DEBUG_GEOS2POSTGIS
+       lwnotice("lwcollection_from_geometry: type: %s, geoms %d",
+               lwgeom_typename(type), ngeoms);
+#endif
 
+       geoms = lwalloc(sizeof(LWGEOM *)*ngeoms);
 
-/*
- * Recursively add a Geometry to the LWGEOM_EXPLODED structure
- * The exploded struct contains note about the number of dimensions
- * requested.
- */
-void
-addToExploded_recursive(Geometry *geom, LWGEOM_EXPLODED *exp)
+       for (i=0; i<ngeoms; i++)
+       {
+               Geometry *g = GEOSGetGeometryN(geom, i);
+#ifdef DEBUG_GEOS2POSTGIS
+               lwnotice("lwcollection_from_geometry: geom %d is a %s", i, lwgeom_typename(GEOSGeometryTypeId(g)));
+#endif
+               geoms[i] = lwgeom_from_geometry(g, want3d);
+#ifdef DEBUG_GEOS2POSTGIS
+               lwnotice("lwcollection_from_geometry: geoms[%d] is a %s", i, lwgeom_typename(geoms[i]->type));
+#endif
+       }
+
+       ret = lwcollection_construct(type, ndims, SRID,
+               wantbbox, ngeoms, geoms);
+       return ret;
+}
+
+
+// Return an LWGEOM from a Geometry
+LWGEOM *
+lwgeom_from_geometry(Geometry *geom, char want3d)
 {
-       char *srl;
        int type = GEOSGeometryTypeId(geom) ;
-       char want3d = exp->ndims > 2 ? 1 : 0;
-       int ngeoms;
-       int t;
 
+#ifdef DEBUG_GEOS2POSTGIS
+       lwnotice("lwgeom_from_geometry: it's a %s", lwgeom_typename(type));
+#endif
 
        switch (type)
        {
@@ -2032,68 +2069,20 @@ addToExploded_recursive(Geometry *geom, LWGEOM_EXPLODED *exp)
                case MULTIPOLYGONTYPE:
                case MULTILINETYPE:
                case MULTIPOINTTYPE:
-
-                       //this is more difficult because GEOS allows GCs of GCs
-                       ngeoms = GEOSGetNumGeometries(geom);
-#ifdef DEBUG_GEOS2POSTGIS
-       elog(NOTICE, "GEOS2POSTGIS: It's a MULTI (of %d elems)", ngeoms);
-#endif
-                       if (ngeoms == 0)
-                       {
-                               return; // skip EMPTY geoms
-                       }
-                       if (ngeoms == 1) {
-                               Geometry *g = GEOSGetGeometryN(geom, 0);
-                               // short cut!
-                               return addToExploded_recursive(g, exp);
-                       }
-                       for (t=0; t<ngeoms; t++) {
-                               Geometry *g = GEOSGetGeometryN(geom, t);
-                               addToExploded_recursive(g, exp);
-                       }
-                       return;
+                       return (LWGEOM *)lwcollection_from_geometry(geom, want3d);
 
                case POLYGONTYPE:
-#ifdef DEBUG_GEOS2POSTGIS
-                       elog(NOTICE, "GEOS2POSTGIS: It's a POLYGON");
-#endif
-                       srl = PolyFromGeometry(geom, want3d);
-                       if (srl == NULL) return;
-                       exp->npolys++;
-                       exp->polys = repalloc(exp->polys,
-                               sizeof(char *)*exp->npolys);
-                       exp->polys[exp->npolys-1] = srl;
-                       return;
+                       return (LWGEOM *)lwpoly_from_geometry(geom, want3d);
 
                case LINETYPE:
-#ifdef DEBUG_GEOS2POSTGIS
-                       elog(NOTICE, "GEOS2POSTGIS: It's a LINE");
-#endif
-                       srl = LineFromGeometry(geom, want3d);
-                       if (srl == NULL) return;
-                       exp->nlines++;
-                       exp->lines = repalloc(exp->lines,
-                               sizeof(char *)*exp->nlines);
-                       exp->lines[exp->nlines-1] = srl;
-                       return;
+                       return (LWGEOM *)lwline_from_geometry(geom, want3d);
 
                case POINTTYPE: 
-#ifdef DEBUG_GEOS2POSTGIS
-                       elog(NOTICE, "GEOS2POSTGIS: It's a POINT");
-#endif
-                       srl = PointFromGeometry(geom, want3d);
-                       if (srl == NULL) return;
-                       exp->npoints++;
-                       exp->points = repalloc(exp->points,
-                               sizeof(char *)*exp->npoints);
-                       exp->points[exp->npoints-1] = srl;
-                       return;
+                       return (LWGEOM *)lwpoint_from_geometry(geom, want3d);
 
                default:
-#ifdef DEBUG_GEOS2POSTGIS
-                       elog(NOTICE, "GEOS2POSTGIS: It's UNKNOWN!");
-#endif
-                       return;
+                       lwerror("lwgeom_from_geometry: unknown geometry type: %d", type);
+                       return NULL;
 
        }
 
@@ -2102,32 +2091,41 @@ addToExploded_recursive(Geometry *geom, LWGEOM_EXPLODED *exp)
 PG_LWGEOM *
 GEOS2POSTGIS(Geometry *geom, char want3d)
 {
+       LWGEOM *lwgeom;
+       size_t size, retsize;
        PG_LWGEOM *result;
-       LWGEOM_EXPLODED *oexp;
-       int SRID;
-       int wantbbox = 0; // might as well be 1 ...
-       int size;
-
-       SRID = GEOSGetSRID(geom);
-
-       // Initialize exploded lwgeom
-       oexp = (LWGEOM_EXPLODED *)palloc(sizeof(LWGEOM_EXPLODED));
-       oexp->SRID = SRID;
-       oexp->ndims = want3d ? 3 : 2;
-       oexp->npoints = 0;
-       oexp->points = palloc(sizeof(char *));
-       oexp->nlines = 0;
-       oexp->lines = palloc(sizeof(char *));
-       oexp->npolys = 0;
-       oexp->polys = palloc(sizeof(char *));
-
-       addToExploded_recursive(geom, oexp);
-
-       size = lwexploded_findlength(oexp, wantbbox);
+
+       lwgeom = lwgeom_from_geometry(geom, want3d);
+       if ( ! lwgeom )
+       {
+               lwerror("GEOS2POSTGIS: lwgeom_from_geometry returned NULL");
+               return NULL;
+       }
+
+#ifdef DEBUG_GEOS2POSTGIS
+       lwnotice("GEOS2POSTGIS: lwgeom_from_geometry returned a %s", lwgeom_summary(lwgeom, 0)); //lwgeom_typename(lwgeom->type));
+#endif
+
+       size = lwgeom_serialize_size(lwgeom);
+
+#ifdef DEBUG_GEOS2POSTGIS
+       lwnotice("GEOS2POSTGIS: lwgeom_serialize_size returned %d", size);
+#endif
+
        size += 4; // postgresql size header
        result = palloc(size);
        result->size = size;
-       lwexploded_serialize_buf(oexp, wantbbox, SERIALIZED_FORM(result), NULL);
+
+#ifdef DEBUG_GEOS2POSTGIS
+       lwnotice("GEOS2POSTGIS: about to serialize %s", lwgeom_typename(lwgeom->type));
+#endif
+
+       lwgeom_serialize_buf(lwgeom, SERIALIZED_FORM(result), &retsize);
+
+       if ( retsize != size-4 )
+       {
+               lwerror("GEOS2POSTGIS: lwgeom_serialize_buf returned %d, lwgeom_serialize_size returned %d", retsize, size);
+       }
 
        return result;
 }
@@ -2145,22 +2143,27 @@ LWGEOM2GEOS(LWGEOM *lwgeom)
        if ( ! lwgeom ) return NULL;
 
 #ifdef DEBUG_POSTGIS2GEOS
-       elog(NOTICE, "LWGEOM2GEOS: got lwgeom[%p]", lwgeom);
+       lwnotice("LWGEOM2GEOS: got lwgeom[%p]", lwgeom);
 #endif
 
        switch (lwgeom->type)
        {
-               LWPOINT *p;
-
                case POINTTYPE:
-                       p = (LWPOINT *)lwgeom;
-                       elog(NOTICE, "LWGEOM2GEOS: lwpoint[%p]", p);
-                       return PostGIS2GEOS_point(p);
+#ifdef DEBUG_POSTGIS2GEOS
+                       lwnotice("LWGEOM2GEOS: point[%p]", lwgeom);
+#endif
+                       return PostGIS2GEOS_point((LWPOINT *)lwgeom);
 
                case LINETYPE:
+#ifdef DEBUG_POSTGIS2GEOS
+                       lwnotice("LWGEOM2GEOS: line[%p]", lwgeom);
+#endif
                        return PostGIS2GEOS_linestring((LWLINE *)lwgeom);
 
                case POLYGONTYPE:
+#ifdef DEBUG_POSTGIS2GEOS
+                       lwnotice("LWGEOM2GEOS: poly[%p]", lwgeom);
+#endif
                        return PostGIS2GEOS_polygon((LWPOLY *)lwgeom);
 
                case MULTIPOINTTYPE:
@@ -2168,13 +2171,17 @@ LWGEOM2GEOS(LWGEOM *lwgeom)
                case MULTIPOLYGONTYPE:
                case COLLECTIONTYPE:
                        col = (LWCOLLECTION *)lwgeom;
+#ifdef DEBUG_POSTGIS2GEOS
+                       lwnotice("LWGEOM2GEOS: %s with %d subgeoms", lwgeom_typename(col->type), col->ngeoms);
+#endif
                        collected = (Geometry **)lwalloc(sizeof(Geometry *)*col->ngeoms);
                        for (i=0; i<col->ngeoms; i++)
                        {
                                collected[i] = LWGEOM2GEOS(col->geoms[i]);
                        }
-                       return PostGIS2GEOS_collection(collected, col->ngeoms,
-                               col->SRID, col->ndims > 2);
+                       return PostGIS2GEOS_collection(col->type,
+                               collected, col->ngeoms, col->SRID,
+                               col->ndims>2);
 
                default:
                        lwerror("Unknown geometry type: %d", lwgeom->type);
@@ -2193,99 +2200,6 @@ POSTGIS2GEOS(PG_LWGEOM *geom)
        return ret;
 }
 
-Geometry *
-_POSTGIS2GEOS(PG_LWGEOM *geom)
-{
-       LWPOINT *point;
-       LWLINE *line;
-       LWPOLY *poly;
-       LWGEOM_EXPLODED *exploded;
-       int type;
-       int i, j;
-       Geometry **collected;
-       int ncollected;
-       Geometry *ret=NULL;
-
-       type = lwgeom_getType(geom->type);
-
-       switch (type)
-       {
-               case POINTTYPE:
-#ifdef DEBUG_POSTGIS2GEOS
-                       elog(NOTICE, "POSTGIS2GEOS: it's a point");
-#endif
-                       point = lwpoint_deserialize(SERIALIZED_FORM(geom));
-                       ret = PostGIS2GEOS_point(point);
-                       break;
-
-               case LINETYPE:
-#ifdef DEBUG_POSTGIS2GEOS
-                       elog(NOTICE, "POSTGIS2GEOS: it's a line");
-#endif
-                       line = lwline_deserialize(SERIALIZED_FORM(geom));
-                       ret = PostGIS2GEOS_linestring(line);
-                       break;
-
-               case POLYGONTYPE:
-#ifdef DEBUG_POSTGIS2GEOS
-                       elog(NOTICE, "POSTGIS2GEOS: it's a polygon");
-#endif
-                       poly = lwpoly_deserialize(SERIALIZED_FORM(geom));
-                       ret = PostGIS2GEOS_polygon(poly);
-                       break;
-
-               default:
-                       break;
-       }
-
-       if ( ret )
-       {
-               return ret;
-       }
-
-#ifdef DEBUG_POSTGIS2GEOS
-       elog(NOTICE, "POSTGIS2GEOS: out of switch");
-#endif
-
-       // Since it is not a base type, let's explode...
-       exploded = lwgeom_explode(SERIALIZED_FORM(geom));
-
-#ifdef DEBUG_POSTGIS2GEOS
-       elog(NOTICE, "POSTGIS2GEOS: exploded produced");
-#endif
-
-       ncollected = exploded->npoints + exploded->nlines + exploded->npolys;
-
-#ifdef DEBUG_POSTGIS2GEOS
-       elog(NOTICE, "POSTGIS2GEOS: it's a collection of %d elems", ncollected);
-#endif
-
-       collected = (Geometry **)palloc(sizeof(Geometry *)*ncollected);
-
-       j=0;
-       for (i=0; i<exploded->npoints; i++)
-       {
-               point = lwpoint_deserialize(exploded->points[i]);
-               collected[j++] = PostGIS2GEOS_point(point);
-       }
-       for (i=0; i<exploded->nlines; i++)
-       {
-               line = lwline_deserialize(exploded->lines[j]);
-               collected[j++] = PostGIS2GEOS_linestring(line);
-       }
-       for (i=0; i<exploded->npolys; i++)
-       {
-               poly = lwpoly_deserialize(exploded->polys[i]);
-               collected[j++] = PostGIS2GEOS_polygon(poly);
-       }
-
-       ret = PostGIS2GEOS_collection(collected, ncollected,
-               exploded->SRID, exploded->ndims > 2);
-
-       return ret;
-
-}
-
 PG_FUNCTION_INFO_V1(GEOSnoop);
 Datum GEOSnoop(PG_FUNCTION_ARGS)
 {
index 5709c159128f7cf8dd0416e6c0f429c5075bce55..c8826a9deae973938960b126e0f4f31d32627dcf 100644 (file)
@@ -10,7 +10,7 @@
 #include "geos/geom.h"
 #include "geos/util.h"
 
-#define DEBUG_POSTGIS2GEOS 1
+//#define DEBUG_POSTGIS2GEOS 1
 
 using namespace geos;
 
@@ -109,10 +109,7 @@ extern "C" char *GEOSjtsport();
 extern "C" Geometry *PostGIS2GEOS_point(const LWPOINT *point);
 extern "C" Geometry *PostGIS2GEOS_linestring(const LWLINE *line);
 extern "C" Geometry *PostGIS2GEOS_polygon(const LWPOLY *polygon);
-extern "C" Geometry *PostGIS2GEOS_multipolygon(LWPOLY *const *const geoms, uint32 ngeoms, int SRID, int is3d);
-extern "C" Geometry *PostGIS2GEOS_multilinestring(LWLINE *const *const geoms, uint32 ngeoms, int SRID, int is3d);
-extern "C" Geometry *PostGIS2GEOS_multipoint(LWPOINT *const *const geoms, uint32 ngeoms, int SRID, int is3d);
-extern "C" Geometry *PostGIS2GEOS_collection(Geometry **geoms, int ngeoms, int SRID, bool is3d);
+extern "C" Geometry *PostGIS2GEOS_collection(int type, Geometry **geoms, int ngeoms, int SRID, bool is3d);
 extern "C" Geometry *PostGIS2GEOS_box3d(BOX3D *box, int SRID);
 
 extern "C" char GEOSisvalid(Geometry *g1);
@@ -281,6 +278,12 @@ PostGIS2GEOS_linestring(const LWLINE *lwline)
        bool is3d = pa->ndims > 2 ? 1 : 0;
        int SRID = lwline->SRID;
 
+#ifdef DEBUG_POSTGIS2GEOS
+       char buf[256];
+       sprintf(buf, "PostGIS2GEOS_line got lwline[%p]", lwline);
+       NOTICE_MESSAGE(buf);
+#endif
+
        try{
                uint32 t;
                Coordinate c;
@@ -356,6 +359,12 @@ Geometry *PostGIS2GEOS_polygon(const LWPOLY *lwpoly)
        int SRID = lwpoly->SRID;
        bool is3d = lwpoly->ndims > 2 ? 1 : 0;
 
+#ifdef DEBUG_POSTGIS2GEOS
+       char buf[256];
+       sprintf(buf, "PostGIS2GEOS_poly got lwpoly[%p]", lwpoly);
+       NOTICE_MESSAGE(buf);
+#endif
+
        try
        {
                Coordinate c;
@@ -497,7 +506,7 @@ Geometry *PostGIS2GEOS_polygon(const LWPOLY *lwpoly)
        }
 }
 
-Geometry *PostGIS2GEOS_multipoint(LWPOINT *const *const geoms, uint32 ngeoms, int SRID, bool is3d)
+Geometry *PostGIS2GEOS_multipoint(LWPOINT **geoms, uint32 ngeoms, int SRID, bool is3d)
 {
        try
        {
@@ -534,7 +543,7 @@ Geometry *PostGIS2GEOS_multipoint(LWPOINT *const *const geoms, uint32 ngeoms, in
        }
 }
 
-Geometry *PostGIS2GEOS_multilinestring(LWLINE *const *const geoms, uint32 ngeoms, int SRID, bool is3d)
+Geometry *PostGIS2GEOS_multilinestring(LWLINE **geoms, uint32 ngeoms, int SRID, bool is3d)
 {
        try
        {
@@ -571,7 +580,7 @@ Geometry *PostGIS2GEOS_multilinestring(LWLINE *const *const geoms, uint32 ngeoms
        }
 }
 
-Geometry *PostGIS2GEOS_multipolygon(LWPOLY *const *const polygons, uint32 npolys, int SRID, bool is3d)
+Geometry *PostGIS2GEOS_multipolygon(LWPOLY **polygons, uint32 npolys, int SRID, bool is3d)
 {
        try
        {
@@ -608,8 +617,15 @@ Geometry *PostGIS2GEOS_multipolygon(LWPOLY *const *const polygons, uint32 npolys
        }
 }
 
-Geometry *PostGIS2GEOS_collection(Geometry **geoms, int ngeoms, int SRID, bool is3d)
+Geometry *PostGIS2GEOS_collection(int type, Geometry **geoms, int ngeoms, int SRID, bool is3d)
 {
+#ifdef DEBUG_POSTGIS2GEOS
+       char buf[256];
+       sprintf(buf, "PostGIS2GEOS_collection: requested type %d, ngeoms: %d",
+                       type, ngeoms);
+       NOTICE_MESSAGE(buf);
+#endif
+
        try
        {
                Geometry *g;
@@ -620,7 +636,26 @@ Geometry *PostGIS2GEOS_collection(Geometry **geoms, int ngeoms, int SRID, bool i
                {
                        (*subGeos)[t] = geoms[t];
                }
-               g = geomFactory->buildGeometry(subGeos);
+               //g = geomFactory->buildGeometry(subGeos);
+               switch (type)
+               {
+                       case COLLECTIONTYPE:
+                               g = geomFactory->createGeometryCollection(subGeos);
+                               break;
+                       case MULTIPOINTTYPE:
+                               g = geomFactory->createMultiPoint(subGeos);
+                               break;
+                       case MULTILINETYPE:
+                               g = geomFactory->createMultiLineString(subGeos);
+                               break;
+                       case MULTIPOLYGONTYPE:
+                               g = geomFactory->createMultiPolygon(subGeos);
+                               break;
+                       default:
+                               NOTICE_MESSAGE("Unsupported type request for PostGIS2GEOS_collection");
+                               g = NULL;
+                               
+               }
 #if GEOS_LAST_INTERFACE < 2
                delete subGeos;
 #endif
index ab99a7a2d833b0ffe2f4b70a37c10c0090de2660..6262ca0aab63081c6c3ad1bc0287f33425b9f672 100644 (file)
@@ -5,6 +5,9 @@
 #include <string.h>
 #include "liblwgeom.h"
 
+//#define DEBUG_CALLS 1
+
+
 // construct a new LWLINE.  points will *NOT* be copied
 // use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
 LWLINE *lwline_construct(int ndims, int SRID,  POINTARRAY *points)
@@ -107,7 +110,7 @@ char  *lwline_serialize(LWLINE *line)
 // the given buffer, and returning number of bytes written into
 // the given int pointer.
 // result's first char will be the 8bit type.  See serialized form doc
-void lwline_serialize_buf(LWLINE *line, char *buf, int *retsize)
+void lwline_serialize_buf(LWLINE *line, char *buf, size_t *retsize)
 {
        int size=1;  // type byte
        char hasSRID;
@@ -195,12 +198,20 @@ lwline_serialize_size(LWLINE *line)
 {
        size_t size = 1;  //type
 
+#ifdef DEBUG_CALLS
+       lwnotice("lwline_serialize_size called");
+#endif
+
        if ( line->SRID != -1 ) size += 4; // SRID
        if ( line->hasbbox ) size += sizeof(BOX2DFLOAT4);
 
        size += sizeof(double)*line->ndims*line->points->npoints; // points
        size += 4; // npoints
 
+#ifdef DEBUG_CALLS
+       lwnotice("lwline_serialize_size returning %d", size);
+#endif
+
        return size;
 }
 
index 2e7c86d91c5710f5763b11b917d1c14f50969db3..deb2d388b9ee4779754022bd4974ac97300c872c 100644 (file)
@@ -3,6 +3,8 @@
 #include <string.h>
 #include "liblwgeom.h"
 
+//#define DEBUG_CALLS 1
+
 // convert this point into its serialize form
 // result's first char will be the 8bit type.  See serialized form doc
 char *
@@ -28,20 +30,22 @@ lwpoint_serialize(LWPOINT *point)
 // the given int pointer.
 // result's first char will be the 8bit type.  See serialized form doc
 void
-lwpoint_serialize_buf(LWPOINT *point, char *buf, int *retsize)
+lwpoint_serialize_buf(LWPOINT *point, char *buf, size_t *retsize)
 {
        int size=1;
        char hasSRID;
        char *loc;
 
+#ifdef DEBUG_CALLS
+       lwnotice("lwpoint_serialize_buf(%p, %p) called", point, buf);
+#endif
+
        hasSRID = (point->SRID != -1);
 
        if (hasSRID) size +=4;  //4 byte SRID
        if (point->hasbbox) size += sizeof(BOX2DFLOAT4); // bvol
 
-       if (point->ndims == 3) size += 24; //x,y,z
-       else if (point->ndims == 2) size += 16 ; //x,y,z
-       else if (point->ndims == 4) size += 32 ; //x,y,z,m
+       size += sizeof(double)*point->ndims;
 
        buf[0] = (unsigned char) lwgeom_makeType_full(point->ndims,
                hasSRID, POINTTYPE, point->hasbbox);
@@ -121,11 +125,19 @@ lwpoint_serialize_size(LWPOINT *point)
 {
        size_t size = 1; // type
 
+#ifdef DEBUG_CALLS
+       lwnotice("lwpoint_serialize_size called");
+#endif
+
        if ( point->SRID != -1 ) size += 4; // SRID
        if ( point->hasbbox ) size += sizeof(BOX2DFLOAT4);
 
        size += point->ndims * sizeof(double); // point
 
+#ifdef DEBUG_CALLS
+       lwnotice("lwpoint_serialize_size returning %d", size);
+#endif
+
        return size; 
 }
 
@@ -161,7 +173,7 @@ lwpoint_deserialize(char *serialized_form)
        char *loc = NULL;
        POINTARRAY *pa;
 
-#ifdef DEBUG
+#ifdef DEBUG_CALLS
        lwnotice("lwpoint_deserialize called");
 #endif
 
@@ -234,6 +246,9 @@ LWPOINT *
 lwpoint_clone(const LWPOINT *g)
 {
        LWPOINT *ret = lwalloc(sizeof(LWPOINT));
+#ifdef DEBUG_CALLS
+       lwnotice("lwpoint_clone called");
+#endif
        memcpy(ret, g, sizeof(LWPOINT));
        return ret;
 }
index 9dc6db2319f87f4a3f2d773929cd966aa2c09470..d0e34659aeae36a66139491b326482be9c7a9cde 100644 (file)
@@ -5,6 +5,8 @@
 #include <string.h>
 #include "liblwgeom.h"
 
+//#define DEBUG_CALLS 1
+
 // 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 *
@@ -134,7 +136,7 @@ lwpoly_serialize(LWPOLY *poly)
 // result's first char will be the 8bit type.  See serialized form doc
 // points copied
 void
-lwpoly_serialize_buf(LWPOLY *poly, char *buf, int *retsize)
+lwpoly_serialize_buf(LWPOLY *poly, char *buf, size_t *retsize)
 {
        int size=1;  // type byte
        char hasSRID;
@@ -143,6 +145,10 @@ lwpoly_serialize_buf(LWPOLY *poly, char *buf, int *retsize)
        int npoints;
        char *loc;
 
+#ifdef DEBUG_CALLS
+       lwnotice("lwpoly_serialize_buf called");
+#endif
+
        hasSRID = (poly->SRID != -1);
 
        size += 4; // nrings
@@ -321,6 +327,11 @@ lwpoly_serialize_size(LWPOLY *poly)
        if ( poly->SRID != -1 ) size += 4; // SRID
        if ( poly->hasbbox ) size += sizeof(BOX2DFLOAT4);
 
+#ifdef DEBUG_CALLS
+       lwnotice("lwpoly_serialize_size called with poly[%p] (%d rings)",
+                       poly, poly->nrings);
+#endif
+
        size += 4; // nrings
 
        for (i=0; i<poly->nrings; i++)
@@ -329,6 +340,10 @@ lwpoly_serialize_size(LWPOLY *poly)
                size += poly->rings[i]->npoints*poly->ndims*sizeof(double);
        }
 
+#ifdef DEBUG_CALLS
+       lwnotice("lwpoly_serialize_size returning %d", size);
+#endif
+
        return size;
 }
 
index 9057d5c1e546549b28c920a2dd738134cc7c779b..e4aeba9d147992ec19405e563fda7d9e76611778 100644 (file)
@@ -1617,6 +1617,11 @@ CREATEFUNCTION ForceRHR(geometry)
        AS '@MODULE_FILENAME@', 'LWGEOM_forceRHR_poly'
        LANGUAGE 'C' WITH (iscachable,isstrict);
 
+CREATEFUNCTION noop(geometry)
+       RETURNS geometry
+       AS '@MODULE_FILENAME@', 'LWGEOM_noop'
+       LANGUAGE 'C' WITH (iscachable,isstrict);
+
 ------------------------------------------------------------------------
 
 --