From: Sandro Santilli Date: Thu, 30 Sep 2004 15:42:28 +0000 (+0000) Subject: Added BBOX finders and its support in serializer. X-Git-Tag: pgis_1_0_0RC1~357 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f3e6e82ff3cecd96e81947ecb90200934d0a52ea;p=postgis Added BBOX finders and its support in serializer. git-svn-id: http://svn.osgeo.org/postgis/trunk@915 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/lwgeom/TODO b/lwgeom/TODO index 489042357..12dd6dbac 100644 --- a/lwgeom/TODO +++ b/lwgeom/TODO @@ -1,4 +1,3 @@ -- serialize, serialize_size needs to check for hasbbox (wantbbox) flag - Flatten(geometry) diff --git a/lwgeom/liblwgeom.h b/lwgeom/liblwgeom.h index a9cc9cc63..bf0ba3e8c 100644 --- a/lwgeom/liblwgeom.h +++ b/lwgeom/liblwgeom.h @@ -463,21 +463,10 @@ extern BOX3D *lwpoly_findbbox(LWPOLY *poly); //-------------------------------------------------------- -extern size_t lwmpoint_serialize_size(LWMPOINT *mpoint); -extern void lwmpoint_serialize_buf(LWMPOINT *mpoint, char *buf, int *size); - -extern size_t lwmline_serialize_size(LWMLINE *mline); -extern void lwmline_serialize_buf(LWMLINE *mline, char *buf, int *size); - -extern size_t lwmpoly_serialize_size(LWMPOLY *mpoly); -extern void lwmpoly_serialize_buf(LWMPOLY *mpoly, char *buf, int *size); - - extern size_t lwgeom_serialize_size(LWGEOM *geom); -extern void lwgeom_serialize_buf(LWGEOM *geom, char *buf, int *size); -extern char *lwgeom_serialize(LWGEOM *geom, char wantbbox); - extern size_t lwcollection_serialize_size(LWCOLLECTION *coll); +extern void lwgeom_serialize_buf(LWGEOM *geom, char *buf, int *size); +extern char *lwgeom_serialize(LWGEOM *geom); extern void lwcollection_serialize_buf(LWCOLLECTION *mcoll, char *buf, int *size); LWGEOM *lwgeom_deserialize(char *serializedform); @@ -889,5 +878,15 @@ extern void lwpoly_forceRHR(LWPOLY *poly); extern void lwgeom_forceRHR(LWGEOM *lwgeom); extern char *lwgeom_summary(LWGEOM *lwgeom, int offset); extern const char *lwgeom_typename(int type); +extern int ptarray_compute_bbox_p(const POINTARRAY *pa, BOX2DFLOAT4 *result); +extern int lwpoint_compute_bbox_p(LWPOINT *point, BOX2DFLOAT4 *box); +extern int lwline_compute_bbox_p(LWLINE *line, BOX2DFLOAT4 *box); +extern int lwpoly_compute_bbox_p(LWPOLY *poly, BOX2DFLOAT4 *box); +extern int lwcollection_compute_bbox_p(LWCOLLECTION *col, BOX2DFLOAT4 *box); +// return alloced memory +extern BOX2DFLOAT4 *box2d_union(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2); +// args may overlap ! +extern int box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox); +extern int lwgeom_compute_bbox_p(LWGEOM *lwgeom, BOX2DFLOAT4 *box); #endif // !defined _LIBLWGEOM_H diff --git a/lwgeom/lwcollection.c b/lwgeom/lwcollection.c index d0d6d0c4b..076bd582c 100644 --- a/lwgeom/lwcollection.c +++ b/lwgeom/lwcollection.c @@ -51,6 +51,7 @@ lwcollection_serialize_size(LWCOLLECTION *col) int i; if ( col->SRID != -1 ) size += 4; // SRID + if ( col->hasbbox ) size += sizeof(BOX2DFLOAT4); for (i=0; ingeoms; i++) size += lwgeom_serialize_size(lwcollection_getsubgeom(col, i)); @@ -76,6 +77,14 @@ lwcollection_serialize_buf(LWCOLLECTION *coll, char *buf, int *retsize) hasSRID, COLLECTIONTYPE); loc = buf+1; + // Add BBOX if requested + if ( coll->hasbbox ) + { + lwgeom_compute_bbox_p((LWGEOM *)coll, (BOX2DFLOAT4 *)loc); + size += sizeof(BOX2DFLOAT4); + loc += sizeof(BOX2DFLOAT4); + } + // Add SRID if requested if (hasSRID) { @@ -98,3 +107,19 @@ lwcollection_serialize_buf(LWCOLLECTION *coll, char *buf, int *retsize) if (retsize) *retsize = size; } + +int +lwcollection_compute_bbox_p(LWCOLLECTION *col, BOX2DFLOAT4 *box) +{ + BOX2DFLOAT4 boxbuf; + uint32 i; + + if ( ! col->ngeoms ) return 0; + if ( ! lwgeom_compute_bbox_p(col->geoms[0], box) ) return 0; + for (i=1; ingeoms; i++) + { + if ( ! lwgeom_compute_bbox_p(col->geoms[i], &boxbuf) ) return 0; + if ( ! box2d_union_p(box, &boxbuf, box) ) return 0; + } + return 1; +} diff --git a/lwgeom/lwgeom.c b/lwgeom/lwgeom.c index 67e599785..6f01ad70e 100644 --- a/lwgeom/lwgeom.c +++ b/lwgeom/lwgeom.c @@ -48,11 +48,8 @@ lwgeom_serialize_size(LWGEOM *lwgeom) case POLYGONTYPE: size = lwpoly_serialize_size((LWPOLY *)lwgeom); case MULTIPOINTTYPE: - size = lwmpoint_serialize_size((LWMPOINT *)lwgeom); case MULTILINETYPE: - size = lwmline_serialize_size((LWMLINE *)lwgeom); case MULTIPOLYGONTYPE: - size = lwmpoly_serialize_size((LWMPOLY *)lwgeom); case COLLECTIONTYPE: size = lwcollection_serialize_size((LWCOLLECTION *)lwgeom); default: @@ -67,57 +64,42 @@ void lwgeom_serialize_buf(LWGEOM *lwgeom, char *buf, int *retsize) { int type = lwgeom->type; - int size; switch (type) { case POINTTYPE: - lwpoint_serialize_buf((LWPOINT *)lwgeom, buf, &size); + lwpoint_serialize_buf((LWPOINT *)lwgeom, buf, retsize); break; case LINETYPE: - lwline_serialize_buf((LWLINE *)lwgeom, buf, &size); + lwline_serialize_buf((LWLINE *)lwgeom, buf, retsize); break; case POLYGONTYPE: - lwpoly_serialize_buf((LWPOLY *)lwgeom, buf, &size); + lwpoly_serialize_buf((LWPOLY *)lwgeom, buf, retsize); break; case MULTIPOINTTYPE: - lwmpoint_serialize_buf((LWMPOINT *)lwgeom, buf, &size); - break; case MULTILINETYPE: - lwmline_serialize_buf((LWMLINE *)lwgeom, buf, &size); - break; case MULTIPOLYGONTYPE: - lwmpoly_serialize_buf((LWMPOLY *)lwgeom, buf, &size); - break; case COLLECTIONTYPE: - lwcollection_serialize_buf((LWCOLLECTION *)lwgeom, buf, &size); + lwcollection_serialize_buf((LWCOLLECTION *)lwgeom, buf, + retsize); break; default: lwerror("Unknown geometry type: %d", type); return; } - *retsize = size; return; } char * -lwgeom_serialize(LWGEOM *lwgeom, char wantbbox) +lwgeom_serialize(LWGEOM *lwgeom) { size_t size = lwgeom_serialize_size(lwgeom); size_t retsize; - char *loc; - - if ( wantbbox ) size += sizeof(BOX2DFLOAT4); - char *serialized = lwalloc(size); - if ( wantbbox ) loc = serialized + sizeof(BOX2DFLOAT4); - else loc = serialized; - - lwgeom_serialize_buf(lwgeom, loc, &retsize); + lwgeom_serialize_buf(lwgeom, serialized, &retsize); #ifdef DEBUG - if ( wantbbox ) retsize += 4; if ( retsize != size ) { lwerror("lwgeom_serialize: computed size %d, returned size %d", @@ -175,3 +157,31 @@ lwgeom_reverse(LWGEOM *lwgeom) } } +int +lwgeom_compute_bbox_p(LWGEOM *lwgeom, BOX2DFLOAT4 *buf) +{ + switch(lwgeom->type) + { + case POINTTYPE: + return lwpoint_compute_bbox_p((LWPOINT *)lwgeom, buf); + case LINETYPE: + return lwline_compute_bbox_p((LWLINE *)lwgeom, buf); + case POLYGONTYPE: + return lwpoly_compute_bbox_p((LWPOLY *)lwgeom, buf); + case MULTIPOINTTYPE: + case MULTILINETYPE: + case MULTIPOLYGONTYPE: + case COLLECTIONTYPE: + return lwcollection_compute_bbox_p((LWCOLLECTION *)lwgeom, buf); + } + return 0; +} + +//dont forget to lwfree() result +BOX2DFLOAT4 * +lwgeom_compute_bbox(LWGEOM *lwgeom) +{ + BOX2DFLOAT4 *result = lwalloc(sizeof(BOX2DFLOAT4)); + if ( lwgeom_compute_bbox_p(lwgeom, result) ) return result; + else return NULL; +} diff --git a/lwgeom/lwgeom_api.c b/lwgeom/lwgeom_api.c index fa159481e..4f7c98246 100644 --- a/lwgeom/lwgeom_api.c +++ b/lwgeom/lwgeom_api.c @@ -720,6 +720,36 @@ BOX3D *pointArray_bbox(const POINTARRAY *pa) return result; } +// calculate the 2d bounding box of a set of points +// write result to the provided BOX2DFLOAT4 +// Return 0 if bounding box is NULL (empty geom) +int +ptarray_compute_bbox_p(const POINTARRAY *pa, BOX2DFLOAT4 *result) +{ + int t; + POINT2D *pt; + + if (pa->npoints == 0) return 0; + + pt = (POINT2D *)getPoint(pa, 0); + + result->xmin = pt->x; + result->xmax = pt->x; + result->ymin = pt->y; + result->ymax = pt->y; + + for (t=1;tnpoints;t++) + { + pt = (POINT2D *)getPoint(pa, t); + if (pt->x < result->xmin) result->xmin = pt->x; + if (pt->y < result->ymin) result->ymin = pt->y; + if (pt->x > result->xmax) result->xmax = pt->x; + if (pt->y > result->ymax) result->ymax = pt->y; + } + + return 1; +} + //size of point represeneted in the POINTARRAY // 16 for 2d, 24 for 3d, 32 for 4d int @@ -2530,3 +2560,82 @@ ptarray_isccw(const POINTARRAY *pa) else return 1; } +// returns a BOX2DFLOAT4 that encloses b1 and b2 +// combine_boxes(NULL,A) --> A +// combine_boxes(A,NULL) --> A +// combine_boxes(A,B) --> A union B +BOX2DFLOAT4 * +box2d_union(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2) +{ + BOX2DFLOAT4 *result; + + if ( (b1 == NULL) && (b2 == NULL) ) + { + return NULL; + } + + result = lwalloc(sizeof(BOX2DFLOAT4)); + + if (b1 == NULL) + { + memcpy(result, b2, sizeof(BOX3D)); + return result; + } + if (b2 == NULL) + { + memcpy(result, b1, sizeof(BOX3D)); + return result; + } + + if (b1->xmin < b2->xmin) result->xmin = b1->xmin; + else result->xmin = b2->xmin; + + if (b1->ymin < b2->ymin) result->ymin = b1->ymin; + else result->ymin = b2->ymin; + + if (b1->xmax > b2->xmax) result->xmax = b1->xmax; + else result->xmax = b2->xmax; + + if (b1->ymax > b2->ymax) result->ymax = b1->ymax; + else result->ymax = b2->ymax; + + return result; +} + +// combine_boxes(NULL,A) --> A +// combine_boxes(A,NULL) --> A +// combine_boxes(A,B) --> A union B +// ubox may be one of the two args... +int +box2d_union_p(BOX2DFLOAT4 *b1, BOX2DFLOAT4 *b2, BOX2DFLOAT4 *ubox) +{ + if ( (b1 == NULL) && (b2 == NULL) ) + { + return 0; + } + + if (b1 == NULL) + { + memcpy(ubox, b2, sizeof(BOX3D)); + return 1; + } + if (b2 == NULL) + { + memcpy(ubox, b1, sizeof(BOX3D)); + return 1; + } + + if (b1->xmin < b2->xmin) ubox->xmin = b1->xmin; + else ubox->xmin = b2->xmin; + + if (b1->ymin < b2->ymin) ubox->ymin = b1->ymin; + else ubox->ymin = b2->ymin; + + if (b1->xmax > b2->xmax) ubox->xmax = b1->xmax; + else ubox->xmax = b2->xmax; + + if (b1->ymax > b2->ymax) ubox->ymax = b1->ymax; + else ubox->ymax = b2->ymax; + + return 1; +} diff --git a/lwgeom/lwgeom_box2dfloat4.c b/lwgeom/lwgeom_box2dfloat4.c index 48ba0ed7c..752afe43b 100644 --- a/lwgeom/lwgeom_box2dfloat4.c +++ b/lwgeom/lwgeom_box2dfloat4.c @@ -263,21 +263,15 @@ Datum box2d_inter(PG_FUNCTION_ARGS) //union of two BOX2Ds -PG_FUNCTION_INFO_V1(box2d_union); -Datum box2d_union(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(BOX2D_union); +Datum BOX2D_union(PG_FUNCTION_ARGS) { - BOX2DFLOAT4 *a = (BOX2DFLOAT4*) PG_GETARG_POINTER(0); - BOX2DFLOAT4 *b = (BOX2DFLOAT4*) PG_GETARG_POINTER(1); - BOX2DFLOAT4 *n; - - n = (BOX2DFLOAT4 *) palloc(sizeof(BOX2DFLOAT4)); - - n->xmax = LWGEOM_Maxf(a->xmax, b->xmax); - n->ymax = LWGEOM_Maxf(a->ymax, b->ymax); - n->xmin = LWGEOM_Minf(a->xmin, b->xmin); - n->ymin = LWGEOM_Minf(a->ymin, b->ymin); - + BOX2DFLOAT4 *a = (BOX2DFLOAT4*) PG_GETARG_POINTER(0); + BOX2DFLOAT4 *b = (BOX2DFLOAT4*) PG_GETARG_POINTER(1); + BOX2DFLOAT4 *n; + n = (BOX2DFLOAT4 *) lwalloc(sizeof(BOX2DFLOAT4)); + if ( ! box2d_union_p(a,b,n) ) PG_RETURN_NULL(); PG_RETURN_POINTER(n); } diff --git a/lwgeom/lwgeom_gist.c b/lwgeom/lwgeom_gist.c index 349a12517..41c567ed4 100644 --- a/lwgeom/lwgeom_gist.c +++ b/lwgeom/lwgeom_gist.c @@ -712,7 +712,8 @@ Datum lwgeom_box_penalty(PG_FUNCTION_ARGS) #endif - ud = DirectFunctionCall2(box2d_union, origentry->key, newentry->key); + ud = DirectFunctionCall2(BOX2D_union, origentry->key, newentry->key); + //ud = box2d_union(origentry->key, newentry->key); tmp1 = size_box2d_double(ud); if (DatumGetPointer(ud) != NULL) pfree(DatumGetPointer(ud)); @@ -733,7 +734,8 @@ Datum lwgeom_box_penalty(PG_FUNCTION_ARGS) BOX2DFLOAT4 *a, *b,*c; a = (BOX2DFLOAT4*) DatumGetPointer(origentry->key); b = (BOX2DFLOAT4*) DatumGetPointer(newentry->key); - c = (BOX2DFLOAT4*) DatumGetPointer(DirectFunctionCall2(box2d_union, origentry->key, newentry->key)); + //c = (BOX2DFLOAT4*) DatumGetPointer(DirectFunctionCall2(box2d_union, origentry->key, newentry->key)); + c = box2d_union(origentry->key, newentry->key); //elog(NOTICE,"lwgeom_box_penalty -- a = <%.16g %.16g,%.16g %.16g>", a->xmin, a->ymin, a->xmax, a->ymax); //elog(NOTICE,"lwgeom_box_penalty -- b = <%.16g %.16g,%.16g %.16g>", b->xmin, b->ymin, b->xmax, b->ymax); //elog(NOTICE,"lwgeom_box_penalty -- c = <%.16g %.16g,%.16g %.16g>", c->xmin, c->ymin, c->xmax, c->ymax); diff --git a/lwgeom/lwgeom_pg.h b/lwgeom/lwgeom_pg.h index 8f04f47aa..ed4631141 100644 --- a/lwgeom/lwgeom_pg.h +++ b/lwgeom/lwgeom_pg.h @@ -29,7 +29,7 @@ Datum box2d_overright(PG_FUNCTION_ARGS); Datum box2d_contained(PG_FUNCTION_ARGS); Datum box2d_contain(PG_FUNCTION_ARGS); Datum box2d_inter(PG_FUNCTION_ARGS); -Datum box2d_union(PG_FUNCTION_ARGS); +Datum BOX2D_union(PG_FUNCTION_ARGS); Datum gist_lwgeom_compress(PG_FUNCTION_ARGS); Datum gist_lwgeom_consistent(PG_FUNCTION_ARGS); diff --git a/lwgeom/lwline.c b/lwgeom/lwline.c index 7999711c1..df8ff1e6c 100644 --- a/lwgeom/lwline.c +++ b/lwgeom/lwline.c @@ -86,78 +86,20 @@ LWLINE *lwline_deserialize(char *serialized_form) // result's first char will be the 8bit type. See serialized form doc char *lwline_serialize(LWLINE *line) { - int size=1; // type byte - char hasSRID; - unsigned char * result; - int t; - char *loc; - -if (line == NULL) - lwerror("lwline_serialize:: given null line"); - - hasSRID = (line->SRID != -1); - - if (hasSRID) - size +=4; //4 byte SRID - - if (line->ndims == 3) - { - size += 24 * line->points->npoints; //x,y,z - } - else if (line->ndims == 2) - { - size += 16 * line->points->npoints; //x,y - } - else if (line->ndims == 4) - { - size += 32 * line->points->npoints; //x,y - } + size_t size, retsize; + char * result; + if (line == NULL) lwerror("lwline_serialize:: given null line"); - size+=4; // npoints - + size = lwline_serialize_size(line); result = lwalloc(size); + lwline_serialize_buf(line, result, &retsize); - result[0] = (unsigned char) lwgeom_makeType(line->ndims,hasSRID, LINETYPE); - loc = result+1; - - if (hasSRID) + if ( retsize != size ) { - memcpy(loc, &line->SRID, sizeof(int32)); - loc += 4; + lwerror("lwline_serialize_size returned %d, ..serialize_buf returned %d", size, retsize); } - memcpy(loc, &line->points->npoints, sizeof(int32)); - loc +=4; - //copy in points - -//lwnotice(" line serialize - size = %i", size); - - if (line->ndims == 3) - { - for (t=0; t< line->points->npoints;t++) - { - getPoint3d_p(line->points, t, loc); - loc += 24; // size of a 3d point - } - } - else if (line->ndims == 2) - { - for (t=0; t< line->points->npoints;t++) - { - getPoint2d_p(line->points, t, loc); - loc += 16; // size of a 2d point - } - } - else if (line->ndims == 4) - { - for (t=0; t< line->points->npoints;t++) - { - getPoint4d_p(line->points, t, loc); - loc += 32; // size of a 2d point - } - } - //printBYTES((unsigned char *)result, size); return result; } @@ -171,6 +113,7 @@ void lwline_serialize_buf(LWLINE *line, char *buf, int *retsize) char hasSRID; int t; char *loc; + int ptsize = sizeof(double)*line->ndims; if (line == NULL) lwerror("lwline_serialize:: given null line"); @@ -178,26 +121,21 @@ void lwline_serialize_buf(LWLINE *line, char *buf, int *retsize) hasSRID = (line->SRID != -1); if (hasSRID) size +=4; //4 byte SRID - - if (line->ndims == 3) - { - size += 24 * line->points->npoints; //x,y,z - } - else if (line->ndims == 2) - { - size += 16 * line->points->npoints; //x,y - } - else if (line->ndims == 4) - { - size += 32 * line->points->npoints; //x,y - } + if (line->hasbbox) size += sizeof(BOX2DFLOAT4); // bvol + size += ptsize * line->points->npoints; size+=4; // npoints - buf[0] = (unsigned char) lwgeom_makeType(line->ndims, - hasSRID, LINETYPE); + buf[0] = (unsigned char) lwgeom_makeType_full(line->ndims, + hasSRID, LINETYPE, line->hasbbox); loc = buf+1; + if (line->hasbbox) + { + lwgeom_compute_bbox_p((LWGEOM *)line, (BOX2DFLOAT4 *)loc); + loc += sizeof(BOX2DFLOAT4); + } + if (hasSRID) { memcpy(loc, &line->SRID, sizeof(int32)); @@ -258,6 +196,8 @@ lwline_serialize_size(LWLINE *line) size_t size = 1; //type if ( line->SRID != -1 ) size += 4; // SRID + if ( line->hasbbox ) size += sizeof(BOX2DFLOAT4); + size += sizeof(double)*line->ndims*line->points->npoints; // points return size; @@ -326,3 +266,8 @@ void printLWLINE(LWLINE *line) lwnotice("}"); } +int +lwline_compute_bbox_p(LWLINE *line, BOX2DFLOAT4 *box) +{ + return ptarray_compute_bbox_p(line->points, box); +} diff --git a/lwgeom/lwmline.c b/lwgeom/lwmline.c index 17886c973..d6002118a 100644 --- a/lwgeom/lwmline.c +++ b/lwgeom/lwmline.c @@ -42,58 +42,3 @@ lwmline_deserialize(char *srl) return result; } -// find serialized size of this mline -size_t -lwmline_serialize_size(LWMLINE *mline) -{ - size_t size = 5; // type + nsubgeoms - int i; - - if ( mline->SRID != -1 ) size += 4; // SRID - - for (i=0; ingeoms; i++) - size += lwline_serialize_size(mline->geoms[i]); - - return size; -} - -// convert this multiline into its serialize form writing it into -// the given buffer, and returning number of bytes written into -// the given int pointer. -void -lwmline_serialize_buf(LWMLINE *mline, char *buf, int *retsize) -{ - int size=1; // type - int subsize=0; - char hasSRID; - char *loc; - int i; - - hasSRID = (mline->SRID != -1); - - buf[0] = (unsigned char) lwgeom_makeType(mline->ndims, - hasSRID, MULTILINETYPE); - loc = buf+1; - - // Add SRID if requested - if (hasSRID) - { - memcpy(loc, &mline->SRID, 4); - size += 4; - loc += 4; - } - - // Write number of subgeoms - memcpy(loc, &mline->ngeoms, 4); - size += 4; - loc += 4; - - // Serialize subgeoms - for (i=0; ingeoms; i++) - { - lwline_serialize_buf(mline->geoms[i], loc, &subsize); - size += subsize; - } - - if (retsize) *retsize = size; -} diff --git a/lwgeom/lwmpoint.c b/lwgeom/lwmpoint.c index 0417d1111..b8413f37d 100644 --- a/lwgeom/lwmpoint.c +++ b/lwgeom/lwmpoint.c @@ -42,58 +42,3 @@ lwmpoint_deserialize(char *srl) return result; } -// find serialized size of this mpoint -size_t -lwmpoint_serialize_size(LWMPOINT *mpoint) -{ - size_t size = 5; // type + nsubgeoms - int i; - - if ( mpoint->SRID != -1 ) size += 4; // SRID - - for (i=0; ingeoms; i++) - size += lwpoint_serialize_size(mpoint->geoms[i]); - - return size; -} - -// convert this multipoint into its serialize form writing it into -// the given buffer, and returning number of bytes written into -// the given int pointer. -void -lwmpoint_serialize_buf(LWMPOINT *mpoint, char *buf, int *retsize) -{ - int size=1; // type - int subsize=0; - char hasSRID; - char *loc; - int i; - - hasSRID = (mpoint->SRID != -1); - - buf[0] = (unsigned char) lwgeom_makeType(mpoint->ndims, - hasSRID, MULTIPOINTTYPE); - loc = buf+1; - - // Add SRID if requested - if (hasSRID) - { - memcpy(loc, &mpoint->SRID, 4); - size += 4; - loc += 4; - } - - // Write number of subgeoms - memcpy(loc, &mpoint->ngeoms, 4); - size += 4; - loc += 4; - - // Serialize subgeoms - for (i=0; ingeoms; i++) - { - lwpoint_serialize_buf(mpoint->geoms[i], loc, &subsize); - size += subsize; - } - - if (retsize) *retsize = size; -} diff --git a/lwgeom/lwmpoly.c b/lwgeom/lwmpoly.c index bb1faf983..dfb4edded 100644 --- a/lwgeom/lwmpoly.c +++ b/lwgeom/lwmpoly.c @@ -48,58 +48,3 @@ lwmpoly_deserialize(char *srl) return result; } -// find serialized size of this mpoly -size_t -lwmpoly_serialize_size(LWMPOLY *mpoly) -{ - size_t size = 5; // type + nsubgeoms - int i; - - if ( mpoly->SRID != -1 ) size += 4; // SRID - - for (i=0; ingeoms; i++) - size += lwpoly_serialize_size(mpoly->geoms[i]); - - return size; -} - -// convert this multipolygon into its serialize form writing it into -// the given buffer, and returning number of bytes written into -// the given int pointer. -void -lwmpoly_serialize_buf(LWMPOLY *mpoly, char *buf, int *retsize) -{ - int size=1; // type - int subsize=0; - char hasSRID; - char *loc; - int i; - - hasSRID = (mpoly->SRID != -1); - - buf[0] = (unsigned char) lwgeom_makeType(mpoly->ndims, - hasSRID, MULTIPOLYGONTYPE); - loc = buf+1; - - // Add SRID if requested - if (hasSRID) - { - memcpy(loc, &mpoly->SRID, 4); - size += 4; - loc += 4; - } - - // Write number of subgeoms - memcpy(loc, &mpoly->ngeoms, 4); - size += 4; - loc += 4; - - // Serialize subgeoms - for (i=0; ingeoms; i++) - { - lwpoly_serialize_buf(mpoly->geoms[i], loc, &subsize); - size += subsize; - } - - if (retsize) *retsize = size; -} diff --git a/lwgeom/lwpoint.c b/lwgeom/lwpoint.c index a50b0f59e..d6a29c4ba 100644 --- a/lwgeom/lwpoint.c +++ b/lwgeom/lwpoint.c @@ -8,36 +8,18 @@ char * lwpoint_serialize(LWPOINT *point) { - int size=1; - char hasSRID; + size_t size, retsize; char *result; - char *loc; - - hasSRID = (point->SRID != -1); - - if (hasSRID) size +=4; //4 byte SRID - - if (point->ndims == 3) size += 24; //x,y,z - else if (point->ndims == 2) size += 16 ; //x,y,z - else if (point->ndims == 4) size += 32 ; //x,y,z,m + size = lwpoint_serialize_size(point); result = lwalloc(size); + lwpoint_serialize_buf(point, result, &retsize); - result[0] = (unsigned char) lwgeom_makeType(point->ndims, - hasSRID, POINTTYPE); - loc = result+1; - - if (hasSRID) + if ( retsize != size ) { - memcpy(loc, &point->SRID, sizeof(int32)); - loc += 4; + lwerror("lwpoint_serialize_size returned %d, ..serialize_buf returned %d", size, 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); return result; } @@ -55,15 +37,22 @@ lwpoint_serialize_buf(LWPOINT *point, char *buf, int *retsize) hasSRID = (point->SRID != -1); if (hasSRID) size +=4; //4 byte SRID + if (point->hasbbox) size += sizeof(BOX2DFLOAT4); // bvol if (point->ndims == 3) size += 24; //x,y,z else if (point->ndims == 2) size += 16 ; //x,y,z else if (point->ndims == 4) size += 32 ; //x,y,z,m - buf[0] = (unsigned char) lwgeom_makeType(point->ndims, - hasSRID, POINTTYPE); + buf[0] = (unsigned char) lwgeom_makeType_full(point->ndims, + hasSRID, POINTTYPE, point->hasbbox); loc = buf+1; + if (point->hasbbox) + { + lwgeom_compute_bbox_p((LWGEOM *)point, (BOX2DFLOAT4 *)loc); + loc += sizeof(BOX2DFLOAT4); + } + if (hasSRID) { memcpy(loc, &point->SRID, sizeof(int32)); @@ -133,6 +122,8 @@ lwpoint_serialize_size(LWPOINT *point) size_t size = 1; // type if ( point->SRID != -1 ) size += 4; // SRID + if ( point->hasbbox ) size += sizeof(BOX2DFLOAT4); + size += point->ndims * sizeof(double); // point return size; @@ -232,3 +223,8 @@ void printLWPOINT(LWPOINT *point) lwnotice("}"); } +int +lwpoint_compute_bbox_p(LWPOINT *point, BOX2DFLOAT4 *box) +{ + return ptarray_compute_bbox_p(point->point, box); +} diff --git a/lwgeom/lwpoly.c b/lwgeom/lwpoly.c index 76b6b04fd..0d8a3f397 100644 --- a/lwgeom/lwpoly.c +++ b/lwgeom/lwpoly.c @@ -113,80 +113,16 @@ lwpoly_deserialize(char *serialized_form) char * lwpoly_serialize(LWPOLY *poly) { - int size=1; // type byte - char hasSRID; + size_t size, retsize; char *result; - int t,u; - int total_points = 0; - int npoints; - char *loc; - - hasSRID = (poly->SRID != -1); - - if (hasSRID) - size +=4; //4 byte SRID - - size += 4; // nrings - size += 4*poly->nrings; //npoints/ring - - - for (t=0;tnrings;t++) - { - total_points += poly->rings[t]->npoints; - } - if (poly->ndims == 3) - size += 24*total_points; - else if (poly->ndims == 2) - size += 16*total_points; - else if (poly->ndims == 4) - size += 32*total_points; + size = lwpoly_serialize_size(poly); result = lwalloc(size); - - result[0] = (unsigned char) lwgeom_makeType(poly->ndims,hasSRID, POLYGONTYPE); - loc = result+1; - - if (hasSRID) + lwpoly_serialize_buf(poly, result, &retsize); + + if ( retsize != size ) { - memcpy(loc, &poly->SRID, sizeof(int32)); - loc += 4; - } - - memcpy(loc, &poly->nrings, sizeof(int32)); // nrings - loc+=4; - - - - for (t=0;tnrings;t++) - { - POINTARRAY *pa = poly->rings[t]; - npoints = poly->rings[t]->npoints; - memcpy(loc, &npoints, sizeof(int32)); //npoints this ring - loc+=4; - if (poly->ndims == 3) - { - for (u=0;undims == 2) - { - for (u=0;undims == 4) - { - for (u=0;uSRID != -1); - if (hasSRID) size +=4; //4 byte SRID - size += 4; // nrings size += 4*poly->nrings; //npoints/ring - for (t=0;tnrings;t++) - { + for (t=0;tnrings;t++) { total_points += poly->rings[t]->npoints; } - if (poly->ndims == 3) size += 24*total_points; - else if (poly->ndims == 2) size += 16*total_points; - else if (poly->ndims == 4) size += 32*total_points; + size += sizeof(double)*poly->ndims*total_points; - buf[0] = (unsigned char) lwgeom_makeType(poly->ndims, - hasSRID, POLYGONTYPE); + buf[0] = (unsigned char) lwgeom_makeType_full(poly->ndims, + hasSRID, POLYGONTYPE, poly->hasbbox); loc = buf+1; + if (poly->hasbbox) + { + lwgeom_compute_bbox_p((LWGEOM *)poly, (BOX2DFLOAT4 *)loc); + size += sizeof(BOX2DFLOAT4); // bvol + loc += sizeof(BOX2DFLOAT4); + } + if (hasSRID) { memcpy(loc, &poly->SRID, sizeof(int32)); loc += 4; + size +=4; //4 byte SRID } memcpy(loc, &poly->nrings, sizeof(int32)); // nrings @@ -380,6 +319,7 @@ lwpoly_serialize_size(LWPOLY *poly) uint32 i; if ( poly->SRID != -1 ) size += 4; // SRID + if ( poly->hasbbox ) size += sizeof(BOX2DFLOAT4); size += 4; // nrings @@ -419,3 +359,20 @@ void printLWPOLY(LWPOLY *poly) lwnotice("}"); } +int +lwpoly_compute_bbox_p(LWPOLY *poly, BOX2DFLOAT4 *box) +{ + BOX2DFLOAT4 boxbuf; + uint32 i; + + if ( ! poly->nrings ) return 0; + if ( ! ptarray_compute_bbox_p(poly->rings[0], box) ) return 0; + for (i=1; inrings; i++) + { + if ( ! ptarray_compute_bbox_p(poly->rings[0], &boxbuf) ) + return 0; + if ( ! box2d_union_p(box, &boxbuf, box) ) + return 0; + } + return 1; +}