diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index 1ea6603bb..18f7b8c53 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -712,13 +712,17 @@ void lwgeom_force2d_recursive(uchar *serialized, uchar *optr, size_t *retsize) { LWGEOM_INSPECTED *inspected; - int i; + int i,j,k; size_t totsize=0; size_t size=0; int type; + uchar newtypefl; LWPOINT *point = NULL; LWLINE *line = NULL; LWPOLY *poly = NULL; + POINTARRAY newpts; + POINTARRAY **nrings; + POINT2D p2d; uchar *loc; @@ -731,10 +735,20 @@ lwgeom_force2d_recursive(uchar *serialized, uchar *optr, size_t *retsize) if ( type == POINTTYPE ) { point = lwpoint_deserialize(serialized); + TYPE_SETZM(newpts.dims, 0, 0); + newpts.npoints = 1; + newpts.serialized_pointlist = lwalloc(sizeof(POINT2D)); + loc = newpts.serialized_pointlist; + getPoint2d_p(point->point, 0, &p2d); + memcpy(loc, &p2d, sizeof(POINT2D)); + point->point = &newpts; TYPE_SETZM(point->type, 0, 0); lwpoint_serialize_buf(point, optr, retsize); + lwfree(newpts.serialized_pointlist); + lwfree(point); + #ifdef PGIS_DEBUG -elog(NOTICE, "lwgeom_force2d_recursive: it's a point, size:%d", *retsize); +lwnotice("lwgeom_force2d_recursive returning"); #endif return; } @@ -742,10 +756,31 @@ elog(NOTICE, "lwgeom_force2d_recursive: it's a point, size:%d", *retsize); if ( type == LINETYPE ) { line = lwline_deserialize(serialized); +#ifdef PGIS_DEBUG +elog(NOTICE, "lwgeom_force2d_recursive: it's a line with %d points", line->points->npoints); +#endif + TYPE_SETZM(newpts.dims, 0, 0); + newpts.npoints = line->points->npoints; + newpts.serialized_pointlist = lwalloc(sizeof(POINT2D)*line->points->npoints); +#ifdef PGIS_DEBUG +elog(NOTICE, "lwgeom_force2d_recursive: %d bytes pointlist allocated", sizeof(POINT2D)*line->points->npoints); +#endif + + loc = newpts.serialized_pointlist; + for (j=0; jpoints->npoints; j++) + { + getPoint2d_p(line->points, j, &p2d); + memcpy(loc, &p2d, sizeof(POINT2D)); + loc+=sizeof(POINT2D); + } + line->points = &newpts; TYPE_SETZM(line->type, 0, 0); lwline_serialize_buf(line, optr, retsize); + lwfree(newpts.serialized_pointlist); + lwfree(line); + #ifdef PGIS_DEBUG -elog(NOTICE, "lwgeom_force2d_recursive: it's a line, size:%d", *retsize); +lwnotice("lwgeom_force2d_recursive returning"); #endif return; } @@ -753,28 +788,72 @@ elog(NOTICE, "lwgeom_force2d_recursive: it's a line, size:%d", *retsize); if ( type == POLYGONTYPE ) { poly = lwpoly_deserialize(serialized); + TYPE_SETZM(newpts.dims, 0, 0); + newpts.npoints = 0; + newpts.serialized_pointlist = lwalloc(1); + nrings = lwalloc(sizeof(POINTARRAY *)*poly->nrings); + loc = newpts.serialized_pointlist; + for (j=0; jnrings; j++) + { + POINTARRAY *ring = poly->rings[j]; + POINTARRAY *nring = lwalloc(sizeof(POINTARRAY)); + TYPE_SETZM(nring->dims, 0, 0); + nring->npoints = ring->npoints; + nring->serialized_pointlist = + lwalloc(ring->npoints*sizeof(POINT2D)); + loc = nring->serialized_pointlist; + for (k=0; knpoints; k++) + { + getPoint2d_p(ring, k, &p2d); + memcpy(loc, &p2d, sizeof(POINT2D)); + loc+=sizeof(POINT2D); + } + nrings[j] = nring; + } + poly->rings = nrings; TYPE_SETZM(poly->type, 0, 0); lwpoly_serialize_buf(poly, optr, retsize); + lwfree(poly); + // TODO: free nrigs[*]->serialized_pointlist + #ifdef PGIS_DEBUG -elog(NOTICE, "lwgeom_force2d_recursive: it's a poly, size:%d", *retsize); +lwnotice("lwgeom_force2d_recursive returning"); #endif return; } + if ( type != MULTIPOINTTYPE && type != MULTIPOLYGONTYPE && + type != MULTILINETYPE && type != COLLECTIONTYPE ) + { + lwerror("lwgeom_force2d_recursive: unknown geometry: %d", + type); + } + // OK, this is a collection, so we write down its metadata // first and then call us again #ifdef PGIS_DEBUG -elog(NOTICE, "lwgeom_force2d_recursive: it's a collection (type:%d)", type); +lwnotice("lwgeom_force2d_recursive: it's a collection (%s)", lwgeom_typename(type)); #endif + // Add type - *optr = lwgeom_makeType_full(0, 0, lwgeom_hasSRID(serialized[0]), + newtypefl = lwgeom_makeType_full(0, 0, lwgeom_hasSRID(serialized[0]), type, lwgeom_hasBBOX(serialized[0])); + optr[0] = newtypefl; optr++; totsize++; loc=serialized+1; +#ifdef PGIS_DEBUG + lwnotice("lwgeom_force2d_recursive: added collection type (%s[%s]) - size:%d", lwgeom_typename(type), lwgeom_typeflags(newtypefl), totsize); +#endif + + if ( lwgeom_hasBBOX(serialized[0]) != lwgeom_hasBBOX(newtypefl) ) + lwerror("typeflag mismatch in BBOX"); + if ( lwgeom_hasSRID(serialized[0]) != lwgeom_hasSRID(newtypefl) ) + lwerror("typeflag mismatch in SRID"); + // Add BBOX if any if (lwgeom_hasBBOX(serialized[0])) { @@ -782,6 +861,9 @@ elog(NOTICE, "lwgeom_force2d_recursive: it's a collection (type:%d)", type); optr += sizeof(BOX2DFLOAT4); totsize += sizeof(BOX2DFLOAT4); loc += sizeof(BOX2DFLOAT4); +#ifdef PGIS_DEBUG + lwnotice("lwgeom_force2d_recursive: added collection bbox - size:%d", totsize); +#endif } // Add SRID if any @@ -791,18 +873,24 @@ elog(NOTICE, "lwgeom_force2d_recursive: it's a collection (type:%d)", type); optr += 4; totsize += 4; loc += 4; +#ifdef PGIS_DEBUG + lwnotice("lwgeom_force2d_recursive: added collection SRID - size:%d", totsize); +#endif } // Add numsubobjects - memcpy(optr, loc, 4); - optr += 4; - totsize += 4; - + memcpy(optr, loc, sizeof(uint32)); + optr += sizeof(uint32); + totsize += sizeof(uint32); + loc += sizeof(uint32); #ifdef PGIS_DEBUG -elog(NOTICE, " collection header size:%d", totsize); + lwnotice("lwgeom_force2d_recursive: added collection ngeoms - size:%d", totsize); #endif - // Now recurse for each suboject +#ifdef PGIS_DEBUG + lwnotice("lwgeom_force2d_recursive: inspecting subgeoms"); +#endif + // Now recurse for each subobject inspected = lwgeom_inspect(serialized); for (i=0; ingeometries; i++) { @@ -811,12 +899,17 @@ elog(NOTICE, " collection header size:%d", totsize); totsize += size; optr += size; #ifdef PGIS_DEBUG -elog(NOTICE, " elem %d size: %d (tot: %d)", i, size, totsize); +lwnotice("lwgeom_force2d_recursive: added elem %d size: %d (tot: %d)", + i, size, totsize); #endif } pfree_inspected(inspected); - *retsize = totsize; +#ifdef PGIS_DEBUG +lwnotice("lwgeom_force2d_recursive returning"); +#endif + + if ( retsize ) *retsize = totsize; } /* @@ -840,6 +933,7 @@ lwgeom_force3dz_recursive(uchar *serialized, uchar *optr, size_t *retsize) POINTARRAY newpts; POINTARRAY **nrings; uchar *loc; + POINT3DZ point3dz; #ifdef PGIS_DEBUG @@ -855,7 +949,8 @@ lwgeom_force3dz_recursive(uchar *serialized, uchar *optr, size_t *retsize) newpts.npoints = 1; newpts.serialized_pointlist = lwalloc(sizeof(POINT3DZ)); loc = newpts.serialized_pointlist; - getPoint3dz_p(point->point, 0, (POINT3DZ *)loc); + getPoint3dz_p(point->point, 0, &point3dz); + memcpy(loc, &point3dz, sizeof(POINT3DZ)); point->point = &newpts; TYPE_SETZM(point->type, 1, 0); lwpoint_serialize_buf(point, optr, retsize); @@ -877,7 +972,8 @@ elog(NOTICE, "lwgeom_force3dz_recursive: it's a line"); loc = newpts.serialized_pointlist; for (j=0; jpoints->npoints; j++) { - getPoint3dz_p(line->points, j, (POINT3DZ *)loc); + getPoint3dz_p(line->points, j, &point3dz); + memcpy(loc, &point3dz, sizeof(POINT3DZ)); loc+=sizeof(POINT3DZ); } line->points = &newpts; @@ -908,7 +1004,8 @@ elog(NOTICE, "lwgeom_force3dz_recursive: it's a line, size:%d", *retsize); loc = nring->serialized_pointlist; for (k=0; knpoints; k++) { - getPoint3dz_p(ring, k, (POINT3DZ *)loc); + getPoint3dz_p(ring, k, &point3dz); + memcpy(loc, &point3dz, sizeof(POINT3DZ)); loc+=sizeof(POINT3DZ); } nrings[j] = nring; @@ -1001,9 +1098,8 @@ lwgeom_force3dm_recursive(uchar *serialized, uchar *optr, size_t *retsize) LWPOLY *poly = NULL; POINTARRAY newpts; POINTARRAY **nrings; - POINT3DM *p3dm; + POINT3DM p3dm; uchar *loc; - char check; #ifdef PGIS_DEBUG @@ -1019,8 +1115,8 @@ lwgeom_force3dm_recursive(uchar *serialized, uchar *optr, size_t *retsize) newpts.npoints = 1; newpts.serialized_pointlist = lwalloc(sizeof(POINT3DM)); loc = newpts.serialized_pointlist; - p3dm = (POINT3DM *)loc; - getPoint3dm_p(point->point, 0, p3dm); + getPoint3dm_p(point->point, 0, &p3dm); + memcpy(loc, &p3dm, sizeof(POINT3DM)); point->point = &newpts; TYPE_SETZM(point->type, 0, 1); lwpoint_serialize_buf(point, optr, retsize); @@ -1047,15 +1143,10 @@ elog(NOTICE, "lwgeom_force3dm_recursive: %d bytes pointlist allocated", sizeof(P #endif loc = newpts.serialized_pointlist; - check = TYPE_NDIMS(line->points->dims); for (j=0; jpoints->npoints; j++) { - getPoint3dm_p(line->points, j, (POINT3DM *)loc); - if ( check != TYPE_NDIMS(line->points->dims) ) - { - lwerror("getPoint3dm_p messed with input pointarray"); - return; - } + getPoint3dm_p(line->points, j, &p3dm); + memcpy(loc, &p3dm, sizeof(POINT3DM)); loc+=sizeof(POINT3DM); } line->points = &newpts; @@ -1089,7 +1180,8 @@ lwnotice("lwgeom_force3dm_recursive returning"); loc = nring->serialized_pointlist; for (k=0; knpoints; k++) { - getPoint3dm_p(ring, k, (POINT3DM *)loc); + getPoint3dm_p(ring, k, &p3dm); + memcpy(loc, &p3dm, sizeof(POINT3DM)); loc+=sizeof(POINT3DM); } nrings[j] = nring; @@ -1216,6 +1308,7 @@ lwgeom_force4d_recursive(uchar *serialized, uchar *optr, size_t *retsize) LWPOLY *poly = NULL; POINTARRAY newpts; POINTARRAY **nrings; + POINT4D p4d; uchar *loc; @@ -1232,7 +1325,8 @@ lwgeom_force4d_recursive(uchar *serialized, uchar *optr, size_t *retsize) newpts.npoints = 1; newpts.serialized_pointlist = lwalloc(sizeof(POINT4D)); loc = newpts.serialized_pointlist; - getPoint4d_p(point->point, 0, (POINT4D *)loc); + getPoint4d_p(point->point, 0, &p4d); + memcpy(loc, &p4d, sizeof(POINT4D)); point->point = &newpts; TYPE_SETZM(point->type, 1, 1); lwpoint_serialize_buf(point, optr, retsize); @@ -1254,7 +1348,8 @@ elog(NOTICE, "lwgeom_force4d_recursive: it's a line"); loc = newpts.serialized_pointlist; for (j=0; jpoints->npoints; j++) { - getPoint4d_p(line->points, j, (POINT4D *)loc); + getPoint4d_p(line->points, j, &p4d); + memcpy(loc, &p4d, sizeof(POINT4D)); loc+=sizeof(POINT4D); } line->points = &newpts; @@ -1285,7 +1380,8 @@ elog(NOTICE, "lwgeom_force4d_recursive: it's a line, size:%d", *retsize); loc = nring->serialized_pointlist; for (k=0; knpoints; k++) { - getPoint4d_p(ring, k, (POINT4D *)loc); + getPoint4d_p(ring, k, &p4d); + memcpy(loc, &p4d, sizeof(POINT4D)); loc+=sizeof(POINT4D); } nrings[j] = nring;