override CFLAGS += -DUSE_STATS
endif
-OBJS=lwgeom_pg.o liblwgeom.o lwgeom.o lwpoint.o lwline.o lwpoly.o lwmpoint.o lwmline.o lwmpoly.o lwcollection.o lwgeom_spheroid.o lwgeom_api.o lwgeom_ogc.o lwgeom_functions_analytic.o lwgeom_geos.o lwgeom_inout.o lwgeom_estimate.o lwgeom_functions_basic.o lwgeom_gist.o lwgeom_btree.o lwgeom_transform.o stringBuffer.o lwgeom_box.o lwgeom_box3d.o lwgeom_box2dfloat4.o lwgeom_chip.o lex.yy.o wktparse.tab.o lwgparse.o wktunparse.o lwgeom_svg.o lwgeom_gml.o $(GEOS_WRAPPER)
+OBJS=lwgeom_pg.o lwgeom_debug.o liblwgeom.o lwgeom.o lwpoint.o lwline.o lwpoly.o lwmpoint.o lwmline.o lwmpoly.o lwcollection.o lwgeom_spheroid.o lwgeom_api.o lwgeom_ogc.o lwgeom_functions_analytic.o lwgeom_geos.o lwgeom_inout.o lwgeom_estimate.o lwgeom_functions_basic.o lwgeom_gist.o lwgeom_btree.o lwgeom_transform.o stringBuffer.o lwgeom_box.o lwgeom_box3d.o lwgeom_box2dfloat4.o lwgeom_chip.o lex.yy.o wktparse.tab.o lwgparse.o wktunparse.o lwgeom_svg.o lwgeom_gml.o $(GEOS_WRAPPER)
OTHERS=y.output lex.yy.c wktparse.tab.c wktparse.tab.h lwpostgis.sql
lwreporter lwnotice = pg_notice;
#endif
+static char *lwgeomTypeName[] = {
+ "Unknown",
+ "Point",
+ "Line",
+ "Polygon",
+ "MultiPoint",
+ "MultiLine",
+ "MultiPolygon",
+ "GeometryCollection"
+};
void *
default_allocator(size_t size)
va_end (ap);
return;
}
- va_end(ap);
printf("%s", msg);
+ va_end(ap);
free(msg);
}
va_end (ap);
return;
}
- va_end(ap);
fprintf(stderr, "%s", msg);
+ va_end(ap);
free(msg);
}
+
+const char *
+lwgeom_typename(int type)
+{
+ return lwgeomTypeName[type];
+}
double m;
} POINT4D;
+//-----------------------------------------------------------
+
// Point array abstracts a lot of the complexity of points and point lists.
// It handles miss-alignment in the serialized form, 2d/3d translation
// (2d points converted to 3d will have z=0 or NaN)
uint32 npoints;
} POINTARRAY;
+//-----------------------------------------------------------
+
+// LWGEOM (any type)
+typedef struct
+{
+ int type; // POINT|LINE|POLY|MPOINT|MLINE|MPOLY|COLLECTION
+ char ndims; // 2=2d, 3=3d, 4=4d
+ uint32 SRID; // -1 == unneeded
+ char hasbbox;
+ void *data;
+} LWGEOM;
+
+// POINTYPE
+typedef struct
+{
+ int type; // POINTTYPE
+ char ndims;
+ uint32 SRID;
+ char hasbbox;
+ POINTARRAY *point; // hide 2d/3d (this will be an array of 1 point)
+} LWPOINT; // "light-weight point"
+
+// LINETYPE
+typedef struct
+{
+ int type; // LINETYPE
+ char ndims;
+ uint32 SRID;
+ char hasbbox;
+ POINTARRAY *points; // array of POINT3D
+} LWLINE; //"light-weight line"
+
+// POLYGONTYPE
+typedef struct
+{
+ int type; // POLYGONTYPE
+ char ndims;
+ uint32 SRID;
+ char hasbbox;
+ int nrings;
+ POINTARRAY **rings; // list of rings (list of points)
+} LWPOLY; // "light-weight polygon"
+
+// MULTIPOINTTYPE
+typedef struct
+{
+ int type; // MULTIPOINTTYPE
+ char ndims;
+ uint32 SRID;
+ char hasbbox;
+ int ngeoms;
+ LWPOINT **geoms;
+} LWMPOINT;
+
+// MULTILINETYPE
+typedef struct
+{
+ int type; // MULTILINETYPE
+ char ndims;
+ uint32 SRID;
+ char hasbbox;
+ int ngeoms;
+ LWLINE **geoms;
+} LWMLINE;
+
+// MULTIPOLYGONTYPE
+typedef struct
+{
+ int type; // MULTIPOLYGONTYPE
+ char ndims;
+ uint32 SRID;
+ char hasbbox;
+ int ngeoms;
+ LWPOLY **geoms;
+} LWMPOLY;
+
+// COLLECTIONTYPE
+typedef struct
+{
+ int type; // COLLECTIONTYPE
+ char ndims;
+ uint32 SRID;
+ char hasbbox;
+ int ngeoms;
+ LWGEOM **geoms;
+} LWCOLLECTION;
+
+//-------------------------------------------------------------
+
// copies a point from the point array into the parameter point
// will set point's z=0 (or NaN) if pa is 2d
// will set point's m=0 (or NaN( if pa is 3d or 2d
// bounding box finder and (TODO) serialized form size finder.
//--------------------------------------------------------
-typedef struct
-{
- int type;
- char ndims; // 2=2d, 3=3d, 4=4d, 5=undef
- int SRID; // spatial ref sys
- POINTARRAY *point; // hide 2d/3d (this will be an array of 1 point)
-} LWPOINT; // "light-weight point"
-
// 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 ndims, int SRID, POINTARRAY *point);
//--------------------------------------------------------
-typedef struct
-{
- int type;
- char ndims; // 2=2d, 3=3d, 4=4d, 5=undef
- int SRID; // spatial ref sys -1=none
- POINTARRAY *points; // array of POINT3D
-} LWLINE; //"light-weight line"
-
// 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 ndims, int SRID, POINTARRAY *points);
//--------------------------------------------------------
-typedef struct
-{
- int type;
- int32 SRID;
- char ndims;
- int nrings;
- POINTARRAY **rings; // list of rings (list of points)
-} LWPOLY; // "light-weight polygon"
-
// 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 ndims, int SRID, int nrings,POINTARRAY **points);
//--------------------------------------------------------
-// MULTIPOINTTYPE
-typedef struct
-{
- int type;
- int32 SRID;
- char ndims;
- int ngeoms;
- LWPOINT **geoms;
-} LWMPOINT;
extern size_t lwmpoint_serialize_size(LWMPOINT *mpoint);
extern void lwmpoint_serialize_buf(LWMPOINT *mpoint, char *buf, int *size);
-// MULTILINETYPE
-typedef struct
-{
- int type;
- int32 SRID;
- char ndims;
- int ngeoms;
- LWLINE **geoms;
-} LWMLINE;
-
extern size_t lwmline_serialize_size(LWMLINE *mline);
extern void lwmline_serialize_buf(LWMLINE *mline, char *buf, int *size);
-// MULTIPOLYGONTYPE
-typedef struct
-{
- int type;
- int32 SRID;
- char ndims;
- int ngeoms;
- LWPOLY **geoms;
-} LWMPOLY;
-
extern size_t lwmpoly_serialize_size(LWMPOLY *mpoly);
extern void lwmpoly_serialize_buf(LWMPOLY *mpoly, char *buf, int *size);
-// LWGEOM (any type)
-typedef struct
-{
- int type;
- void *data;
-} LWGEOM;
extern size_t lwgeom_serialize_size(LWGEOM *geom);
extern void lwgeom_serialize_buf(LWGEOM *geom, char *buf, int *size);
extern char *lwgeom_serialize(LWGEOM *geom, char wantbbox);
-// COLLECTIONTYPE
-typedef struct
-{
- int type;
- int32 SRID;
- char ndims;
- int ngeoms;
- LWGEOM **geoms;
-} LWCOLLECTION;
-
extern size_t lwcollection_serialize_size(LWCOLLECTION *coll);
extern void lwcollection_serialize_buf(LWCOLLECTION *mcoll, char *buf, int *size);
extern void lwpoly_reverse(LWPOLY *poly);
extern void lwpoly_forceRHR(LWPOLY *poly);
extern void lwgeom_forceRHR(LWGEOM *lwgeom);
+extern char *lwgeom_summary(LWGEOM *lwgeom, int offset);
+extern const char *lwgeom_typename(int type);
#endif // !defined _LIBLWGEOM_H
{
LWCOLLECTION *result;
LWGEOM_INSPECTED *insp;
- int type = lwgeom_getType(srl[0]);
+ char typefl = srl[0];
+ int type = lwgeom_getType(typefl);
int i;
if ( type != COLLECTIONTYPE )
result = lwalloc(sizeof(LWCOLLECTION));
result->type = COLLECTIONTYPE;
+ result->hasbbox = lwgeom_hasBBOX(typefl);
+ result->ndims = lwgeom_ndims(typefl);
result->SRID = insp->SRID;
- result->ndims = lwgeom_ndims(insp->type);
result->ngeoms = insp->ngeometries;
result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries);
Datum LWGEOM_forceRHR_poly(PG_FUNCTION_ARGS);
// internal
-char * lwgeom_summary_recursive(char *serialized, int offset);
-char * lwgeom_summary(LWGEOM *serialized, int offset);
int32 lwgeom_nrings_recursive(char *serialized);
void dump_lwexploded(LWGEOM_EXPLODED *exploded);
void ptarray_reverse(POINTARRAY *pa);
PG_RETURN_INT32(size);
}
-char *lwcollection_summary(LWCOLLECTION *collection, int offset);
-char *lwmpoly_summary(LWMPOLY *mpoly, int offset);
-char *lwmline_summary(LWMLINE *mline, int offset);
-char *lwmpoint_summary(LWMPOINT *mpoint, int offset);
-char *lwpoly_summary(LWPOLY *poly, int offset);
-char *lwline_summary(LWLINE *line, int offset);
-char *lwpoint_summary(LWPOINT *point, int offset);
-
-/*
- * Returns an alloced string containing summary for the LWGEOM object
- */
-char *
-lwpoint_summary(LWPOINT *point, int offset)
-{
- char *result;
- result = lwalloc(256);
- sprintf(result, "Object %d is a POINT()\n", offset);
- return result;
-}
-
-char *
-lwline_summary(LWLINE *line, int offset)
-{
- char *result;
- result = lwalloc(32);
- sprintf(result, "Object %d is a LINE()\n", offset);
- return result;
-}
-
-char *
-lwpoly_summary(LWPOLY *poly, int offset)
-{
- char tmp[256];
- char *result = lwalloc(64*(poly->nrings+1));
- int i;
-
- result[0] = '\0';
- sprintf(tmp, "Object %d is a POLYGON() with %i rings\n",
- offset, poly->nrings);
- strcat(result, tmp);
- for (i=0; i<poly->nrings;i++)
- {
- sprintf(tmp," + ring %i has %i points\n",
- i, poly->rings[i]->npoints);
- strcat(result,tmp);
- }
- return result;
-}
-
-char *
-lwmpoint_summary(LWMPOINT *mpoint, int offset)
-{
- char *result = lwalloc(60);
- sprintf(result, "Object %d is a MULTIPOINT() with %d points\n",
- offset, mpoint->ngeoms);
- return result;
-}
-
-char *
-lwmline_summary(LWMLINE *mline, int offset)
-{
- char *result = lwalloc(60*(mline->ngeoms+1));
- sprintf(result, "Object %d is a MULTILINE() with %d lines\n",
- offset, mline->ngeoms);
- return result;
-}
-
-char *
-lwmpoly_summary(LWMPOLY *mpoly, int offset)
-{
- size_t size = 128;
- char *result = lwalloc(size);
- char *tmp;
- int i;
-
- sprintf(result, "Object %d is a MULTIPOLYGON() with %d polys\n",
- offset, mpoly->ngeoms);
-
- for (i=0; i<mpoly->ngeoms; i++)
- {
- tmp = lwpoly_summary(mpoly->geoms[i], i);
- size += strlen(tmp)+1;
- result = lwrealloc(result, size);
- strcat(result, tmp);
- //lwfree(tmp);
- }
-
- return result;
-}
-
-
-char *
-lwcollection_summary(LWCOLLECTION *collection, int offset)
-{
- char *result = lwalloc(60*(collection->ngeoms+1));
- char *tmp;
- int i;
-
- sprintf(result, "Object %d is a COLLECTION() with %d subgeoms\n",
- offset, collection->ngeoms);
-
- for (i=0; i<collection->ngeoms; i++)
- {
- tmp = lwgeom_summary(lwcollection_getsubgeom(collection, i), i);
- strcat(result, tmp);
- lwfree(tmp);
- }
-
- return result;
-}
-
-char *
-lwgeom_summary(LWGEOM *lwgeom, int offset)
-{
- char *result;
-
- switch (lwgeom->type)
- {
- case POINTTYPE:
- return lwpoint_summary((LWPOINT *)lwgeom, offset);
-
- case LINETYPE:
- return lwline_summary((LWLINE *)lwgeom, offset);
-
- case POLYGONTYPE:
- return lwpoly_summary((LWPOLY *)lwgeom, offset);
-
- case MULTIPOINTTYPE:
- return lwmpoint_summary((LWMPOINT *)lwgeom, offset);
-
- case MULTILINETYPE:
- return lwmline_summary((LWMLINE *)lwgeom, offset);
-
- case MULTIPOLYGONTYPE:
- return lwmpoly_summary((LWMPOLY *)lwgeom, offset);
-
- case COLLECTIONTYPE:
- return lwcollection_summary((LWCOLLECTION *)lwgeom, offset);
- default:
- result = palloc(256);
- sprintf(result, "Object is of unknown type: %d",
- lwgeom->type);
- return result;
- }
-
- return NULL;
-}
-
-/*
- * Returns a lwalloced string containing summary for the serialized
- * LWGEOM object
- */
-char *
-lwgeom_summary_recursive(char *serialized, int offset)
-{
- static int idx = 0;
- LWGEOM_INSPECTED *inspected;
- char *result;
- char *ptr;
- char tmp[100];
- int size;
- int32 j,i;
-
- size = 1;
- result = lwalloc(1);
- result[0] = '\0';
-
- if ( offset == 0 ) idx = 0;
-
- inspected = lwgeom_inspect(serialized);
-
- //now have to do a scan of each object
- for (j=0; j<inspected->ngeometries; j++)
- {
- LWLINE *line=NULL;
- LWPOINT *point=NULL;
- LWPOLY *poly=NULL;
- char *subgeom=lwgeom_getsubgeometry_inspected(inspected, j);
-
- if ( lwgeom_getType(subgeom[0]) == 0 )
- {
- size += 32;
- result = lwrealloc(result,size);
- sprintf(tmp,"Object %i is EMPTY()\n", idx++);
- strcat(result,tmp);
- continue;
- }
-
-
- point = lwgeom_getpoint_inspected(inspected,j);
- if (point !=NULL)
- {
- size += 32;
- result = lwrealloc(result,size);
- sprintf(tmp,"Object %i is a POINT()\n", idx++);
- strcat(result,tmp);
- continue;
- }
-
- poly = lwgeom_getpoly_inspected(inspected, j);
- if (poly !=NULL)
- {
- size += 60*(poly->nrings+1);
- result = lwrealloc(result,size);
- sprintf(tmp,"Object %i is a POLYGON() with %i rings\n",
- idx++, poly->nrings);
- strcat(result,tmp);
- for (i=0; i<poly->nrings;i++)
- {
- sprintf(tmp," + ring %i has %i points\n",
- i, poly->rings[i]->npoints);
- strcat(result,tmp);
- }
- continue;
- }
-
- line = lwgeom_getline_inspected(inspected, j);
- if (line != NULL)
- {
- size += 57;
- result = lwrealloc(result,size);
- sprintf(tmp, "Object %i is a LINESTRING() with %i points\n", idx++, line->points->npoints);
- strcat(result,tmp);
- continue;
- }
-
- ptr = lwgeom_summary_recursive(subgeom, j);
- size += strlen(ptr);
- result = lwrealloc(result,size);
- strcat(result, ptr);
- lwfree(ptr);
- }
-
- pfree_inspected(inspected);
- return result;
-}
-
/*
* Translate a pointarray.
*/
lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom));
- //result = lwgeom_summary_recursive(SERIALIZED_FORM(geom), 0);
result = lwgeom_summary(lwgeom, 0);
// create a text obj to return
- mytext = (text *) lwalloc(VARHDRSZ + strlen(result) );
- VARATT_SIZEP(mytext) = VARHDRSZ + strlen(result) ;
- memcpy(VARDATA(mytext) , result, strlen(result) );
+ mytext = (text *) lwalloc(VARHDRSZ + strlen(result) + 1);
+ VARATT_SIZEP(mytext) = VARHDRSZ + strlen(result) + 1;
+ VARDATA(mytext)[0] = '\n';
+ memcpy(VARDATA(mytext)+1, result, strlen(result) );
lwfree(result);
PG_RETURN_POINTER(mytext);
}
#include "liblwgeom.h"
#include "lwgeom_pg.h"
+#undef DEBUG
+
void *
pg_alloc(size_t size)
{
void * result;
+#ifdef DEBUG
+ lwnotice(" pg_alloc(%d) called", size);
+#endif
result = palloc(size);
- //elog(NOTICE," palloc(%d) = %p", size, result);
+#ifdef DEBUG
+ lwnotice(" pg_alloc(%d) returning %p", size, result);
+#endif
return result;
}
pg_realloc(void *mem, size_t size)
{
void * result;
+#ifdef DEBUG
+ lwnotice(" pg_realloc(%p, %d) called", mem, size);
+#endif
result = repalloc(mem, size);
+#ifdef DEBUG
+ lwnotice(" pg_realloc(%p, %d) returning %p", mem, size, result);
+#endif
return result;
}
va_end (ap);
return;
}
- va_end(ap);
elog(ERROR, "%s", msg);
+ va_end(ap);
free(msg);
}
va_end (ap);
return;
}
- va_end(ap);
elog(NOTICE, "%s", msg);
+ va_end(ap);
free(msg);
}
{
//lwnotice("line has bbox");
loc += sizeof(BOX2DFLOAT4);
+ result->hasbbox = 1;
}
else
{
+ result->hasbbox = 0;
//lwnotice("line has NO bbox");
}
}
else if (line->ndims == 4)
{
- size += 32 * line->points->npoints; //x,y
+ size += 32 * line->points->npoints; //x,y
}
result->type = MULTILINETYPE;
result->SRID = insp->SRID;
result->ndims = lwgeom_ndims(insp->type);
+ result->hasbbox = lwgeom_hasBBOX(insp->type);
result->ngeoms = insp->ngeometries;
result->geoms = lwalloc(sizeof(LWLINE *)*insp->ngeometries);
result = lwalloc(sizeof(LWMPOINT));
result->type = MULTIPOINTTYPE;
result->SRID = insp->SRID;
+ result->hasbbox = lwgeom_hasBBOX(insp->type);
result->ndims = lwgeom_ndims(insp->type);
result->ngeoms = insp->ngeometries;
result->geoms = lwalloc(sizeof(LWPOINT *)*result->ngeoms);
result = lwalloc(sizeof(LWMPOLY));
result->type = MULTIPOLYGONTYPE;
result->SRID = insp->SRID;
+ result->hasbbox = lwgeom_hasBBOX(insp->type);
result->ndims = lwgeom_ndims(insp->type);
result->ngeoms = insp->ngeometries;
result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries);
#ifdef DEBUG
lwnotice("lwpoint_deserialize: input has bbox");
#endif
+ result->hasbbox = 1;
loc += sizeof(BOX2DFLOAT4);
}
+ else result->hasbbox = 0;
if ( lwgeom_hasSRID(type))
{
{
lwnotice("LWPOINT {");
lwnotice(" ndims = %i", (int)point->ndims);
+ lwnotice(" BBOX = %i", point->hasbbox ? 1 : 0 );
lwnotice(" SRID = %i", (int)point->SRID);
printPA(point->point);
lwnotice("}");
if (lwgeom_hasBBOX(type))
{
loc += sizeof(BOX2DFLOAT4);
+ result->hasbbox = 1;
+ }
+ else
+ {
+ result->hasbbox = 0;
}
if ( lwgeom_hasSRID(type))