From: Sandro Santilli Date: Thu, 30 Sep 2004 08:18:06 +0000 (+0000) Subject: Added missing liblwgeom.c file. X-Git-Tag: pgis_1_0_0RC1~360 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=406c2623b7edb0d2d6ce02708c618fe99d034388;p=postgis Added missing liblwgeom.c file. Made LWMPOINT, LWMLINE, LWMPOLY compatible with LWCOLLECTION. Fixed reverse() and forcerhr() to maintain geometry structure. git-svn-id: http://svn.osgeo.org/postgis/trunk@912 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/lwgeom/liblwgeom.c b/lwgeom/liblwgeom.c new file mode 100644 index 000000000..a3b688333 --- /dev/null +++ b/lwgeom/liblwgeom.c @@ -0,0 +1,91 @@ +#include +#include +#include + +#include "lwgeom_pg.h" +#include "liblwgeom.h" + +#define CONTEXT_PG 0 +#define CONTEXT_SA 1 + +#define DEFAULT_CONTEXT CONTEXT_PG + +/* Global variables */ +#if DEFAULT_CONTEXT == SA +lwallocator lwalloc = default_allocator; +lwreallocator lwrealloc = default_reallocator; +lwfreeor lwfree = default_freeor; +lwreporter lwerror = default_errorreporter; +lwreporter lwnotice = default_noticereporter; +#else +lwallocator lwalloc = pg_alloc; +lwreallocator lwrealloc = pg_realloc; +lwfreeor lwfree = pg_free; +lwreporter lwerror = pg_error; +lwreporter lwnotice = pg_notice; +#endif + + +void * +default_allocator(size_t size) +{ + void *mem = malloc(size); + return mem; +} + +void +default_freeor(void *mem) +{ + free(mem); +} + +void * +default_reallocator(void *mem, size_t size) +{ + void *ret = realloc(mem, size); + return ret; +} + +void +default_noticereporter(const char *fmt, ...) +{ + char *msg; + va_list ap; + + va_start (ap, fmt); + + /* + * This is a GNU extension. + * Dunno how to handle errors here. + */ + if (!vasprintf (&msg, fmt, ap)) + { + va_end (ap); + return; + } + va_end(ap); + printf("%s", msg); + free(msg); +} + +void +default_errorreporter(const char *fmt, ...) +{ + char *msg; + va_list ap; + + va_start (ap, fmt); + + /* + * This is a GNU extension. + * Dunno how to handle errors here. + */ + if (!vasprintf (&msg, fmt, ap)) + { + va_end (ap); + return; + } + va_end(ap); + fprintf(stderr, "%s", msg); + free(msg); +} diff --git a/lwgeom/liblwgeom.h b/lwgeom/liblwgeom.h index 31a041c93..0ec1b1ea7 100644 --- a/lwgeom/liblwgeom.h +++ b/lwgeom/liblwgeom.h @@ -363,7 +363,7 @@ extern BOX3D *lwline_findbbox(LWLINE *line); typedef struct { - char type; + int type; int32 SRID; char ndims; int nrings; @@ -402,8 +402,8 @@ typedef struct int type; int32 SRID; char ndims; - int npoints; - LWPOINT **points; + int ngeoms; + LWPOINT **geoms; } LWMPOINT; extern size_t lwmpoint_serialize_size(LWMPOINT *mpoint); @@ -415,8 +415,8 @@ typedef struct int type; int32 SRID; char ndims; - int nlines; - LWLINE **lines; + int ngeoms; + LWLINE **geoms; } LWMLINE; extern size_t lwmline_serialize_size(LWMLINE *mline); @@ -428,8 +428,8 @@ typedef struct int type; int32 SRID; char ndims; - int npolys; - LWPOLY **polys; + int ngeoms; + LWPOLY **geoms; } LWMPOLY; extern size_t lwmpoly_serialize_size(LWMPOLY *mpoly); @@ -494,7 +494,7 @@ typedef struct const char *serialized_form; // orginal structure unsigned char type; // 8-bit type for the LWGEOM int ngeometries; // number of sub-geometries - char * * const sub_geoms; // list of pointers (into serialized_form) of the sub-geoms + char **sub_geoms; // list of pointers (into serialized_form) of the sub-geoms } LWGEOM_INSPECTED; extern int lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected, int geom_number); @@ -861,5 +861,10 @@ extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad) extern POINTARRAY *segmentize2d_ptarray(POINTARRAY *ipa, double dist); extern int32 lwgeom_npoints(char *serialized); extern char ptarray_isccw(const POINTARRAY *pa); +extern void lwgeom_reverse(LWGEOM *lwgeom); +extern void lwline_reverse(LWLINE *line); +extern void lwpoly_reverse(LWPOLY *poly); +extern void lwpoly_forceRHR(LWPOLY *poly); +extern void lwgeom_forceRHR(LWGEOM *lwgeom); #endif // !defined _LIBLWGEOM_H diff --git a/lwgeom/lwgeom.c b/lwgeom/lwgeom.c index 2f163b8fc..67e599785 100644 --- a/lwgeom/lwgeom.c +++ b/lwgeom/lwgeom.c @@ -128,3 +128,50 @@ lwgeom_serialize(LWGEOM *lwgeom, char wantbbox) return serialized; } +// Force Right-hand-rule on LWGEOM polygons +void +lwgeom_forceRHR(LWGEOM *lwgeom) +{ + LWCOLLECTION *coll; + int i; + + switch (lwgeom->type) + { + case POLYGONTYPE: + lwpoly_reverse((LWPOLY *)lwgeom); + return; + + case MULTIPOLYGONTYPE: + case COLLECTIONTYPE: + coll = (LWCOLLECTION *)lwgeom; + for (i=0; ingeoms; i++) + lwgeom_forceRHR(coll->geoms[i]); + return; + } +} + +// Reverse vertex order of LWGEOM +void +lwgeom_reverse(LWGEOM *lwgeom) +{ + int i; + LWCOLLECTION *col; + + switch (lwgeom->type) + { + case LINETYPE: + lwline_reverse((LWLINE *)lwgeom); + return; + case POLYGONTYPE: + lwpoly_reverse((LWPOLY *)lwgeom); + return; + case MULTILINETYPE: + case MULTIPOLYGONTYPE: + case COLLECTIONTYPE: + col = (LWCOLLECTION *)lwgeom; + for (i=0; ingeoms; i++) + lwgeom_reverse(col->geoms[i]); + return; + } +} + diff --git a/lwgeom/lwgeom.h b/lwgeom/lwgeom.h index 2cb8d0d2a..70f5ca78d 100644 --- a/lwgeom/lwgeom.h +++ b/lwgeom/lwgeom.h @@ -1,826 +1,4 @@ -//lwgeom.h +typedef struct LWGEOM_T LWGEOM; -// basic API for handling the LWGEOM, BOX2DFLOAT4, LWPOINT, LWLINE, and LWPOLY. -// See below for other support types like POINTARRAY and LWGEOM_INSPECTED - -#include -#include "utils/geo_decls.h" - - -typedef struct -{ - float xmin; - float ymin; - float xmax; - float ymax; -} BOX2DFLOAT4; - -typedef struct -{ - double xmin, ymin, zmin; - double xmax, ymax, zmax; -} BOX3D; - - -typedef struct chiptag -{ - int size; //unused (for use by postgresql) - - int endian_hint; // the number 1 in the endian of this datastruct - - BOX3D bvol; - int SRID; - char future[4]; - float factor; // Usually 1.0. - // Integer values are multiplied by this number - // to get the actual height value - // (for sub-meter accuracy height data). - - int datatype; // 1 = float32, - // 5 = 24bit integer, - // 6 = 16bit integer (short) - // 101 = float32 (NDR), - // 105 = 24bit integer (NDR), - // 106=16bit int (NDR) - - int height; - int width; - int compression; // 0 = no compression, 1 = differencer - // 0x80 = new value - // 0x7F = nodata - - // this is provided for convenience, it should be set to - // sizeof(chip) bytes into the struct because the serialized form is: - //
- // NULL when serialized - void *data; // data[0] = bottm left, - // data[width] = 1st pixel, 2nd row (uncompressed) - -} CHIP; - -/* - * standard definition of an ellipsoid (what wkt calls a spheroid) - * f = (a-b)/a - * e_sq = (a*a - b*b)/(a*a) - * b = a - fa - */ -typedef struct -{ - double a; //semimajor axis - double b; //semiminor axis - double f; //flattening - double e; //eccentricity (first) - double e_sq; //eccentricity (first), squared - char name[20]; //name of ellipse -} SPHEROID; - - -// POINT3D already defined in postgis.h -// ALL LWGEOM structures will use POINT3D as an abstract point. -// This means a 2d geometry will be stored as (x,y) in its serialized -// form, but all functions will work on (x,y,0). This keeps all the -// analysis functions simple. -// NOTE: for GEOS integration, we'll probably set z=NaN -// so look out - z might be NaN for 2d geometries! -typedef struct { double x,y,z; } POINT3D; - - -// type for 2d points. When you convert this to 3d, the -// z component will be either 0 or NaN. -typedef struct -{ - double x; - double y; -} POINT2D; - -typedef struct -{ - double x; - double y; - double z; - 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) -// DONT MIX 2D and 3D POINTS! *EVERYTHING* is either one or the other -typedef struct -{ - char *serialized_pointlist; // array of POINT 2D, 3D or 4D. - // probably missaligned. - // points to a double - char ndims; // 2=2d, 3=3d, 4=4d - uint32 npoints; -} POINTARRAY; - -// 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 -// NOTE: point is a real POINT3D *not* a pointer -extern POINT4D getPoint4d(const POINTARRAY *pa, int n); - -// 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 -// NOTE: this will modify the point4d pointed to by 'point'. -extern void getPoint4d_p(const POINTARRAY *pa, int n, char *point); - -// copies a point from the point array into the parameter point -// will set point's z=0 (or NaN) if pa is 2d -// NOTE: point is a real POINT3D *not* a pointer -extern POINT3D getPoint3d(const POINTARRAY *pa, int n); - -// copies a point from the point array into the parameter point -// will set point's z=0 (or NaN) if pa is 2d -// NOTE: this will modify the point3d pointed to by 'point'. -extern void getPoint3d_p(const POINTARRAY *pa, int n, char *point); - - -// copies a point from the point array into the parameter point -// z value (if present is not returned) -// NOTE: point is a real POINT3D *not* a pointer -extern POINT2D getPoint2d(const POINTARRAY *pa, int n); - -// copies a point from the point array into the parameter point -// z value (if present is not returned) -// NOTE: this will modify the point2d pointed to by 'point'. -extern void getPoint2d_p(const POINTARRAY *pa, int n, char *point); - -// get a pointer to nth point of a POINTARRAY -// You'll need to cast it to appropriate dimensioned point. -// Note that if you cast to a higher dimensional point you'll -// possibly corrupt the POINTARRAY. -extern char *getPoint(const POINTARRAY *pa, int n); -//--- here is a macro equivalent, for speed... -//#define getPoint(x,n) &( (x)->serialized_pointlist[((x)->ndims*8)*(n)] ) - - -// constructs a POINTARRAY. -// NOTE: points is *not* copied, so be careful about modification (can be aligned/missaligned) -// NOTE: ndims is descriptive - it describes what type of data 'points' -// points to. No data conversion is done. -extern POINTARRAY *pointArray_construct(char *points, int ndims, uint32 npoints); - -//calculate the bounding box of a set of points -// returns a 3d box -// if pa is 2d, then box3d's zmin/zmax will be either 0 or NaN -// dont call on an empty pa -extern BOX3D *pointArray_bbox(const POINTARRAY *pa); - -//size of point represeneted in the POINTARRAY -// 16 for 2d, 24 for 3d, 32 for 4d -extern int pointArray_ptsize(const POINTARRAY *pa); - - -/* - * - * LWGEOM types are an 8-bit char in this format: - * - * BSDDtttt - * - * WHERE - * B = 16 byte BOX2DFLOAT4 follows (probably not aligned) [before SRID] - * S = 4 byte SRID attached (0= not attached (-1), 1= attached) - * DD = dimentionality (0=2d, 1=3d, 2= 4d) - * tttt = actual type (as per the WKB type): - * - * enum wkbGeometryType { - * wkbPoint = 1, - * wkbLineString = 2, - * wkbPolygon = 3, - * wkbMultiPoint = 4, - * wkbMultiLineString = 5, - * wkbMultiPolygon = 6, - * wkbGeometryCollection = 7 - * }; - * - */ -#define POINTTYPE 1 -#define LINETYPE 2 -#define POLYGONTYPE 3 -#define MULTIPOINTTYPE 4 -#define MULTILINETYPE 5 -#define MULTIPOLYGONTYPE 6 -#define COLLECTIONTYPE 7 - -#define TYPE_SETTYPE(c,t) (((c)&0xF0)|t) -#define TYPE_SETDIMS(c,d) (((c)&0xCF)|d) -#define TYPE_SETHASBBOX(c,b) (((c)&0x7F)|b) -#define TYPE_SETHASSRID(c,s) (((c)&0xBF)|s) - -extern bool lwgeom_hasSRID(unsigned char type); // true iff S bit is set -extern bool lwgeom_hasBBOX(unsigned char type); // true iff B bit set -extern int lwgeom_ndims(unsigned char type); // returns the DD value -extern int lwgeom_getType(unsigned char type); // returns the tttt value - -extern unsigned char lwgeom_makeType(int ndims, char hasSRID, int type); -extern unsigned char lwgeom_makeType_full(int ndims, char hasSRID, int type, bool hasBBOX); - - - -/* - * This is the binary representation of lwgeom compatible - * with postgresql varlena struct - */ -typedef struct { - int32 size; - unsigned char type; // encodes ndims, type, bbox presence, - // srid presence - char data[1]; -} PG_LWGEOM; - -/* - * Construct a full LWGEOM type (including size header) - * from a serialized form. - * The constructed LWGEOM object will be allocated using palloc - * and the serialized form will be copied. - * If you specify a SRID other then -1 it will be set. - * If you request bbox (wantbbox=1) it will be extracted or computed - * from the serialized form. - */ -extern PG_LWGEOM *PG_LWGEOM_construct(char *serialized, int SRID, int wantbbox); - -/* - * Use this macro to extract the char * required - * by most functions from an PG_LWGEOM struct. - * (which is an PG_LWGEOM w/out int32 size casted to char *) - */ -#define SERIALIZED_FORM(x) ((char *)(x))+4 - - -/* - * This function computes the size in bytes - * of the serialized geometries. - */ -extern int lwgeom_size(const char *serialized_form); -extern int lwgeom_size_subgeom(const char *serialized_form, int geom_number); - - -//-------------------------------------------------------- -// all the base types (point/line/polygon) will have a -// basic constructor, basic de-serializer, basic serializer, -// bounding box finder and (TODO) serialized form size finder. -//-------------------------------------------------------- - -typedef struct -{ - 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); - -// 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) -// Returns NULL if serialized form is not a point. -// See serialized form doc -extern LWPOINT *lwpoint_deserialize(char *serialized_form); - -// Find size this point would get when serialized (no BBOX) -extern uint32 lwpoint_size(LWPOINT *point); - -// convert this point into its serialize form -// result's first char will be the 8bit type. See serialized form doc -extern char *lwpoint_serialize(LWPOINT *point); - -// same as above, writes to buf -extern void lwpoint_serialize_buf(LWPOINT *point, char *buf, int *size); - -// find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN) -extern BOX3D *lwpoint_findbbox(LWPOINT *point); - -// convenience functions to hide the POINTARRAY -extern POINT2D lwpoint_getPoint2d(const LWPOINT *point); -extern POINT3D lwpoint_getPoint3d(const LWPOINT *point); - -//-------------------------------------------------------- - -typedef struct -{ - 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); - -// given the LWGEOM serialized form (or a pointer into a muli* one) -// construct a proper LWLINE. -// serialized_form should point to the 8bit type format (with type = 2) -// See serialized form doc -extern LWLINE *lwline_deserialize(char *serialized_form); - -// find the size this line would get when serialized (no BBOX) -extern uint32 lwline_size(LWLINE *line); - -// convert this line into its serialize form -// result's first char will be the 8bit type. See serialized form doc -// copies data. -extern char *lwline_serialize(LWLINE *line); - -// same as above, writes to buf -extern void lwline_serialize_buf(LWLINE *line, char *buf, int *size); - -// find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN) -extern BOX3D *lwline_findbbox(LWLINE *line); - -//-------------------------------------------------------- - -typedef struct -{ - 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); - -// given the LWPOLY serialized form (or a pointer into a muli* one) -// construct a proper LWPOLY. -// serialized_form should point to the 8bit type format (with type = 3) -// See serialized form doc -extern LWPOLY *lwpoly_deserialize(char *serialized_form); - -// find the size this polygon would get when serialized (no bbox!) -extern uint32 lwpoly_size(LWPOLY *poly); - -// create the serialized form of the polygon -// result's first char will be the 8bit type. See serialized form doc -// points copied -extern char *lwpoly_serialize(LWPOLY *poly); - -// same as above, writes to buf -extern void lwpoly_serialize_buf(LWPOLY *poly, char *buf, int *size); - -// find bounding box (standard one) zmin=zmax=0 if 2d (might change to NaN) -extern BOX3D *lwpoly_findbbox(LWPOLY *poly); - -//-------------------------------------------------------- - -// MULTIPOINTTYPE -typedef struct -{ - int32 SRID; - char ndims; - int npoints; - LWPOINT **points; -} LWMPOINT; - -// MULTILINETYPE -typedef struct -{ - int32 SRID; - char ndims; - int nlines; - LWLINE **lines; -} LWMLINE; - -// MULTIPOLYGONTYPE -typedef struct -{ - int32 SRID; - char ndims; - int npolys; - LWPOLY **polys; -} LWMPOLY; - -// COLLECTIONTYPE -typedef struct -{ - int32 SRID; - char ndims; - int ngeoms; - struct LWGEOM **geoms; -} LWCOLLECTION; - -// LWGEOM (any type) -typedef struct -{ - char type; - union { - LWPOINT *point; - LWMPOINT *mpoint; - LWLINE *line; - LWMLINE *mline; - LWPOLY *poly; - LWMPOLY *mpoly; - LWCOLLECTION *collection; - }; -} LWGEOM; - -LWGEOM *lwgeom_deserialize(char *serializedform); -LWMPOINT *lwmpoint_deserialize(char *serializedform); - -//------------------------------------------------------ - -//------------------------------------------------------ -// Multi-geometries -// -// These are all handled equivelently so its easy to write iterator code. -// NOTE NOTE: you can hand in a non-multigeometry to most of these functions -// and get usual behavior (ie. get geometry 0 on a POINT -// will return the point). -// This makes coding even easier since you dont have to necessarily -// differenciate between the multi* and non-multi geometries. -// -// NOTE: these usually work directly off the serialized form, so -// they're a little more difficult to handle (and slower) -// NOTE NOTE: the get functions maybe slow, so we may want to have an "analysed" -// lwgeom that would just have pointer to the start of each sub-geometry. -//------------------------------------------------------ - - - -// use this version for speed. READ-ONLY! -typedef struct -{ - int SRID; - const char *serialized_form; // orginal structure - unsigned char type; // 8-bit type for the LWGEOM - int ngeometries; // number of sub-geometries - char * * const sub_geoms; // list of pointers (into serialized_form) of the sub-geoms -} LWGEOM_INSPECTED; - -extern int lwgeom_size_inspected(const LWGEOM_INSPECTED *inspected, int geom_number); - -/* - * This structure is intended to be used for geometry collection construction. - * Does not allow specification of collection structure - * (serialization chooses the simpler form) - */ -typedef struct -{ - int SRID; - int ndims; - uint32 npoints; - char **points; - uint32 nlines; - char **lines; - uint32 npolys; - char **polys; -} LWGEOM_EXPLODED; - -void pfree_exploded(LWGEOM_EXPLODED *exploded); - -// Returns a 'palloced' union of the two input exploded geoms. -// Returns NULL if SRID or ndims do not match. -LWGEOM_EXPLODED * lwexploded_sum(LWGEOM_EXPLODED *exp1, LWGEOM_EXPLODED *exp2); - -/* - * This function recursively scan the given serialized geometry - * and returns a list of _all_ subgeoms in it (deep-first) - */ -extern LWGEOM_EXPLODED *lwgeom_explode(char *serialized); - -/* - * Return the length of the serialized form corresponding - * to this exploded structure. - */ -extern uint32 lwexploded_findlength(LWGEOM_EXPLODED *exp, int wantbbox); - -// Serialize an LWGEOM_EXPLODED object. -// SRID and ndims will be taken from exploded structure. -// wantbbox will determine result bbox. -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); - -// 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 -// This function just computes the length of each sub-object and pre-caches this info. -// For a geometry collection of multi* geometries, you can inspect the sub-components -// as well. -extern LWGEOM_INSPECTED *lwgeom_inspect(const char *serialized_form); - - -// 1st geometry has geom_number = 0 -// if the actual sub-geometry isnt a POINT, null is returned (see _gettype()). -// if there arent enough geometries, return null. -// this is fine to call on a point (with geom_num=0), multipoint or geometrycollection -extern LWPOINT *lwgeom_getpoint(char *serialized_form, int geom_number); -extern LWPOINT *lwgeom_getpoint_inspected(LWGEOM_INSPECTED *inspected, int geom_number); - -// 1st geometry has geom_number = 0 -// if the actual geometry isnt a LINE, null is returned (see _gettype()). -// if there arent enough geometries, return null. -// this is fine to call on a line, multiline or geometrycollection -extern LWLINE *lwgeom_getline(char *serialized_form, int geom_number); -extern LWLINE *lwgeom_getline_inspected(LWGEOM_INSPECTED *inspected, int geom_number); - -// 1st geometry has geom_number = 0 -// if the actual geometry isnt a POLYGON, null is returned (see _gettype()). -// if there arent enough geometries, return null. -// this is fine to call on a polygon, multipolygon or geometrycollection -extern LWPOLY *lwgeom_getpoly(char *serialized_form, int geom_number); -extern LWPOLY *lwgeom_getpoly_inspected(LWGEOM_INSPECTED *inspected, int geom_number); - -// this gets the serialized form of a sub-geometry -// 1st geometry has geom_number = 0 -// if this isnt a multi* geometry, and geom_number ==0 then it returns -// itself -// returns null on problems. -// in the future this is how you would access a muli* portion of a -// geometry collection. -// GEOMETRYCOLLECTION(MULTIPOINT(0 0, 1 1), LINESTRING(0 0, 1 1)) -// ie. lwgeom_getpoint( lwgeom_getsubgeometry( serialized, 0), 1) -// --> POINT(1 1) -// you can inspect the sub-geometry as well if you wish. -extern char *lwgeom_getsubgeometry(const char *serialized_form, int geom_number); -extern char *lwgeom_getsubgeometry_inspected(LWGEOM_INSPECTED *inspected, int geom_number); - - -// 1st geometry has geom_number = 0 -// use geom_number = -1 to find the actual type of the serialized form. -// ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, -1) -// --> multipoint -// ie lwgeom_gettype( <'MULTIPOINT(0 0, 1 1)'>, 0) -// --> point -// gets the 8bit type of the geometry at location geom_number -extern char lwgeom_getsubtype(char *serialized_form, int geom_number); -extern char lwgeom_getsubtype_inspected(LWGEOM_INSPECTED *inspected, int geom_number); - - -// how many sub-geometries are there? -// for point,line,polygon will return 1. -extern int lwgeom_getnumgeometries(char *serialized_form); -extern int lwgeom_getnumgeometries_inspected(LWGEOM_INSPECTED *inspected); - - - -// set finalType to COLLECTIONTYPE or 0 (0 means choose a best type) -// (ie. give it 2 points and ask it to be a multipoint) -// use SRID=-1 for unknown SRID (will have 8bit type's S = 0) -// all subgeometries must have the same SRID -// if you want to construct an inspected, call this then inspect the result... -extern char *lwgeom_construct(int SRID,int finalType,int ndims, int nsubgeometries, char **serialized_subs); - - -// construct the empty geometry (GEOMETRYCOLLECTION(EMPTY)) -extern char *lwgeom_constructempty(int SRID,int ndims); -extern void lwgeom_constructempty_buf(int SRID, int ndims, char *buf, int *size); -int lwgeom_empty_length(int SRID); - -// get the SRID from the LWGEOM -// none present => -1 -extern int lwgeom_getSRID(PG_LWGEOM *lwgeom); -extern int lwgeom_getsrid(char *serialized); -extern PG_LWGEOM *lwgeom_setSRID(PG_LWGEOM *lwgeom, int32 newSRID); - -//get bounding box of LWGEOM (automatically calls the sub-geometries bbox generators) -extern BOX3D *lw_geom_getBB(char *serialized_form); -extern BOX3D *lw_geom_getBB_inspected(LWGEOM_INSPECTED *inspected); - - -//------------------------------------------------------ -// other stuff - -// handle the double-to-float conversion. The results of this -// will usually be a slightly bigger box because of the difference -// between float8 and float4 representations. - -extern BOX2DFLOAT4 *box3d_to_box2df(BOX3D *box); -extern int box3d_to_box2df_p(BOX3D *box, BOX2DFLOAT4 *res); -extern BOX3D box2df_to_box3d(BOX2DFLOAT4 *box); -extern void box2df_to_box3d_p(BOX2DFLOAT4 *box, BOX3D *box3d); - -extern BOX2DFLOAT4 *box_to_box2df(BOX *box); // postgresql standard type -extern BOX box2df_to_box(BOX2DFLOAT4 *box); // postgresql standard type -extern void box2df_to_box_p(BOX2DFLOAT4 *box, BOX *out); // postgresql standard type - -extern 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. -// WARNING! the EMPTY geom will result in a random BOX2D returned -extern BOX2DFLOAT4 getbox2d(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); - -//**************************************************************** -// memory management -- these only delete the memory associated -// directly with the structure - NOT the stuff pointing into -// the original de-serialized info - -extern void pfree_inspected(LWGEOM_INSPECTED *inspected); -extern void pfree_point (LWPOINT *pt); -extern void pfree_line (LWLINE *line); -extern void pfree_polygon (LWPOLY *poly); -extern void pfree_POINTARRAY(POINTARRAY *pa); - - -//*********************************************************** -// utility - -extern uint32 get_uint32(const char *loc); -extern int32 get_int32(const char *loc); -extern void printPA(POINTARRAY *pa); -extern void printLWPOINT(LWPOINT *point); -extern void printLWLINE(LWLINE *line); -extern void printLWPOLY(LWPOLY *poly); -extern void printBYTES(unsigned char *a, int n); -extern void printMULTI(char *serialized); -extern void deparse_hex(unsigned char str, unsigned char *result); -extern void printType(unsigned char str); - - -//------------------------------------------------------------ -//------------------------------------------------------------ -// On serialized form (see top for the 8bit type implementation) - -// NOTE: contrary to the original proposal, bounding boxes are *never* -// included in the geometry. You must either refer to the index -// or compute it on demand. - - -// The serialized form is always a stream of bytes. The first four are always -// the memory size of the LWGEOM (including the 4 byte memory size). - -// The easiest way to describe the serialed form is with examples: -// (more examples are available in the postgis mailing list) - -//3D point w/o bounding box:: -// size = 29 bytes -// type: S=0,D=1, tttt= 1 -// X -// Y -// Z - -//2D line String -// size = ... -// type: S=0,D=0, tttt= 2 -// npoints -// X0 -// Y0 -// X1 -// Y1 -// X2 -// Y2 -//... - -//3D polygon w/o bounding box -// size = ... -// type: S=0,D=0, tttt= 3 -// nrings -// npoints in ring0 -// X0 -// Y0 -// X1 -// Y1 -// X2 -// Y2 -//... -// npoints in ring1 -// X0 -// Y0 -// X1 -// Y1 -// X2 -// Y2 -//... -//... - - -// the multi* representations are very simple - -// size = ... -// type: ... with tttt= -// ngeometries -// -// -// -// ... - - - -// see implementation for more exact details. - - -//---------------------------------------------------------------- -// example function (computes total length of the lines in a LWGEOM). -// This works for a LINESTRING, MULTILINESTRING, OR GEOMETRYCOLLECTION - - - -// char *serialized_form = (char *) [[get from database]] -// -// double total_length_so_far = 0; -// for (int t=0;t< lwgeom_getnumgeometries(serialized_form) ; t++) -// { -// LWLINE *line = lwgeom_getline(serialized_form, t); -// if (line != NULL) -// { -// double length = findlength( POINT_ARRAY(line->points) ); //2d/3d aware -// total_length_so_far + = length; -// } -// } -// return total_length_so_far; - - -// using the LWGEOM_INSPECTED way: - - -// char *serialized_form = (char *) [[get from datbase]] -// LWGEOM_INSPECTED inspected_geom = lwgeom_inspect(serialized_form); -// -// double total_length_so_far = 0; -// for (int t=0;t< lwgeom_getnumgeometries(inspected_geom) ; t++) -// { -// LWLINE *line = lwgeom_getline(inspected_geom, t); -// if (line != NULL) -// { -// double length = findlength( POINT_ARRAY(line->points) ); //2d/3d aware -// total_length_so_far + = length; -// } -// } -// return total_length_so_far; - - -// the findlength() function could be written like based on functions like: -// -// POINT3D getPoint3d(POINTARRAY pa, int n); (for a 2d/3d point and 3d length) -// POINT2D getPoint2d(POINTARRAY pa, int n); (for a 2d/3d point and 2d length) -// NOTE: make sure your findlength() function knows what to do with z=NaN. - - - - -// other forwards (for indirect function calls) - -extern float LWGEOM_Minf(float a, float b); -extern float LWGEOM_Maxf(float a, float b); -extern double LWGEOM_Mind(double a, double b); -extern double LWGEOM_Maxd(double a, double b); - - - -extern BOX3D *lw_geom_getBB_simple(char *serialized_form); - -extern float nextDown_f(double d); -extern float nextUp_f(double d); -extern double nextDown_d(float d); -extern double nextUp_d(float d); - - - -#if ! defined(__MINGW32__) -#define max(a,b) ((a) > (b) ? (a) : (b)) -#define min(a,b) ((a) <= (b) ? (a) : (b)) -#endif -#define abs(a) ((a) < (0) ? (-a) : (a)) - - -// general utilities -extern double lwgeom_polygon_area(LWPOLY *poly); -extern double lwgeom_polygon_perimeter(LWPOLY *poly); -extern double lwgeom_polygon_perimeter2d(LWPOLY *poly); -extern double lwgeom_pointarray_length2d(POINTARRAY *pts); -extern double lwgeom_pointarray_length(POINTARRAY *pts); -extern void lwgeom_force2d_recursive(char *serialized, char *optr, int *retsize); -extern void lwgeom_force3d_recursive(char *serialized, char *optr, int *retsize); -extern void lwgeom_force4d_recursive(char *serialized, char *optr, int *retsize); -extern double distance2d_pt_pt(POINT2D *p1, POINT2D *p2); -extern double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B); -extern double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D); -extern double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa); -extern double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2); -extern int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring); -extern int pt_in_poly_2d(POINT2D *p, LWPOLY *poly); -extern double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly); -extern double distance2d_point_point(LWPOINT *point1, LWPOINT *point2); -extern double distance2d_point_line(LWPOINT *point, LWLINE *line); -extern double distance2d_line_line(LWLINE *line1, LWLINE *line2); -extern double distance2d_point_poly(LWPOINT *point, LWPOLY *poly); -extern double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2); -extern double distance2d_line_poly(LWLINE *line, LWPOLY *poly); -extern double lwgeom_mindistance2d_recursive(char *lw1, char *lw2); -extern void lwgeom_translate_recursive(char *serialized, double xoff, double yoff, double zoff); -extern void lwgeom_translate_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff); -extern int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad); -extern POINTARRAY *segmentize2d_ptarray(POINTARRAY *ipa, double dist); -extern int32 lwgeom_npoints(char *serialized); -extern bool ptarray_isccw(const POINTARRAY *pa); +extern void lwgeom_reverse(LWGEOM *lwgeom); +extern void lwgeom_forceRHR(LWGEOM *lwgeom); diff --git a/lwgeom/lwgeom_api.c b/lwgeom/lwgeom_api.c index 887d42e42..fa159481e 100644 --- a/lwgeom/lwgeom_api.c +++ b/lwgeom/lwgeom_api.c @@ -939,8 +939,8 @@ lwgeom_inspect(const char *serialized_form) //simple geometry (point/line/polygon)-- not multi! result->ngeometries = 1; sub_geoms = (char**) lwalloc(sizeof(char*)); - sub_geoms[0] = serialized_form; - result->sub_geoms = sub_geoms; + sub_geoms[0] = (char *)serialized_form; + result->sub_geoms = (char **)sub_geoms; return result; } @@ -963,7 +963,7 @@ lwgeom_inspect(const char *serialized_form) sub_geoms = (char**) lwalloc(sizeof(char*) * result->ngeometries ); result->sub_geoms = sub_geoms; - sub_geoms[0] = loc; + sub_geoms[0] = (char *)loc; #ifdef DEBUG lwnotice("subgeom[0] @ %p", sub_geoms[0]); #endif diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index 6de34d956..a717b7eac 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -53,10 +53,8 @@ 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); -POINTARRAY *ptarray_reverse(const POINTARRAY *pa); -LWLINE *lwline_reverse(const LWLINE *line); -LWPOLY *lwpoly_reverse(const LWPOLY *poly); -LWPOLY *lwpoly_forceRHR(const LWPOLY *poly); +void ptarray_reverse(POINTARRAY *pa); + /*------------------------------------------------------------------*/ @@ -759,88 +757,59 @@ lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad) } -POINTARRAY * -ptarray_reverse(const POINTARRAY *ipa) +void +ptarray_reverse(POINTARRAY *pa) { - POINTARRAY *opa; - uint32 i, j; - int ptsize; - - opa = (POINTARRAY *)lwalloc(sizeof(POINTARRAY)); - opa->ndims = ipa->ndims; - opa->npoints = ipa->npoints; - ptsize = pointArray_ptsize(ipa); - opa->serialized_pointlist = lwalloc(ipa->npoints*ptsize); + POINT4D pbuf; + uint32 i; + int ptsize = pointArray_ptsize(pa); + int last = pa->npoints-1; + int mid = last/2; - for (i=0, j=ipa->npoints-1; inpoints; i++, j--) + for (i=0; i<=mid; i++) { - memcpy(getPoint(opa, j), getPoint(ipa, i), ptsize); + char *from, *to; + from = getPoint(pa, i); + to = getPoint(pa, (last-i)); + memcpy((char *)&pbuf, to, ptsize); + memcpy(to, from, ptsize); + memcpy(from, (char *)&pbuf, ptsize); } - return opa; } -LWLINE * -lwline_reverse(const LWLINE *iline) +void +lwline_reverse(LWLINE *line) { - LWLINE *oline; - POINTARRAY *rpa = ptarray_reverse(iline->points); - - oline = lwline_construct(iline->ndims, iline->SRID, rpa); - return oline; + ptarray_reverse(line->points); } -LWPOLY * -lwpoly_reverse(const LWPOLY *ipoly) +void +lwpoly_reverse(LWPOLY *poly) { - LWPOLY *opoly; - POINTARRAY **rpa; int i; - rpa = lwalloc(sizeof(POINTARRAY *)*ipoly->nrings); - - for (i=0; inrings; i++) - { - rpa[i] = ptarray_reverse(ipoly->rings[i]); - } - - opoly = lwpoly_construct(ipoly->ndims, ipoly->SRID, - ipoly->nrings, rpa); - - return opoly; + for (i=0; inrings; i++) + ptarray_reverse(poly->rings[i]); } -LWPOLY * -lwpoly_forceRHR(const LWPOLY *ipoly) +void +lwpoly_forceRHR(LWPOLY *poly) { - LWPOLY *opoly; - POINTARRAY **rpa; int i; - POINTARRAY *opa; - rpa = lwalloc(sizeof(POINTARRAY *)*ipoly->nrings); - - if ( ptarray_isccw(ipoly->rings[0]) ) + if ( ptarray_isccw(poly->rings[0]) ) { - opa = ipoly->rings[0]; - rpa[0] = ptarray_reverse(ipoly->rings[0]); + ptarray_reverse(poly->rings[0]); } - else rpa[0] = ipoly->rings[0]; - for (i=1; inrings; i++) + for (i=1; inrings; i++) { - if ( ! ptarray_isccw(ipoly->rings[i]) ) + if ( ! ptarray_isccw(poly->rings[i]) ) { - opa = ipoly->rings[i]; - rpa[i] = ptarray_reverse(ipoly->rings[i]); + ptarray_reverse(poly->rings[i]); } - else rpa[i] = ipoly->rings[i]; } - - opoly = lwpoly_construct(ipoly->ndims, ipoly->SRID, - ipoly->nrings, rpa); - - return opoly; } /*------------------------------------------------------------------*/ @@ -917,16 +886,16 @@ lwmpoint_summary(LWMPOINT *mpoint, int offset) { char *result = lwalloc(60); sprintf(result, "Object %d is a MULTIPOINT() with %d points\n", - offset, mpoint->npoints); + offset, mpoint->ngeoms); return result; } char * lwmline_summary(LWMLINE *mline, int offset) { - char *result = lwalloc(60*(mline->nlines+1)); + char *result = lwalloc(60*(mline->ngeoms+1)); sprintf(result, "Object %d is a MULTILINE() with %d lines\n", - offset, mline->nlines); + offset, mline->ngeoms); return result; } @@ -939,11 +908,11 @@ lwmpoly_summary(LWMPOLY *mpoly, int offset) int i; sprintf(result, "Object %d is a MULTIPOLYGON() with %d polys\n", - offset, mpoly->npolys); + offset, mpoly->ngeoms); - for (i=0; inpolys; i++) + for (i=0; ingeoms; i++) { - tmp = lwpoly_summary(mpoly->polys[i], i); + tmp = lwpoly_summary(mpoly->geoms[i], i); size += strlen(tmp)+1; result = lwrealloc(result, size); strcat(result, tmp); @@ -2977,51 +2946,14 @@ PG_FUNCTION_INFO_V1(LWGEOM_reverse); Datum LWGEOM_reverse(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; - PG_LWGEOM *result = NULL; - LWGEOM_EXPLODED *exp; - int size; - int wantbbox; - int i; - - geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - - if ( lwgeom_getType(geom->type) == COLLECTIONTYPE ) - { - elog(ERROR, "Collection reversing is not supported"); - PG_RETURN_NULL(); - } - - wantbbox = lwgeom_hasBBOX(geom->type); - exp = lwgeom_explode(SERIALIZED_FORM(geom)); - - for (i=0; inlines; i++) - { - LWLINE *line = lwline_deserialize(exp->lines[i]); - LWLINE *rline = lwline_reverse(line); - pfree_line(line); - exp->lines[i] = lwline_serialize(rline); - } + LWGEOM *lwgeom; - for (i=0; inpolys; i++) - { - LWPOLY *poly = lwpoly_deserialize(exp->polys[i]); - LWPOLY *rpoly = lwpoly_reverse(poly); - pfree_polygon(poly); - exp->polys[i] = lwpoly_serialize(rpoly); - } + geom = (PG_LWGEOM *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)); - size = lwexploded_findlength(exp, wantbbox); - result = lwalloc(size+4); - result->size = (size+4); - lwexploded_serialize_buf(exp, wantbbox, SERIALIZED_FORM(result), &size); - - if ( result->size != (size+4) ) - { - elog(ERROR, "lwexploded_serialize_buf wrote %d bytes, lwexploded_findlength returned %d", size, result->size-4); - PG_RETURN_NULL(); - } + lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom)); + lwgeom_reverse(lwgeom); - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(geom); } // Force polygons of the collection to obey Right-Hand-Rule @@ -3029,41 +2961,12 @@ PG_FUNCTION_INFO_V1(LWGEOM_forceRHR_poly); Datum LWGEOM_forceRHR_poly(PG_FUNCTION_ARGS) { PG_LWGEOM *geom; - PG_LWGEOM *result = NULL; - LWGEOM_EXPLODED *exp; - int size; - int wantbbox; - int i; - - geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - - if ( lwgeom_getType(geom->type) != POLYGONTYPE && - lwgeom_getType(geom->type) != MULTIPOLYGONTYPE ) - { - elog(ERROR, "Only polygon|multipolygon supported"); - PG_RETURN_NULL(); - } - - wantbbox = lwgeom_hasBBOX(geom->type); - exp = lwgeom_explode(SERIALIZED_FORM(geom)); + LWGEOM *lwgeom; - for (i=0; inpolys; i++) - { - LWPOLY *poly = lwpoly_deserialize(exp->polys[i]); - LWPOLY *rpoly = lwpoly_reverse(poly); - exp->polys[i] = lwpoly_serialize(rpoly); - } + geom = (PG_LWGEOM *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)); - size = lwexploded_findlength(exp, wantbbox); - result = lwalloc(size+4); - result->size = (size+4); - lwexploded_serialize_buf(exp, wantbbox, SERIALIZED_FORM(result), &size); - - if ( result->size != (size+4) ) - { - elog(ERROR, "lwexploded_serialize_buf wrote %d bytes, lwexploded_findlength returned %d", size, result->size-4); - PG_RETURN_NULL(); - } + lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom)); + lwgeom_forceRHR(lwgeom); - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(geom); } diff --git a/lwgeom/lwmline.c b/lwgeom/lwmline.c index 45641efbd..2b69faba2 100644 --- a/lwgeom/lwmline.c +++ b/lwgeom/lwmline.c @@ -24,16 +24,16 @@ lwmline_deserialize(char *srl) result->type = MULTILINETYPE; result->SRID = insp->SRID; result->ndims = lwgeom_ndims(insp->type); - result->nlines = insp->ngeometries; - result->lines = lwalloc(sizeof(LWLINE *)*insp->ngeometries); + result->ngeoms = insp->ngeometries; + result->geoms = lwalloc(sizeof(LWLINE *)*insp->ngeometries); for (i=0; ingeometries; i++) { - result->lines[i] = lwline_deserialize(insp->sub_geoms[i]); - if ( result->lines[i]->ndims != result->ndims ) + result->geoms[i] = lwline_deserialize(insp->sub_geoms[i]); + if ( result->geoms[i]->ndims != result->ndims ) { lwerror("Mixed dimensions (multiline:%d, line%d:%d)", - result->ndims, i, result->lines[i]->ndims); + result->ndims, i, result->geoms[i]->ndims); return NULL; } } @@ -50,8 +50,8 @@ lwmline_serialize_size(LWMLINE *mline) if ( mline->SRID != -1 ) size += 4; // SRID - for (i=0; inlines; i++) - size += lwline_serialize_size(mline->lines[i]); + for (i=0; ingeoms; i++) + size += lwline_serialize_size(mline->geoms[i]); return size; } @@ -83,14 +83,14 @@ lwmline_serialize_buf(LWMLINE *mline, char *buf, int *retsize) } // Write number of subgeoms - memcpy(loc, &mline->nlines, 4); + memcpy(loc, &mline->ngeoms, 4); size += 4; loc += 4; // Serialize subgeoms - for (i=0; inlines; i++) + for (i=0; ingeoms; i++) { - lwline_serialize_buf(mline->lines[i], loc, &subsize); + lwline_serialize_buf(mline->geoms[i], loc, &subsize); size += subsize; } diff --git a/lwgeom/lwmpoint.c b/lwgeom/lwmpoint.c index e02edd947..980546663 100644 --- a/lwgeom/lwmpoint.c +++ b/lwgeom/lwmpoint.c @@ -24,16 +24,16 @@ lwmpoint_deserialize(char *srl) result->type = MULTIPOINTTYPE; result->SRID = insp->SRID; result->ndims = lwgeom_ndims(insp->type); - result->npoints = insp->ngeometries; - result->points = lwalloc(sizeof(LWPOINT *)*result->npoints); + result->ngeoms = insp->ngeometries; + result->geoms = lwalloc(sizeof(LWPOINT *)*result->ngeoms); for (i=0; ingeometries; i++) { - result->points[i] = lwpoint_deserialize(insp->sub_geoms[i]); - if ( result->points[i]->ndims != result->ndims ) + result->geoms[i] = lwpoint_deserialize(insp->sub_geoms[i]); + if ( result->geoms[i]->ndims != result->ndims ) { lwerror("Mixed dimensions (multipoint:%d, point%d:%d)", - result->ndims, i, result->points[i]->ndims); + result->ndims, i, result->geoms[i]->ndims); return NULL; } } @@ -50,8 +50,8 @@ lwmpoint_serialize_size(LWMPOINT *mpoint) if ( mpoint->SRID != -1 ) size += 4; // SRID - for (i=0; inpoints; i++) - size += lwpoint_serialize_size(mpoint->points[i]); + for (i=0; ingeoms; i++) + size += lwpoint_serialize_size(mpoint->geoms[i]); return size; } @@ -83,14 +83,14 @@ lwmpoint_serialize_buf(LWMPOINT *mpoint, char *buf, int *retsize) } // Write number of subgeoms - memcpy(loc, &mpoint->npoints, 4); + memcpy(loc, &mpoint->ngeoms, 4); size += 4; loc += 4; // Serialize subgeoms - for (i=0; inpoints; i++) + for (i=0; ingeoms; i++) { - lwpoint_serialize_buf(mpoint->points[i], loc, &subsize); + lwpoint_serialize_buf(mpoint->geoms[i], loc, &subsize); size += subsize; } diff --git a/lwgeom/lwmpoly.c b/lwgeom/lwmpoly.c index 92b9fc46e..dba76d135 100644 --- a/lwgeom/lwmpoly.c +++ b/lwgeom/lwmpoly.c @@ -3,6 +3,8 @@ #include #include "liblwgeom.h" +//#define DEBUG_CALLS 1 + LWMPOLY * lwmpoly_deserialize(char *srl) { @@ -11,6 +13,10 @@ lwmpoly_deserialize(char *srl) int type = lwgeom_getType(srl[0]); int i; +#ifdef DEBUG_CALLS + lwnotice("lwmpoly_deserialize called"); +#endif + if ( type != MULTIPOLYGONTYPE ) { lwerror("lwmpoly_deserialize called on NON multipoly: %d", @@ -21,20 +27,19 @@ lwmpoly_deserialize(char *srl) insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWMPOLY)); - result->type = srl[0]; result->type = MULTIPOLYGONTYPE; result->SRID = insp->SRID; result->ndims = lwgeom_ndims(insp->type); - result->npolys = insp->ngeometries; - result->polys = lwalloc(sizeof(LWPOLY *)*insp->ngeometries); + result->ngeoms = insp->ngeometries; + result->geoms = lwalloc(sizeof(LWPOLY *)*insp->ngeometries); for (i=0; ingeometries; i++) { - result->polys[i] = lwpoly_deserialize(insp->sub_geoms[i]); - if ( result->polys[i]->ndims != result->ndims ) + result->geoms[i] = lwpoly_deserialize(insp->sub_geoms[i]); + if ( result->geoms[i]->ndims != result->ndims ) { lwerror("Mixed dimensions (multipoly:%d, poly%d:%d)", - result->ndims, i, result->polys[i]->ndims); + result->ndims, i, result->geoms[i]->ndims); return NULL; } } @@ -51,8 +56,8 @@ lwmpoly_serialize_size(LWMPOLY *mpoly) if ( mpoly->SRID != -1 ) size += 4; // SRID - for (i=0; inpolys; i++) - size += lwpoly_serialize_size(mpoly->polys[i]); + for (i=0; ingeoms; i++) + size += lwpoly_serialize_size(mpoly->geoms[i]); return size; } @@ -84,14 +89,14 @@ lwmpoly_serialize_buf(LWMPOLY *mpoly, char *buf, int *retsize) } // Write number of subgeoms - memcpy(loc, &mpoly->npolys, 4); + memcpy(loc, &mpoly->ngeoms, 4); size += 4; loc += 4; // Serialize subgeoms - for (i=0; inpolys; i++) + for (i=0; ingeoms; i++) { - lwpoly_serialize_buf(mpoly->polys[i], loc, &subsize); + lwpoly_serialize_buf(mpoly->geoms[i], loc, &subsize); size += subsize; }