From: Sandro Santilli Date: Mon, 4 Oct 2004 13:53:42 +0000 (+0000) Subject: Serialized form and WKB prepared to accept ZM flags replacing DD (dimensions) X-Git-Tag: pgis_1_0_0RC1~349 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d745e459b8564a8a4e32f2ffc01f63846022caa8;p=postgis Serialized form and WKB prepared to accept ZM flags replacing DD (dimensions) git-svn-id: http://svn.osgeo.org/postgis/trunk@923 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/lwgeom/liblwgeom.h b/lwgeom/liblwgeom.h index bd500e068..9238f4cb2 100644 --- a/lwgeom/liblwgeom.h +++ b/lwgeom/liblwgeom.h @@ -143,10 +143,8 @@ typedef struct // LWGEOM (any type) typedef struct { - int type; // POINT|LINE|POLY|MPOINT|MLINE|MPOLY|COLLECTION - char ndims; // 2=2d, 3=3d, 4=4d + unsigned char type; uint32 SRID; // -1 == unneeded - char hasbbox; void *data; } LWGEOM; @@ -154,9 +152,7 @@ typedef struct 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" @@ -164,9 +160,7 @@ typedef struct typedef struct { int type; // LINETYPE - char ndims; uint32 SRID; - char hasbbox; POINTARRAY *points; // array of POINT3D } LWLINE; //"light-weight line" @@ -174,9 +168,7 @@ typedef struct 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" @@ -184,10 +176,8 @@ typedef struct // MULTIPOINTTYPE typedef struct { - int type; // MULTIPOINTTYPE - char ndims; + unsigned char type; uint32 SRID; - char hasbbox; int ngeoms; LWPOINT **geoms; } LWMPOINT; @@ -195,10 +185,8 @@ typedef struct // MULTILINETYPE typedef struct { - int type; // MULTILINETYPE - char ndims; + unsigned char type; uint32 SRID; - char hasbbox; int ngeoms; LWLINE **geoms; } LWMLINE; @@ -206,10 +194,8 @@ typedef struct // MULTIPOLYGONTYPE typedef struct { - int type; // MULTIPOLYGONTYPE - char ndims; + unsigned char type; uint32 SRID; - char hasbbox; int ngeoms; LWPOLY **geoms; } LWMPOLY; @@ -217,10 +203,8 @@ typedef struct // COLLECTIONTYPE typedef struct { - int type; // COLLECTIONTYPE - char ndims; + unsigned char type; uint32 SRID; - char hasbbox; int ngeoms; LWGEOM **geoms; } LWCOLLECTION; @@ -312,7 +296,7 @@ extern int pointArray_ptsize(const POINTARRAY *pa); * 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) + * ZM = dimentionality (hasZ, hasM) * tttt = actual type (as per the WKB type): * * enum wkbGeometryType { @@ -334,13 +318,25 @@ extern int pointArray_ptsize(const POINTARRAY *pa); #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) +#define WKBZOFFSET 0x80000000 +#define WKBMOFFSET 0x40000000 + +#define TYPE_SETTYPE(c,t) ((c)=(((c)&0xF0)|t)) +#define TYPE_SETZM(t,z,m) ((t)=(((t)&0xCF)|(z<<5)|(m<<4))) +#define TYPE_SETHASBBOX(t,b) ((t)=(((t)&0x7F)|(b<<7))) +#define TYPE_SETHASSRID(t,s) ((t)=(((t)&0xBF)|(s<<6))) + +#define TYPE_HASZ(t) ( ((t)&0x20)>>5 ) +#define TYPE_HASM(t) ( ((t)&0x10)>>4 ) +#define TYPE_HASBBOX(t) ((t)&0x80) +#define TYPE_HASSRID(t) (((t)&0x40)) +#define TYPE_NDIMS(t) ((((t)&0x20)>>5)+(((t)&0x10)>>4)+2) +#define TYPE_GETTYPE(t) ((t)&0x0F) extern char lwgeom_hasBBOX(unsigned char type); // true iff B bit set -extern int lwgeom_ndims(unsigned char type); // returns the DD value +extern int lwgeom_ndims(unsigned char type); // returns 2,3 or 4 +extern int lwgeom_hasZ(unsigned char type); // has Z ? +extern int lwgeom_hasM(unsigned char type); // has M ? extern int lwgeom_getType(unsigned char type); // returns the tttt value extern unsigned char lwgeom_makeType(int ndims, char hasSRID, int type); @@ -399,7 +395,7 @@ extern uint32 lwgeom_size_poly(const char *serialized_line); // 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); +extern LWPOINT *lwpoint_construct(int ndims, int SRID, char wantbbox, POINTARRAY *point); // given the LWPOINT serialized form (or a pointer into a muli* one) // construct a proper LWPOINT. @@ -429,7 +425,7 @@ extern POINT3D lwpoint_getPoint3d(const LWPOINT *point); // 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); +extern LWLINE *lwline_construct(int ndims, int SRID, char wantbbox, POINTARRAY *points); // given the LWGEOM serialized form (or a pointer into a muli* one) // construct a proper LWLINE. @@ -455,7 +451,7 @@ extern BOX3D *lwline_findbbox(LWLINE *line); // construct a new LWPOLY. arrays (points/points per ring) will NOT be copied // use SRID=-1 for unknown SRID (will have 8bit type's S = 0) -extern LWPOLY *lwpoly_construct(int ndims, int SRID, int nrings,POINTARRAY **points); +extern LWPOLY *lwpoly_construct(int ndims, int SRID, char wantbbox, int nrings, POINTARRAY **points); // given the LWPOLY serialized form (or a pointer into a muli* one) // construct a proper LWPOLY. @@ -943,5 +939,7 @@ extern LWCOLLECTION *lwcollection_clone(const LWCOLLECTION *lwgeom); extern LWCOLLECTION *lwcollection_construct(int type, int ndims, uint32 SRID, char hasbbox, int ngeoms, LWGEOM **geoms); +// Return a char string with ASCII versionf of type flags +extern const char *lwgeom_typeflags(unsigned char type); #endif // !defined _LIBLWGEOM_H diff --git a/lwgeom/lwcollection.c b/lwgeom/lwcollection.c index 967b8c875..43a06922e 100644 --- a/lwgeom/lwcollection.c +++ b/lwgeom/lwcollection.c @@ -24,9 +24,7 @@ lwcollection_deserialize(char *srl) insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWCOLLECTION)); - result->type = COLLECTIONTYPE; - result->hasbbox = lwgeom_hasBBOX(typefl); - result->ndims = lwgeom_ndims(typefl); + result->type = typefl; result->SRID = insp->SRID; result->ngeoms = insp->ngeometries; result->geoms = lwalloc(sizeof(LWGEOM *)*insp->ngeometries); @@ -53,7 +51,7 @@ lwcollection_serialize_size(LWCOLLECTION *col) int i; if ( col->SRID != -1 ) size += 4; // SRID - if ( col->hasbbox ) size += sizeof(BOX2DFLOAT4); + if ( TYPE_HASBBOX(col->type) ) size += sizeof(BOX2DFLOAT4); #ifdef DEBUG_CALLS lwnotice("lwcollection_serialize_size[%p]: start size: %d", col, size); @@ -89,12 +87,12 @@ lwcollection_serialize_buf(LWCOLLECTION *coll, char *buf, size_t *retsize) hasSRID = (coll->SRID != -1); - buf[0] = (unsigned char) lwgeom_makeType_full(coll->ndims, - hasSRID, coll->type, coll->hasbbox); + buf[0] = (unsigned char) lwgeom_makeType_full(TYPE_NDIMS(coll->type), + hasSRID, TYPE_GETTYPE(coll->type), TYPE_HASBBOX(coll->type)); loc = buf+1; // Add BBOX if requested - if ( coll->hasbbox ) + if ( TYPE_HASBBOX(coll->type) ) { lwgeom_compute_bbox_p((LWGEOM *)coll, (BOX2DFLOAT4 *)loc); size += sizeof(BOX2DFLOAT4); @@ -147,10 +145,9 @@ lwcollection_construct(int type, int ndims, uint32 SRID, char hasbbox, { LWCOLLECTION *ret; ret = lwalloc(sizeof(LWCOLLECTION)); - ret->type = type; - ret->ndims = ndims; + ret->type = lwgeom_makeType_full(ndims, (SRID!=-1), COLLECTIONTYPE, + hasbbox); ret->SRID = SRID; - ret->hasbbox = hasbbox; ret->ngeoms = ngeoms; ret->geoms = geoms; return ret; @@ -203,8 +200,10 @@ lwcollection_add(const LWCOLLECTION *to, uint32 where, const LWGEOM *what) geoms[i+1] = lwgeom_clone(to->geoms[i]); } - col = lwcollection_construct(COLLECTIONTYPE, to->ndims, to->SRID, - (what->hasbbox || to->hasbbox ), to->ngeoms+1, geoms); + col = lwcollection_construct(COLLECTIONTYPE, TYPE_NDIMS(to->type), + to->SRID, + ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->ngeoms+1, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwgeom.c b/lwgeom/lwgeom.c index 57ebe2408..c84ff48a0 100644 --- a/lwgeom/lwgeom.c +++ b/lwgeom/lwgeom.c @@ -38,7 +38,7 @@ lwgeom_deserialize(char *srl) size_t lwgeom_serialize_size(LWGEOM *lwgeom) { - int type = lwgeom->type; + int type = TYPE_GETTYPE(lwgeom->type); #ifdef DEBUG_CALLS lwnotice("lwgeom_serialize_size called"); @@ -66,7 +66,7 @@ lwgeom_serialize_size(LWGEOM *lwgeom) void lwgeom_serialize_buf(LWGEOM *lwgeom, char *buf, size_t *retsize) { - int type = lwgeom->type; + int type = TYPE_GETTYPE(lwgeom->type); #ifdef DEBUG_CALLS lwnotice("lwgeom_serialize_buf called with a %s", @@ -124,7 +124,7 @@ lwgeom_forceRHR(LWGEOM *lwgeom) LWCOLLECTION *coll; int i; - switch (lwgeom->type) + switch (TYPE_GETTYPE(lwgeom->type)) { case POLYGONTYPE: lwpoly_reverse((LWPOLY *)lwgeom); @@ -146,7 +146,7 @@ lwgeom_reverse(LWGEOM *lwgeom) int i; LWCOLLECTION *col; - switch (lwgeom->type) + switch (TYPE_GETTYPE(lwgeom->type)) { case LINETYPE: lwline_reverse((LWLINE *)lwgeom); @@ -167,7 +167,7 @@ lwgeom_reverse(LWGEOM *lwgeom) int lwgeom_compute_bbox_p(LWGEOM *lwgeom, BOX2DFLOAT4 *buf) { - switch(lwgeom->type) + switch(TYPE_GETTYPE(lwgeom->type)) { case POINTTYPE: return lwpoint_compute_bbox_p((LWPOINT *)lwgeom, buf); @@ -276,7 +276,7 @@ lwgeom_release(LWGEOM *lwgeom) LWGEOM * lwgeom_clone(const LWGEOM *lwgeom) { - switch(lwgeom->type) + switch(TYPE_GETTYPE(lwgeom->type)) { case POINTTYPE: return (LWGEOM *)lwpoint_clone((LWPOINT *)lwgeom); @@ -302,13 +302,13 @@ lwgeom_clone(const LWGEOM *lwgeom) LWGEOM * lwgeom_add(const LWGEOM *to, uint32 where, const LWGEOM *what) { - if ( what->ndims != to->ndims ) + if ( TYPE_NDIMS(what->type) != TYPE_NDIMS(to->type) ) { lwerror("lwgeom_add: mixed dimensions not supported"); return NULL; } - switch(to->type) + switch(TYPE_GETTYPE(to->type)) { case POINTTYPE: return (LWGEOM *)lwpoint_add((const LWPOINT *)to, where, what); diff --git a/lwgeom/lwgeom_api.c b/lwgeom/lwgeom_api.c index 111e04160..700e34375 100644 --- a/lwgeom/lwgeom_api.c +++ b/lwgeom/lwgeom_api.c @@ -775,15 +775,29 @@ pointArray_ptsize(const POINTARRAY *pa) // returns true if this type says it has an SRID (S bit set) -char lwgeom_hasSRID(unsigned char type) +char +lwgeom_hasSRID(unsigned char type) { - return (type & 0x40); + return TYPE_HASSRID(type); } // returns either 2,3, or 4 -- 2=2D, 3=3D, 4=4D -int lwgeom_ndims(unsigned char type) +int +lwgeom_ndims(unsigned char type) +{ + return TYPE_NDIMS(type); +} + +// has M ? +int lwgeom_hasM(unsigned char type) +{ + return ( (type & 0x10) >>4); +} + +// has Z ? +int lwgeom_hasZ(unsigned char type) { - return ( (type & 0x30) >>4) +2; + return ( (type & 0x20) >>5); } @@ -797,31 +811,25 @@ int lwgeom_getType(unsigned char type) //construct a type (hasBOX=false) unsigned char lwgeom_makeType(int ndims, char hasSRID, int type) { - unsigned char result = type; - - if (ndims == 3) - result = result | 0x10; - if (ndims == 4) - result = result | 0x20; - if (hasSRID) - result = result | 0x40; - - return result; + return lwgeom_makeType_full(ndims, hasSRID, type, 0); } -//construct a type +/* + * Construct a type + * TODO: needs to be expanded to accept explicit MZ type + */ unsigned char lwgeom_makeType_full(int ndims, char hasSRID, int type, char hasBBOX) { unsigned char result = type; if (ndims == 3) - result = result | 0x10; + TYPE_SETZM(result, 1, 0); if (ndims == 4) - result = result | 0x20; + TYPE_SETZM(result, 1, 1); if (hasSRID) - result = result | 0x40; + TYPE_SETHASSRID(result, 1); if (hasBBOX) - result = result | 0x80; + TYPE_SETHASBBOX(result, 1); return result; } @@ -829,7 +837,7 @@ unsigned char lwgeom_makeType_full(int ndims, char hasSRID, int type, char hasBB //returns true if there's a bbox in this LWGEOM (B bit set) char lwgeom_hasBBOX(unsigned char type) { - return (type & 0x80); + return TYPE_HASBBOX(type); } //***************************************************************************** @@ -2644,3 +2652,17 @@ box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox) return 1; } + +const char * +lwgeom_typeflags(unsigned char type) +{ + static char flags[5]; + int flagno=0; + if ( TYPE_HASZ(type) ) flags[flagno++] = 'Z'; + if ( TYPE_HASM(type) ) flags[flagno++] = 'M'; + if ( TYPE_HASBBOX(type) ) flags[flagno++] = 'B'; + if ( TYPE_HASSRID(type) ) flags[flagno++] = 'S'; + flags[flagno] = '\0'; + //lwnotice("Flags: %s - returning %p", flags, flags); + return flags; +} diff --git a/lwgeom/lwgeom_box2dfloat4.c b/lwgeom/lwgeom_box2dfloat4.c index 752afe43b..a395e8b58 100644 --- a/lwgeom/lwgeom_box2dfloat4.c +++ b/lwgeom/lwgeom_box2dfloat4.c @@ -434,7 +434,7 @@ Datum BOX2DFLOAT4_to_LWGEOM(PG_FUNCTION_ARGS) pa[0]->npoints = 5; // Construct polygon - poly = lwpoly_construct(2, -1, 1, pa); + poly = lwpoly_construct(2, -1, wantbbox, 1, pa); // Serialize polygon ser = lwpoly_serialize(poly); diff --git a/lwgeom/lwgeom_box3d.c b/lwgeom/lwgeom_box3d.c index 60c461d58..496bf7bc7 100644 --- a/lwgeom/lwgeom_box3d.c +++ b/lwgeom/lwgeom_box3d.c @@ -180,7 +180,7 @@ Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS) pa[0]->npoints = 5; // Construct polygon - poly = lwpoly_construct(2, -1, 1, pa); + poly = lwpoly_construct(2, -1, wantbbox, 1, pa); // Serialize polygon ser = lwpoly_serialize(poly); diff --git a/lwgeom/lwgeom_chip.c b/lwgeom/lwgeom_chip.c index 9fbaa4043..2af28c797 100644 --- a/lwgeom/lwgeom_chip.c +++ b/lwgeom/lwgeom_chip.c @@ -180,7 +180,7 @@ Datum CHIP_to_LWGEOM(PG_FUNCTION_ARGS) pa[0]->npoints = 5; // Construct polygon - poly = lwpoly_construct(2, chip->SRID, 1, pa); + poly = lwpoly_construct(2, chip->SRID, wantbbox, 1, pa); // Serialize polygon ser = lwpoly_serialize(poly); diff --git a/lwgeom/lwgeom_debug.c b/lwgeom/lwgeom_debug.c index 8692f285b..1ab7fff7b 100644 --- a/lwgeom/lwgeom_debug.c +++ b/lwgeom/lwgeom_debug.c @@ -14,7 +14,7 @@ lwgeom_summary(LWGEOM *lwgeom, int offset) { char *result; - switch (lwgeom->type) + switch (TYPE_GETTYPE(lwgeom->type)) { case POINTTYPE: return lwpoint_summary((LWPOINT *)lwgeom, offset); @@ -47,16 +47,14 @@ char * lwpoint_summary(LWPOINT *point, int offset) { char *result; - result = lwalloc(128); + result = lwalloc(128+offset); char pad[offset+1]; memset(pad, ' ', offset); pad[offset] = '\0'; - sprintf(result, "%s%s[%c%c%d]\n", - pad, lwgeom_typename(point->type), - point->hasbbox ? 'B' : '_', - point->SRID != -1 ? 'S' : '_', - point->ndims); + sprintf(result, "%s%s[%s]\n", + pad, lwgeom_typename(TYPE_GETTYPE(point->type)), + lwgeom_typeflags(point->type)); return result; } @@ -69,11 +67,9 @@ lwline_summary(LWLINE *line, int offset) memset(pad, ' ', offset); pad[offset] = '\0'; - sprintf(result, "%s%s[%c%c%d] with %d points\n", - pad, lwgeom_typename(line->type), - line->hasbbox ? 'B' : '_', - line->SRID != -1 ? 'S' : '_', - line->ndims, + sprintf(result, "%s%s[%s] with %d points\n", + pad, lwgeom_typename(TYPE_GETTYPE(line->type)), + lwgeom_typeflags(line->type), line->points->npoints); return result; } @@ -96,11 +92,9 @@ lwcollection_summary(LWCOLLECTION *col, int offset) result = (char *)lwalloc(size); - sprintf(result, "%s%s[%c%c%d] with %d elements\n", - pad, lwgeom_typename(col->type), - col->hasbbox ? 'B' : '_', - col->SRID != -1 ? 'S' : '_', - col->ndims, + sprintf(result, "%s%s[%s] with %d elements\n", + pad, lwgeom_typename(TYPE_GETTYPE(col->type)), + lwgeom_typeflags(col->type), col->ngeoms); for (i=0; ingeoms; i++) @@ -137,11 +131,9 @@ lwpoly_summary(LWPOLY *poly, int offset) result = lwalloc(size); - sprintf(result, "%s%s[%c%c%d] with %i rings\n", - pad, lwgeom_typename(poly->type), - poly->hasbbox ? 'B' : '_', - poly->SRID != -1 ? 'S' : '_', - poly->ndims, + sprintf(result, "%s%s[%s] with %i rings\n", + pad, lwgeom_typename(TYPE_GETTYPE(poly->type)), + lwgeom_typeflags(poly->type), poly->nrings); for (i=0; inrings;i++) diff --git a/lwgeom/lwgeom_functions_analytic.c b/lwgeom/lwgeom_functions_analytic.c index d9adc1531..36fd5d757 100644 --- a/lwgeom/lwgeom_functions_analytic.c +++ b/lwgeom/lwgeom_functions_analytic.c @@ -176,7 +176,8 @@ simplify2d_lwline(LWLINE *iline, double dist) ipts = iline->points; opts = DP_simplify2d(ipts, dist); - oline = lwline_construct(ipts->ndims, iline->SRID, opts); + oline = lwline_construct(ipts->ndims, iline->SRID, + TYPE_HASBBOX(iline->type), opts); return oline; } @@ -246,8 +247,8 @@ elog(NOTICE, "simplify_polygon3d: simplified polygon with %d rings", norings); if ( ! norings ) return NULL; opoly = palloc(sizeof(LWPOLY)); + opoly->type = ipoly->type; opoly->SRID = ipoly->SRID; - opoly->ndims = ipoly->ndims; opoly->nrings = norings; opoly->rings = orings; @@ -381,8 +382,10 @@ Datum LWGEOM_line_interpolate_point(PG_FUNCTION_ARGS) else getPoint4d_p(ipa, ipa->npoints-1, (char *)&pt); - opa = pointArray_construct((char *)&pt, line->ndims, 1); - point = lwpoint_construct(line->ndims, line->SRID, opa); + opa = pointArray_construct((char *)&pt, + TYPE_NDIMS(line->type), 1); + point = lwpoint_construct(TYPE_NDIMS(line->type), + line->SRID, 0, opa); srl = lwpoint_serialize(point); pfree_point(point); PG_RETURN_POINTER(PG_LWGEOM_construct(srl, line->SRID, 0)); @@ -411,8 +414,10 @@ Datum LWGEOM_line_interpolate_point(PG_FUNCTION_ARGS) pt.y = (p1->y) + ((p2->y - p1->y) * dseg); pt.z = 0; pt.m = 0; - opa = pointArray_construct((char *)&pt, line->ndims, 1); - point = lwpoint_construct(line->ndims, line->SRID, opa); + opa = pointArray_construct((char *)&pt, + TYPE_NDIMS(line->type), 1); + point = lwpoint_construct(TYPE_NDIMS(line->type), + line->SRID, 0, opa); srl = lwpoint_serialize(point); pfree_point(point); PG_RETURN_POINTER(PG_LWGEOM_construct(srl, line->SRID, 0)); @@ -423,8 +428,8 @@ Datum LWGEOM_line_interpolate_point(PG_FUNCTION_ARGS) /* Return the last point on the line. This shouldn't happen, but * could if there's some floating point rounding errors. */ getPoint4d_p(ipa, ipa->npoints-1, (char *)&pt); - opa = pointArray_construct((char *)&pt, line->ndims, 1); - point = lwpoint_construct(line->ndims, line->SRID, opa); + opa = pointArray_construct((char *)&pt, TYPE_NDIMS(line->type), 1); + point = lwpoint_construct(TYPE_NDIMS(line->type), line->SRID, 0, opa); srl = lwpoint_serialize(point); pfree_point(point); PG_RETURN_POINTER(PG_LWGEOM_construct(srl, line->SRID, 0)); diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index 3bf9eaf10..a0a80799b 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -1249,7 +1249,7 @@ lwgeom_force2d_recursive(char *serialized, char *optr, int *retsize) if ( type == POINTTYPE ) { point = lwpoint_deserialize(serialized); - point->ndims = 2; + TYPE_SETZM(point->type, 0, 0); lwpoint_serialize_buf(point, optr, retsize); #ifdef DEBUG elog(NOTICE, "lwgeom_force2d_recursive: it's a point, size:%d", *retsize); @@ -1260,7 +1260,7 @@ elog(NOTICE, "lwgeom_force2d_recursive: it's a point, size:%d", *retsize); if ( type == LINETYPE ) { line = lwline_deserialize(serialized); - line->ndims = 2; + TYPE_SETZM(line->type, 0, 0); lwline_serialize_buf(line, optr, retsize); #ifdef DEBUG elog(NOTICE, "lwgeom_force2d_recursive: it's a line, size:%d", *retsize); @@ -1271,7 +1271,7 @@ elog(NOTICE, "lwgeom_force2d_recursive: it's a line, size:%d", *retsize); if ( type == POLYGONTYPE ) { poly = lwpoly_deserialize(serialized); - poly->ndims = 2; + TYPE_SETZM(poly->type, 0, 0); lwpoly_serialize_buf(poly, optr, retsize); #ifdef DEBUG elog(NOTICE, "lwgeom_force2d_recursive: it's a poly, size:%d", *retsize); @@ -1369,7 +1369,7 @@ lwgeom_force3d_recursive(char *serialized, char *optr, int *retsize) if ( type == POINTTYPE ) { point = lwpoint_deserialize(serialized); - if ( point->ndims < 3 ) + if ( TYPE_NDIMS(point->type) < 3 ) { newpts.ndims = 3; newpts.npoints = 1; @@ -1378,7 +1378,7 @@ lwgeom_force3d_recursive(char *serialized, char *optr, int *retsize) getPoint3d_p(point->point, 0, loc); point->point = &newpts; } - point->ndims = 3; + TYPE_SETZM(point->type, 1, 0); lwpoint_serialize_buf(point, optr, retsize); #ifdef DEBUG elog(NOTICE, "lwgeom_force3d_recursive: it's a point, size:%d", *retsize); @@ -1392,7 +1392,7 @@ elog(NOTICE, "lwgeom_force3d_recursive: it's a point, size:%d", *retsize); elog(NOTICE, "lwgeom_force3d_recursive: it's a line"); #endif line = lwline_deserialize(serialized); - if ( line->ndims < 3 ) + if ( TYPE_NDIMS(line->type) < 3 ) { newpts.ndims = 3; newpts.npoints = line->points->npoints; @@ -1406,7 +1406,7 @@ elog(NOTICE, "lwgeom_force3d_recursive: it's a line"); line->points = &newpts; } - line->ndims = 3; + TYPE_SETZM(line->type, 1, 0); lwline_serialize_buf(line, optr, retsize); #ifdef DEBUG elog(NOTICE, "lwgeom_force3d_recursive: it's a line, size:%d", *retsize); @@ -1417,7 +1417,7 @@ elog(NOTICE, "lwgeom_force3d_recursive: it's a line, size:%d", *retsize); if ( type == POLYGONTYPE ) { poly = lwpoly_deserialize(serialized); - if ( poly->ndims < 3 ) + if ( TYPE_NDIMS(poly->type) < 3 ) { newpts.ndims = 3; newpts.npoints = 0; @@ -1442,7 +1442,7 @@ elog(NOTICE, "lwgeom_force3d_recursive: it's a line, size:%d", *retsize); } poly->rings = nrings; } - poly->ndims = 3; + TYPE_SETZM(poly->type, 1, 0); lwpoly_serialize_buf(poly, optr, retsize); #ifdef DEBUG elog(NOTICE, "lwgeom_force3d_recursive: it's a poly, size:%d", *retsize); @@ -1539,7 +1539,7 @@ lwgeom_force4d_recursive(char *serialized, char *optr, int *retsize) if ( type == POINTTYPE ) { point = lwpoint_deserialize(serialized); - if ( point->ndims < 4 ) + if ( TYPE_NDIMS(point->type) < 4 ) { newpts.ndims = 4; newpts.npoints = 1; @@ -1548,7 +1548,7 @@ lwgeom_force4d_recursive(char *serialized, char *optr, int *retsize) getPoint4d_p(point->point, 0, loc); point->point = &newpts; } - point->ndims = 4; + TYPE_SETZM(point->type, 1, 1); lwpoint_serialize_buf(point, optr, retsize); #ifdef DEBUG elog(NOTICE, "lwgeom_force4d_recursive: it's a point, size:%d", *retsize); @@ -1562,7 +1562,7 @@ elog(NOTICE, "lwgeom_force4d_recursive: it's a point, size:%d", *retsize); elog(NOTICE, "lwgeom_force4d_recursive: it's a line"); #endif line = lwline_deserialize(serialized); - if ( line->ndims < 4 ) + if ( TYPE_NDIMS(line->type) < 4 ) { newpts.ndims = 4; newpts.npoints = line->points->npoints; @@ -1576,7 +1576,7 @@ elog(NOTICE, "lwgeom_force4d_recursive: it's a line"); line->points = &newpts; } - line->ndims = 4; + TYPE_SETZM(line->type, 1, 1); lwline_serialize_buf(line, optr, retsize); #ifdef DEBUG elog(NOTICE, "lwgeom_force4d_recursive: it's a line, size:%d", *retsize); @@ -1587,7 +1587,7 @@ elog(NOTICE, "lwgeom_force4d_recursive: it's a line, size:%d", *retsize); if ( type == POLYGONTYPE ) { poly = lwpoly_deserialize(serialized); - if ( poly->ndims < 4 ) + if ( TYPE_NDIMS(poly->type) < 4 ) { newpts.ndims = 4; newpts.npoints = 0; @@ -1612,7 +1612,7 @@ elog(NOTICE, "lwgeom_force4d_recursive: it's a line, size:%d", *retsize); } poly->rings = nrings; } - poly->ndims = 4; + TYPE_SETZM(poly->type, 1, 1); lwpoly_serialize_buf(poly, optr, retsize); #ifdef DEBUG elog(NOTICE, "lwgeom_force4d_recursive: it's a poly, size:%d", *retsize); @@ -2434,7 +2434,7 @@ Datum LWGEOM_expand(PG_FUNCTION_ARGS) pa[0]->npoints = 5; // Construct polygon - poly = lwpoly_construct(2, SRID, 1, pa); + poly = lwpoly_construct(2, SRID, lwgeom_hasBBOX(geom->type), 1, pa); // Serialize polygon ser = lwpoly_serialize(poly); @@ -2501,7 +2501,7 @@ Datum LWGEOM_envelope(PG_FUNCTION_ARGS) pa[0]->npoints = 5; // Construct polygon - poly = lwpoly_construct(2, SRID, 1, pa); + poly = lwpoly_construct(2, SRID, lwgeom_hasBBOX(geom->type), 1, pa); // Serialize polygon ser = lwpoly_serialize(poly); @@ -2576,7 +2576,7 @@ Datum centroid(PG_FUNCTION_ARGS) pa = pointArray_construct(¢, poly->ndims, 1); // Construct LWPOINT - point = lwpoint_construct(ndims, SRID, pa); + point = lwpoint_construct(ndims, SRID, wantbbox, pa); // Serialize LWPOINT srl = lwpoint_serialize(point); diff --git a/lwgeom/lwgeom_geos.c b/lwgeom/lwgeom_geos.c index 9da7a115d..493ed5aed 100644 --- a/lwgeom/lwgeom_geos.c +++ b/lwgeom/lwgeom_geos.c @@ -182,7 +182,7 @@ Datum unite_garray(PG_FUNCTION_ARGS) /* Ok, we really need geos now ;) */ initGEOS(MAXIMUM_ALIGNOF); - if ( lwgeom_ndims(geoms[0]->type) > 2 ) is3d = 1; + if ( TYPE_NDIMS(geoms[0]->type) > 2 ) is3d = 1; geos_result = POSTGIS2GEOS(geoms[0]); pfree(geoms[0]); for (i=1; itype) > 2 ) || - ( lwgeom_ndims(geom2->type) > 2 ); + is3d = ( TYPE_NDIMS(geom1->type) > 2 ) || + ( TYPE_NDIMS(geom2->type) > 2 ); initGEOS(MAXIMUM_ALIGNOF); //elog(NOTICE,"in geomunion"); @@ -338,8 +338,8 @@ Datum symdifference(PG_FUNCTION_ARGS) geom1 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); geom2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); - is3d = ( lwgeom_ndims(geom1->type) > 2 ) || - ( lwgeom_ndims(geom2->type) > 2 ); + is3d = ( TYPE_NDIMS(geom1->type) > 2 ) || + ( TYPE_NDIMS(geom2->type) > 2 ); initGEOS(MAXIMUM_ALIGNOF); @@ -452,7 +452,7 @@ Datum boundary(PG_FUNCTION_ARGS) #ifdef PROFILE profstart(PROF_G2P); #endif - result = GEOS2POSTGIS(g3, lwgeom_ndims(geom1->type) > 2); + result = GEOS2POSTGIS(g3, TYPE_NDIMS(geom1->type) > 2); #ifdef PROFILE profstart(PROF_P2G1); #endif @@ -522,7 +522,7 @@ Datum convexhull(PG_FUNCTION_ARGS) // elog(NOTICE,"result: %s", GEOSasText(g3) ) ; - result = GEOS2POSTGIS(g3, lwgeom_ndims(geom1->type) > 2); + result = GEOS2POSTGIS(g3, TYPE_NDIMS(geom1->type) > 2); if (result == NULL) { GEOSdeleteGeometry(g1); @@ -591,7 +591,7 @@ Datum buffer(PG_FUNCTION_ARGS) #ifdef PROFILE profstart(PROF_G2P); #endif - result = GEOS2POSTGIS(g3, lwgeom_ndims(geom1->type) > 2); + result = GEOS2POSTGIS(g3, TYPE_NDIMS(geom1->type) > 2); #ifdef PROFILE profstop(PROF_G2P); #endif @@ -632,8 +632,8 @@ Datum intersection(PG_FUNCTION_ARGS) geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); - is3d = ( lwgeom_ndims(geom1->type) > 2 ) || - ( lwgeom_ndims(geom2->type) > 2 ); + is3d = ( TYPE_NDIMS(geom1->type) > 2 ) || + ( TYPE_NDIMS(geom2->type) > 2 ); initGEOS(MAXIMUM_ALIGNOF); @@ -739,8 +739,8 @@ Datum difference(PG_FUNCTION_ARGS) geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); - is3d = ( lwgeom_ndims(geom1->type) > 2 ) || - ( lwgeom_ndims(geom2->type) > 2 ); + is3d = ( TYPE_NDIMS(geom1->type) > 2 ) || + ( TYPE_NDIMS(geom2->type) > 2 ); initGEOS(MAXIMUM_ALIGNOF); @@ -852,7 +852,7 @@ Datum pointonsurface(PG_FUNCTION_ARGS) #ifdef PROFILE profstart(PROF_G2P); #endif - result = GEOS2POSTGIS(g3, (lwgeom_ndims(geom1->type) > 2)); + result = GEOS2POSTGIS(g3, (TYPE_NDIMS(geom1->type) > 2)); #ifdef PROFILE profstop(PROF_G2P); #endif @@ -918,7 +918,7 @@ Datum centroid(PG_FUNCTION_ARGS) #ifdef PROFILE profstart(PROF_G2P); #endif - result = GEOS2POSTGIS(geosresult, (lwgeom_ndims(geom->type) > 2)); + result = GEOS2POSTGIS(geosresult, (TYPE_NDIMS(geom->type) > 2)); #ifdef PROFILE profstop(PROF_G2P); #endif @@ -1889,7 +1889,7 @@ lwpoint_from_geometry(Geometry *g, char want3d) #endif // Construct point array - pa = (POINTARRAY *)palloc(sizeof(POINTARRAY)); + pa = (POINTARRAY *)lwalloc(sizeof(POINTARRAY)); pa->ndims = want3d ? 3 : 2; pa->npoints = 1; @@ -1900,7 +1900,7 @@ lwpoint_from_geometry(Geometry *g, char want3d) GEOSdeleteChar( (char*) pts); // Construct LWPOINT - point = lwpoint_construct(pa->ndims, -1, pa); + point = lwpoint_construct(pa->ndims, -1, 0, pa); return point; } @@ -1940,7 +1940,7 @@ lwline_from_geometry(Geometry *g, char want3d) GEOSdeleteChar( (char*) pts); // Construct LWPOINT - line = lwline_construct(pa->ndims, -1, pa); + line = lwline_construct(pa->ndims, -1, 0, pa); return line; } @@ -2006,7 +2006,7 @@ lwpoly_from_geometry(Geometry *g, char want3d) } // Construct LWPOLY - poly = lwpoly_construct(pa->ndims, -1, nrings+1, rings); + poly = lwpoly_construct(pa->ndims, -1, 0, nrings+1, rings); return poly; } @@ -2041,7 +2041,7 @@ lwcollection_from_geometry(Geometry *geom, char want3d) #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)); + lwnotice("lwcollection_from_geometry: geoms[%d] is a %s", i, lwgeom_typename(TYPE_GETTYPE(geoms[i]->type))); #endif } @@ -2103,7 +2103,7 @@ GEOS2POSTGIS(Geometry *geom, char want3d) } #ifdef DEBUG_GEOS2POSTGIS - lwnotice("GEOS2POSTGIS: lwgeom_from_geometry returned a %s", lwgeom_summary(lwgeom, 0)); //lwgeom_typename(lwgeom->type)); + lwnotice("GEOS2POSTGIS: lwgeom_from_geometry returned a %s", lwgeom_summary(lwgeom, 0)); #endif size = lwgeom_serialize_size(lwgeom); @@ -2117,7 +2117,8 @@ GEOS2POSTGIS(Geometry *geom, char want3d) result->size = size; #ifdef DEBUG_GEOS2POSTGIS - lwnotice("GEOS2POSTGIS: about to serialize %s", lwgeom_typename(lwgeom->type)); + lwnotice("GEOS2POSTGIS: about to serialize %s", + lwgeom_typename(TYPE_GETTYPE(lwgeom->type))); #endif lwgeom_serialize_buf(lwgeom, SERIALIZED_FORM(result), &retsize); @@ -2146,7 +2147,7 @@ LWGEOM2GEOS(LWGEOM *lwgeom) lwnotice("LWGEOM2GEOS: got lwgeom[%p]", lwgeom); #endif - switch (lwgeom->type) + switch (TYPE_GETTYPE(lwgeom->type)) { case POINTTYPE: #ifdef DEBUG_POSTGIS2GEOS @@ -2172,19 +2173,20 @@ LWGEOM2GEOS(LWGEOM *lwgeom) case COLLECTIONTYPE: col = (LWCOLLECTION *)lwgeom; #ifdef DEBUG_POSTGIS2GEOS - lwnotice("LWGEOM2GEOS: %s with %d subgeoms", lwgeom_typename(col->type), col->ngeoms); + lwnotice("LWGEOM2GEOS: %s with %d subgeoms", lwgeom_typename(TYPE_GETTYPE(col->type)), col->ngeoms); #endif collected = (Geometry **)lwalloc(sizeof(Geometry *)*col->ngeoms); for (i=0; ingeoms; i++) { collected[i] = LWGEOM2GEOS(col->geoms[i]); } - return PostGIS2GEOS_collection(col->type, + return PostGIS2GEOS_collection(TYPE_GETTYPE(col->type), collected, col->ngeoms, col->SRID, - col->ndims>2); + TYPE_NDIMS(col->type)>2); default: - lwerror("Unknown geometry type: %d", lwgeom->type); + lwerror("Unknown geometry type: %d", + TYPE_GETTYPE(lwgeom->type)); return NULL; } @@ -2223,7 +2225,7 @@ Datum GEOSnoop(PG_FUNCTION_ARGS) profstop(PROF_GRUN); #endif - result = GEOS2POSTGIS(geosgeom, lwgeom_ndims(geom->type) > 2); + result = GEOS2POSTGIS(geosgeom, TYPE_NDIMS(geom->type) > 2); GEOSdeleteGeometry(geosgeom); #ifdef DEBUG_CONVERTER diff --git a/lwgeom/lwgeom_geos_wrapper.cpp b/lwgeom/lwgeom_geos_wrapper.cpp index c8826a9de..df284bb9a 100644 --- a/lwgeom/lwgeom_geos_wrapper.cpp +++ b/lwgeom/lwgeom_geos_wrapper.cpp @@ -27,6 +27,8 @@ typedef int int32; //---- Definitions found in lwgeom.h (and postgis) +#define TYPE_NDIMS(t) ((((t)&0x20)>>5)+(((t)&0x10)>>4)+2) + typedef unsigned int uint32; typedef int int32; @@ -47,30 +49,24 @@ typedef struct typedef struct { - int type; // POINTTYPE - char ndims; + unsigned char type; 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; + unsigned char type; uint32 SRID; - char hasbbox; POINTARRAY *points; // array of POINT3D } LWLINE; //"light-weight line" // POLYGONTYPE typedef struct { - int type; // POLYGONTYPE - char ndims; + unsigned char type; uint32 SRID; - char hasbbox; int nrings; POINTARRAY **rings; // list of rings (list of points) } LWPOLY; // "light-weight polygon" @@ -357,7 +353,7 @@ Geometry *PostGIS2GEOS_polygon(const LWPOLY *lwpoly) { POINTARRAY *pa; int SRID = lwpoly->SRID; - bool is3d = lwpoly->ndims > 2 ? 1 : 0; + bool is3d = TYPE_NDIMS(lwpoly->type) > 2 ? 1 : 0; #ifdef DEBUG_POSTGIS2GEOS char buf[256]; diff --git a/lwgeom/lwgeom_inout.c b/lwgeom/lwgeom_inout.c index c008ae8e2..bfd95bb2b 100644 --- a/lwgeom/lwgeom_inout.c +++ b/lwgeom/lwgeom_inout.c @@ -489,7 +489,6 @@ Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS) unsigned char old_type; int size; - //elog(NOTICE,"in LWGEOM_addBBOX"); if (lwgeom_hasBBOX( lwgeom->type ) ) @@ -517,6 +516,8 @@ Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS) // copy in bbox memcpy(result->data, &box, sizeof(BOX2DFLOAT4)); + //lwnotice("result->type hasbbox: %d", TYPE_HASBBOX(result->type)); + //elog(NOTICE,"LWGEOM_addBBOX -- about to copy serialized form"); // everything but the type and length memcpy(result->data+sizeof(BOX2DFLOAT4), lwgeom->data, lwgeom->size-5); diff --git a/lwgeom/lwgeom_ogc.c b/lwgeom/lwgeom_ogc.c index 1afb6fa58..925f05599 100644 --- a/lwgeom/lwgeom_ogc.c +++ b/lwgeom/lwgeom_ogc.c @@ -333,7 +333,8 @@ Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS) extring = poly->rings[0]; // This is a LWLINE constructed by exterior ring POINTARRAY - line = lwline_construct(poly->ndims, poly->SRID, extring); + line = lwline_construct(TYPE_NDIMS(poly->type), poly->SRID, + lwgeom_hasBBOX(geom->type), extring); // Now we serialized it (copying data) serializedline = lwline_serialize(line); @@ -416,7 +417,8 @@ Datum LWGEOM_interiorringn_polygon(PG_FUNCTION_ARGS) ring = poly->rings[wanted_index+1]; // This is a LWLINE constructed by exterior ring POINTARRAY - line = lwline_construct(poly->ndims, poly->SRID, ring); + line = lwline_construct(TYPE_NDIMS(poly->type), poly->SRID, + lwgeom_hasBBOX(geom->type), ring); // Now we serialized it (copying data) serializedline = lwline_serialize(line); @@ -476,7 +478,7 @@ Datum LWGEOM_pointn_linestring(PG_FUNCTION_ARGS) // Construct an LWPOINT point = lwpoint_construct(line->points->ndims, lwgeom_getSRID(geom), - pts); + lwgeom_hasBBOX(geom->type), pts); // Serialized the point serializedpoint = lwpoint_serialize(point); @@ -618,7 +620,7 @@ Datum LWGEOM_startpoint_linestring(PG_FUNCTION_ARGS) // Construct an LWPOINT point = lwpoint_construct(line->points->ndims, lwgeom_getSRID(geom), - pts); + lwgeom_hasBBOX(geom->type), pts); // Serialized the point serializedpoint = lwpoint_serialize(point); @@ -669,7 +671,7 @@ Datum LWGEOM_endpoint_linestring(PG_FUNCTION_ARGS) // Construct an LWPOINT point = lwpoint_construct(line->points->ndims, lwgeom_getSRID(geom), - pts); + lwgeom_hasBBOX(geom->type), pts); // Serialized the point serializedpoint = lwpoint_serialize(point); @@ -748,7 +750,7 @@ char line_is_closed(LWLINE *line) if ( sp->x != ep->x ) return 0; if ( sp->y != ep->y ) return 0; - if ( line->ndims > 2 ) + if ( TYPE_HASZ(line->type) ) { if ( sp->z != ep->z ) return 0; } diff --git a/lwgeom/lwgeom_pg.c b/lwgeom/lwgeom_pg.c index b81c70561..6e1745315 100644 --- a/lwgeom/lwgeom_pg.c +++ b/lwgeom/lwgeom_pg.c @@ -18,6 +18,11 @@ pg_alloc(size_t size) #ifdef DEBUG lwnotice(" pg_alloc(%d) returning %p", size, result); #endif + if ( ! result ) + { + elog(ERROR, "Out of virtual memory"); + return NULL; + } return result; } diff --git a/lwgeom/lwgparse.c b/lwgeom/lwgparse.c index 130b16061..7382948e4 100644 --- a/lwgeom/lwgparse.c +++ b/lwgeom/lwgparse.c @@ -8,6 +8,7 @@ #include "wktparse.h" #include #include +#include "liblwgeom.h" /* //To get byte order @@ -393,7 +394,17 @@ void write_type(tuple* this,output_state* out){ type |= this->type; if (the_geom.ndims) //Support empty - type |= ((the_geom.ndims-2) << 4); + { + if ( the_geom.ndims == 3 ) + { + TYPE_SETZM(type, 1, 0); + } + if ( the_geom.ndims == 4 ) + { + TYPE_SETZM(type, 1, 1); + } + //type |= ((the_geom.ndims-2) << 4); + } if ( the_geom.srid != -1 ){ type |= 0x40; @@ -666,12 +677,11 @@ void parse_wkb(const char** b){ //quick exit on error if ( ferror_occured ) return; - if (type & 0x80000000) + the_geom.ndims=2; + if (type & WKBZOFFSET) the_geom.ndims=3; - else if (type & 0x40000000) + if (type & WKBMOFFSET) the_geom.ndims=4; - else - the_geom.ndims=2; type &=0x0f; diff --git a/lwgeom/lwline.c b/lwgeom/lwline.c index 6262ca0aa..f5b156046 100644 --- a/lwgeom/lwline.c +++ b/lwgeom/lwline.c @@ -10,13 +10,14 @@ // 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) +LWLINE * +lwline_construct(int ndims, int SRID, char wantbbox, POINTARRAY *points) { LWLINE *result; result = (LWLINE*) lwalloc( sizeof(LWLINE)); - result->type = LINETYPE; - result->ndims =ndims; + result->type = lwgeom_makeType_full(ndims, (SRID!=-1), LINETYPE, + wantbbox); result->SRID = SRID; result->points = points; @@ -38,7 +39,7 @@ LWLINE *lwline_deserialize(char *serialized_form) result = (LWLINE*) lwalloc(sizeof(LWLINE)) ; type = (unsigned char) serialized_form[0]; - result->type = LINETYPE; + result->type = type; if ( lwgeom_getType(type) != LINETYPE) { @@ -52,11 +53,9 @@ LWLINE *lwline_deserialize(char *serialized_form) { //lwnotice("line has bbox"); loc += sizeof(BOX2DFLOAT4); - result->hasbbox = 1; } else { - result->hasbbox = 0; //lwnotice("line has NO bbox"); } @@ -80,7 +79,6 @@ LWLINE *lwline_deserialize(char *serialized_form) pa = pointArray_construct( loc, lwgeom_ndims(type), npoints); result->points = pa; - result->ndims = lwgeom_ndims(type); return result; } @@ -116,18 +114,18 @@ void lwline_serialize_buf(LWLINE *line, char *buf, size_t *retsize) char hasSRID; int t; char *loc; - int ptsize = sizeof(double)*line->ndims; + int ptsize = sizeof(double)*TYPE_NDIMS(line->type); if (line == NULL) lwerror("lwline_serialize:: given null line"); hasSRID = (line->SRID != -1); - buf[0] = (unsigned char) lwgeom_makeType_full(line->ndims, - hasSRID, LINETYPE, line->hasbbox); + buf[0] = (unsigned char) lwgeom_makeType_full(TYPE_NDIMS(line->type), + hasSRID, LINETYPE, TYPE_HASBBOX(line->type)); loc = buf+1; - if (line->hasbbox) + if (TYPE_HASBBOX(line->type)) { lwgeom_compute_bbox_p((LWGEOM *)line, (BOX2DFLOAT4 *)loc); loc += sizeof(BOX2DFLOAT4); @@ -149,7 +147,7 @@ void lwline_serialize_buf(LWLINE *line, char *buf, size_t *retsize) //lwnotice(" line serialize - size = %i", size); - if (line->ndims == 3) + if (TYPE_NDIMS(line->type) == 3) { for (t=0; t< line->points->npoints;t++) { @@ -157,7 +155,7 @@ void lwline_serialize_buf(LWLINE *line, char *buf, size_t *retsize) loc += 24; // size of a 3d point } } - else if (line->ndims == 2) + else if (TYPE_NDIMS(line->type) == 2) { for (t=0; t< line->points->npoints;t++) { @@ -165,7 +163,7 @@ void lwline_serialize_buf(LWLINE *line, char *buf, size_t *retsize) loc += 16; // size of a 2d point } } - else if (line->ndims == 4) + else if (TYPE_NDIMS(line->type) == 4) { for (t=0; t< line->points->npoints;t++) { @@ -203,9 +201,9 @@ lwline_serialize_size(LWLINE *line) #endif if ( line->SRID != -1 ) size += 4; // SRID - if ( line->hasbbox ) size += sizeof(BOX2DFLOAT4); + if ( TYPE_HASBBOX(line->type) ) size += sizeof(BOX2DFLOAT4); - size += sizeof(double)*line->ndims*line->points->npoints; // points + size += sizeof(double)*TYPE_NDIMS(line->type)*line->points->npoints; // points size += 4; // npoints #ifdef DEBUG_CALLS @@ -272,7 +270,7 @@ lwgeom_size_line(const char *serialized_line) void printLWLINE(LWLINE *line) { lwnotice("LWLINE {"); - lwnotice(" ndims = %i", (int)line->ndims); + lwnotice(" ndims = %i", (int)TYPE_NDIMS(line->type)); lwnotice(" SRID = %i", (int)line->SRID); printPA(line->points); lwnotice("}"); @@ -326,14 +324,18 @@ lwline_add(const LWLINE *to, uint32 where, const LWGEOM *what) } // reset SRID and wantbbox flag from component types geoms[0]->SRID = geoms[1]->SRID = -1; - geoms[0]->hasbbox = geoms[1]->hasbbox = 0; + TYPE_SETHASSRID(geoms[0]->type, 0); + TYPE_SETHASSRID(geoms[1]->type, 0); + TYPE_SETHASBBOX(geoms[0]->type, 0); + TYPE_SETHASBBOX(geoms[1]->type, 0); // Find appropriate geom type - if ( what->type == LINETYPE ) newtype = MULTILINETYPE; + if ( TYPE_GETTYPE(what->type) == LINETYPE ) newtype = MULTILINETYPE; else newtype = COLLECTIONTYPE; - col = lwcollection_construct(newtype, to->ndims, to->SRID, - (what->hasbbox || to->hasbbox ), 2, geoms); + col = lwcollection_construct(newtype, TYPE_NDIMS(to->type), to->SRID, + ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + 2, geoms); return (LWGEOM *)col; } diff --git a/lwgeom/lwmline.c b/lwgeom/lwmline.c index e45378c50..f724d988f 100644 --- a/lwgeom/lwmline.c +++ b/lwgeom/lwmline.c @@ -21,20 +21,20 @@ lwmline_deserialize(char *srl) insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWMLINE)); - result->type = MULTILINETYPE; + result->type = insp->type; 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); for (i=0; ingeometries; i++) { result->geoms[i] = lwline_deserialize(insp->sub_geoms[i]); - if ( result->geoms[i]->ndims != result->ndims ) + if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) ) { lwerror("Mixed dimensions (multiline:%d, line%d:%d)", - result->ndims, i, result->geoms[i]->ndims); + TYPE_NDIMS(result->type), i, + TYPE_NDIMS(result->geoms[i]->type) + ); return NULL; } } @@ -76,11 +76,12 @@ lwmline_add(const LWMLINE *to, uint32 where, const LWGEOM *what) geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]); } - if ( what->type == LINETYPE ) newtype = MULTILINETYPE; + if ( TYPE_GETTYPE(what->type) == LINETYPE ) newtype = MULTILINETYPE; else newtype = COLLECTIONTYPE; - col = lwcollection_construct(newtype, to->ndims, to->SRID, - (what->hasbbox || to->hasbbox ), to->ngeoms+1, geoms); + col = lwcollection_construct(newtype, TYPE_NDIMS(to->type), to->SRID, + ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->ngeoms+1, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwmpoint.c b/lwgeom/lwmpoint.c index 8a40df080..0ccfa3147 100644 --- a/lwgeom/lwmpoint.c +++ b/lwgeom/lwmpoint.c @@ -21,20 +21,20 @@ lwmpoint_deserialize(char *srl) insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWMPOINT)); - result->type = MULTIPOINTTYPE; + result->type = insp->type; 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); for (i=0; ingeometries; i++) { result->geoms[i] = lwpoint_deserialize(insp->sub_geoms[i]); - if ( result->geoms[i]->ndims != result->ndims ) + if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) ) { lwerror("Mixed dimensions (multipoint:%d, point%d:%d)", - result->ndims, i, result->geoms[i]->ndims); + TYPE_NDIMS(result->type), i, + TYPE_NDIMS(result->geoms[i]->type) + ); return NULL; } } @@ -76,11 +76,13 @@ lwmpoint_add(const LWMPOINT *to, uint32 where, const LWGEOM *what) geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]); } - if ( what->type == POINTTYPE ) newtype = MULTIPOINTTYPE; + if ( TYPE_GETTYPE(what->type) == POINTTYPE ) newtype = MULTIPOINTTYPE; else newtype = COLLECTIONTYPE; - col = lwcollection_construct(newtype, to->ndims, to->SRID, - (what->hasbbox || to->hasbbox ), to->ngeoms+1, geoms); + col = lwcollection_construct(newtype, TYPE_NDIMS(to->type), + to->SRID, + ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->ngeoms+1, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwmpoly.c b/lwgeom/lwmpoly.c index 3ccbcf38f..0f9c1b8ba 100644 --- a/lwgeom/lwmpoly.c +++ b/lwgeom/lwmpoly.c @@ -27,20 +27,20 @@ lwmpoly_deserialize(char *srl) insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWMPOLY)); - result->type = MULTIPOLYGONTYPE; + result->type = insp->type; 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); for (i=0; ingeometries; i++) { result->geoms[i] = lwpoly_deserialize(insp->sub_geoms[i]); - if ( result->geoms[i]->ndims != result->ndims ) + if ( TYPE_NDIMS(result->geoms[i]->type) != TYPE_NDIMS(result->type) ) { lwerror("Mixed dimensions (multipoly:%d, poly%d:%d)", - result->ndims, i, result->geoms[i]->ndims); + TYPE_NDIMS(result->type), i, + TYPE_NDIMS(result->geoms[i]->type) + ); return NULL; } } @@ -82,11 +82,12 @@ lwmpoly_add(const LWMPOLY *to, uint32 where, const LWGEOM *what) geoms[i+1] = lwgeom_clone((LWGEOM *)to->geoms[i]); } - if ( what->type == POLYGONTYPE ) newtype = MULTIPOLYGONTYPE; + if ( TYPE_GETTYPE(what->type) == POLYGONTYPE ) newtype = MULTIPOLYGONTYPE; else newtype = COLLECTIONTYPE; - col = lwcollection_construct(newtype, to->ndims, to->SRID, - (what->hasbbox || to->hasbbox ), to->ngeoms+1, geoms); + col = lwcollection_construct(newtype, TYPE_NDIMS(to->type), to->SRID, + ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + to->ngeoms+1, geoms); return (LWGEOM *)col; diff --git a/lwgeom/lwpoint.c b/lwgeom/lwpoint.c index deb2d388b..a1b69946a 100644 --- a/lwgeom/lwpoint.c +++ b/lwgeom/lwpoint.c @@ -43,15 +43,15 @@ lwpoint_serialize_buf(LWPOINT *point, char *buf, size_t *retsize) hasSRID = (point->SRID != -1); if (hasSRID) size +=4; //4 byte SRID - if (point->hasbbox) size += sizeof(BOX2DFLOAT4); // bvol + if (TYPE_HASBBOX(point->type)) size += sizeof(BOX2DFLOAT4); // bvol - size += sizeof(double)*point->ndims; + size += sizeof(double)*TYPE_NDIMS(point->type); - buf[0] = (unsigned char) lwgeom_makeType_full(point->ndims, - hasSRID, POINTTYPE, point->hasbbox); + buf[0] = (unsigned char) lwgeom_makeType_full(TYPE_NDIMS(point->type), + hasSRID, POINTTYPE, TYPE_HASBBOX(point->type)); loc = buf+1; - if (point->hasbbox) + if (TYPE_HASBBOX(point->type)) { lwgeom_compute_bbox_p((LWGEOM *)point, (BOX2DFLOAT4 *)loc); loc += sizeof(BOX2DFLOAT4); @@ -65,9 +65,9 @@ lwpoint_serialize_buf(LWPOINT *point, char *buf, size_t *retsize) //copy in points - if (point->ndims == 3) getPoint3d_p(point->point, 0, loc); - else if (point->ndims == 2) getPoint2d_p(point->point, 0, loc); - else if (point->ndims == 4) getPoint4d_p(point->point, 0, loc); + if (TYPE_NDIMS(point->type) == 3) getPoint3d_p(point->point, 0, loc); + else if (TYPE_NDIMS(point->type) == 2) getPoint2d_p(point->point, 0, loc); + else if (TYPE_NDIMS(point->type) == 4) getPoint4d_p(point->point, 0, loc); if (retsize) *retsize = size; } @@ -130,9 +130,9 @@ lwpoint_serialize_size(LWPOINT *point) #endif if ( point->SRID != -1 ) size += 4; // SRID - if ( point->hasbbox ) size += sizeof(BOX2DFLOAT4); + if ( TYPE_HASBBOX(point->type) ) size += sizeof(BOX2DFLOAT4); - size += point->ndims * sizeof(double); // point + size += TYPE_NDIMS(point->type) * sizeof(double); // point #ifdef DEBUG_CALLS lwnotice("lwpoint_serialize_size returning %d", size); @@ -144,7 +144,7 @@ lwpoint_serialize_size(LWPOINT *point) // construct a new point. point will not be copied // use SRID=-1 for unknown SRID (will have 8bit type's S = 0) LWPOINT * -lwpoint_construct(int ndims, int SRID, POINTARRAY *point) +lwpoint_construct(int ndims, int SRID, char wantbbox, POINTARRAY *point) { LWPOINT *result ; @@ -152,10 +152,9 @@ lwpoint_construct(int ndims, int SRID, POINTARRAY *point) return NULL; // error result = lwalloc(sizeof(LWPOINT)); - result->type = POINTTYPE; - result->ndims = ndims; + result->type = lwgeom_makeType_full(ndims, (SRID!=-1), POINTTYPE, + wantbbox); result->SRID = SRID; - result->point = point; return result; @@ -182,7 +181,7 @@ lwpoint_deserialize(char *serialized_form) type = (unsigned char) serialized_form[0]; if ( lwgeom_getType(type) != POINTTYPE) return NULL; - result->type = POINTTYPE; + result->type = type; loc = serialized_form+1; @@ -191,10 +190,8 @@ lwpoint_deserialize(char *serialized_form) #ifdef DEBUG lwnotice("lwpoint_deserialize: input has bbox"); #endif - result->hasbbox = 1; loc += sizeof(BOX2DFLOAT4); } - else result->hasbbox = 0; if ( lwgeom_hasSRID(type)) { @@ -214,7 +211,6 @@ lwpoint_deserialize(char *serialized_form) pa = pointArray_construct(loc, lwgeom_ndims(type), 1); result->point = pa; - result->ndims = lwgeom_ndims(type); return result; } @@ -228,8 +224,8 @@ void pfree_point (LWPOINT *pt) void printLWPOINT(LWPOINT *point) { lwnotice("LWPOINT {"); - lwnotice(" ndims = %i", (int)point->ndims); - lwnotice(" BBOX = %i", point->hasbbox ? 1 : 0 ); + lwnotice(" ndims = %i", (int)TYPE_NDIMS(point->type)); + lwnotice(" BBOX = %i", TYPE_HASBBOX(point->type) ? 1 : 0 ); lwnotice(" SRID = %i", (int)point->SRID); printPA(point->point); lwnotice("}"); @@ -287,14 +283,18 @@ lwpoint_add(const LWPOINT *to, uint32 where, const LWGEOM *what) } // reset SRID and wantbbox flag from component types geoms[0]->SRID = geoms[1]->SRID = -1; - geoms[0]->hasbbox = geoms[1]->hasbbox = 0; + TYPE_SETHASSRID(geoms[0]->type, 0); + TYPE_SETHASSRID(geoms[1]->type, 0); + TYPE_SETHASBBOX(geoms[0]->type, 0); + TYPE_SETHASBBOX(geoms[1]->type, 0); // Find appropriate geom type - if ( what->type == POINTTYPE ) newtype = MULTIPOINTTYPE; + if ( TYPE_GETTYPE(what->type) == POINTTYPE ) newtype = MULTIPOINTTYPE; else newtype = COLLECTIONTYPE; - col = lwcollection_construct(newtype, to->ndims, to->SRID, - (what->hasbbox || to->hasbbox ), 2, geoms); + col = lwcollection_construct(newtype, TYPE_NDIMS(to->type), to->SRID, + ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + 2, geoms); return (LWGEOM *)col; } diff --git a/lwgeom/lwpoly.c b/lwgeom/lwpoly.c index d0e34659a..21d734852 100644 --- a/lwgeom/lwpoly.c +++ b/lwgeom/lwpoly.c @@ -10,13 +10,13 @@ // construct a new LWPOLY. arrays (points/points per ring) will NOT be copied // use SRID=-1 for unknown SRID (will have 8bit type's S = 0) LWPOLY * -lwpoly_construct(int ndims, int SRID, int nrings,POINTARRAY **points) +lwpoly_construct(int ndims, int SRID, char wantbbox, int nrings, POINTARRAY **points) { LWPOLY *result; result = (LWPOLY*) lwalloc(sizeof(LWPOLY)); - result->type = POLYGONTYPE; - result->ndims = ndims; + result->type = lwgeom_makeType_full(ndims, (SRID!=-1), POLYGONTYPE, + wantbbox); result->SRID = SRID; result->nrings = nrings; result->rings = points; @@ -50,7 +50,7 @@ lwpoly_deserialize(char *serialized_form) result = (LWPOLY*) lwalloc(sizeof(LWPOLY)); type = (unsigned char) serialized_form[0]; - result->type = POLYGONTYPE; + result->type = type; ndims = lwgeom_ndims(type); loc = serialized_form; @@ -68,11 +68,6 @@ lwpoly_deserialize(char *serialized_form) if (lwgeom_hasBBOX(type)) { loc += sizeof(BOX2DFLOAT4); - result->hasbbox = 1; - } - else - { - result->hasbbox = 0; } if ( lwgeom_hasSRID(type)) @@ -104,7 +99,6 @@ lwpoly_deserialize(char *serialized_form) else if (ndims == 4) loc += 32*npoints; } - result->ndims = ndims; return result; } @@ -157,13 +151,13 @@ lwpoly_serialize_buf(LWPOLY *poly, char *buf, size_t *retsize) for (t=0;tnrings;t++) { total_points += poly->rings[t]->npoints; } - size += sizeof(double)*poly->ndims*total_points; + size += sizeof(double)*TYPE_NDIMS(poly->type)*total_points; - buf[0] = (unsigned char) lwgeom_makeType_full(poly->ndims, - hasSRID, POLYGONTYPE, poly->hasbbox); + buf[0] = (unsigned char) lwgeom_makeType_full(TYPE_NDIMS(poly->type), + hasSRID, POLYGONTYPE, TYPE_HASBBOX(poly->type)); loc = buf+1; - if (poly->hasbbox) + if (TYPE_HASBBOX(poly->type)) { lwgeom_compute_bbox_p((LWGEOM *)poly, (BOX2DFLOAT4 *)loc); size += sizeof(BOX2DFLOAT4); // bvol @@ -186,7 +180,7 @@ lwpoly_serialize_buf(LWPOLY *poly, char *buf, size_t *retsize) npoints = poly->rings[t]->npoints; memcpy(loc, &npoints, sizeof(int32)); //npoints this ring loc+=4; - if (poly->ndims == 3) + if (TYPE_NDIMS(poly->type) == 3) { for (u=0;undims == 2) + else if (TYPE_NDIMS(poly->type) == 2) { for (u=0;undims == 4) + else if (TYPE_NDIMS(poly->type) == 4) { for (u=0;uSRID != -1 ) size += 4; // SRID - if ( poly->hasbbox ) size += sizeof(BOX2DFLOAT4); + if ( TYPE_HASBBOX(poly->type) ) size += sizeof(BOX2DFLOAT4); #ifdef DEBUG_CALLS lwnotice("lwpoly_serialize_size called with poly[%p] (%d rings)", @@ -337,7 +331,7 @@ lwpoly_serialize_size(LWPOLY *poly) for (i=0; inrings; i++) { size += 4; // npoints - size += poly->rings[i]->npoints*poly->ndims*sizeof(double); + size += poly->rings[i]->npoints*TYPE_NDIMS(poly->type)*sizeof(double); } #ifdef DEBUG_CALLS @@ -363,7 +357,7 @@ void printLWPOLY(LWPOLY *poly) { int t; lwnotice("LWPOLY {"); - lwnotice(" ndims = %i", (int)poly->ndims); + lwnotice(" ndims = %i", (int)TYPE_NDIMS(poly->type)); lwnotice(" SRID = %i", (int)poly->SRID); lwnotice(" nrings = %i", (int)poly->nrings); for (t=0;tnrings;t++) @@ -436,14 +430,18 @@ lwpoly_add(const LWPOLY *to, uint32 where, const LWGEOM *what) } // reset SRID and wantbbox flag from component types geoms[0]->SRID = geoms[1]->SRID = -1; - geoms[0]->hasbbox = geoms[1]->hasbbox = 0; + TYPE_SETHASSRID(geoms[0]->type, 0); + TYPE_SETHASSRID(geoms[1]->type, 0); + TYPE_SETHASBBOX(geoms[0]->type, 0); + TYPE_SETHASBBOX(geoms[1]->type, 0); // Find appropriate geom type - if ( what->type == POLYGONTYPE ) newtype = MULTIPOLYGONTYPE; + if ( TYPE_GETTYPE(what->type) == POLYGONTYPE ) newtype = MULTIPOLYGONTYPE; else newtype = COLLECTIONTYPE; - col = lwcollection_construct(newtype, to->ndims, to->SRID, - (what->hasbbox || to->hasbbox ), 2, geoms); + col = lwcollection_construct(newtype, TYPE_NDIMS(to->type), to->SRID, + ( TYPE_HASBBOX(what->type) || TYPE_HASBBOX(to->type) ), + 2, geoms); return (LWGEOM *)col; } diff --git a/lwgeom/wktunparse.c b/lwgeom/wktunparse.c index cf4084313..c1e4841e1 100644 --- a/lwgeom/wktunparse.c +++ b/lwgeom/wktunparse.c @@ -16,6 +16,7 @@ #include #include +#include "liblwgeom.h" static int endian_check_int = 1; // dont modify this!!! @@ -213,21 +214,27 @@ byte* output_multipoint(byte* geom,int suppress){ return output_wkt(geom,suppress); } -byte* output_wkt(byte* geom, int supress){ +byte * +output_wkt(byte* geom, int supress) +{ unsigned type=*geom++; - dims = ((type & 0x30) >> 4)+2; + dims = TYPE_NDIMS(type); //((type & 0x30) >> 4)+2; //Skip the bounding box if there is one - if ( type & 0x80 ){ + //if ( type & 0x80 ){ + if ( TYPE_HASBBOX(type) ) + { geom+=16; } - if ( type & 0x40 ){ + //if ( type & 0x40 ){ + if ( TYPE_HASSRID(type) ) { write_str("SRID=");write_int(read_int(&geom));write_str(";"); } - switch(type & 0x0F){ + //switch(type & 0x0F){ + switch(TYPE_GETTYPE(type)) { case POINTTYPE: if ( ! supress) write_str("POINT"); geom=output_single(geom,0); @@ -279,7 +286,9 @@ byte* output_wkt(byte* geom, int supress){ return geom; } -char* unparse_WKT(byte* lw_geom,allocator alloc,freeor free){ +char * +unparse_WKT(byte* lw_geom, allocator alloc, freeor free) +{ if (lw_geom==NULL) return NULL; @@ -290,7 +299,7 @@ char* unparse_WKT(byte* lw_geom,allocator alloc,freeor free){ out_start = out_pos = alloc(len); lwgi=0; - output_wkt(lw_geom+4,0); + output_wkt(lw_geom+4, 0); return out_start; } @@ -307,7 +316,9 @@ void write_wkb_bytes(byte* ptr,int cnt){ } } -byte* output_wkb_point(byte* geom){ +byte * +output_wkb_point(byte* geom) +{ if ( lwgi ){ write_wkb_bytes(geom,dims*4); return geom + (4*dims); @@ -318,43 +329,50 @@ byte* output_wkb_point(byte* geom){ } } -void write_wkb_int(int i){ +void +write_wkb_int(int i){ write_wkb_bytes((byte*)&i,4); } -byte* output_wkb_collection(byte* geom,outwkbfunc func){ +byte * +output_wkb_collection(byte* geom,outwkbfunc func){ int cnt = read_int(&geom); write_wkb_int(cnt); while(cnt--) geom=func(geom); return geom; } -byte* output_wkb_collection_2(byte* geom){ +byte * +output_wkb_collection_2(byte* geom){ return output_wkb_collection(geom,output_wkb_point); } -byte* output_wkb(byte* geom){ +byte * +output_wkb(byte* geom) +{ - int4 type=*geom++; + unsigned char type=*geom++; + int4 wkbtype; - dims = ((type & 0x30) >> 4)+2; + dims = TYPE_NDIMS(type); //Skip the bounding box - if ( type & 0x80 ){ + if ( TYPE_HASBBOX(type) ) { geom+=16; } - if ( type & 0x40 ){ + if ( TYPE_HASSRID(type) ) { write_str("SRID=");write_int(read_int(&geom));write_str(";"); } - type &=0x0f; + //type&=0x0f; + wkbtype = TYPE_GETTYPE(type); - if ( dims==3) - type |=0x80000000; - else if (dims==4) - type |=0x40000000; + if ( TYPE_HASZ(type) ) + wkbtype |= WKBZOFFSET; + if ( TYPE_HASM(type) ) + wkbtype |= WKBMOFFSET; if ( getMachineEndian() != LITTLE_ENDIAN_CHECK ){ byte endian=0; @@ -365,9 +383,9 @@ byte* output_wkb(byte* geom){ write_wkb_bytes(&endian,1); } - write_wkb_int(type); + write_wkb_int(wkbtype); - switch(type & 0x0F){ + switch(TYPE_GETTYPE(type)){ case POINTTYPE: geom=output_wkb_point(geom); break;