mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-25 01:22:47 +00:00
Flip nrings function from serialized to lwgeom based.
git-svn-id: http://svn.osgeo.org/postgis/trunk@6177 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
parent
d490f9252b
commit
3c8910ea90
|
@ -1549,6 +1549,13 @@ extern int lwgeom_needs_bbox(const LWGEOM *geom);
|
|||
extern int lwgeom_count_vertices(const LWGEOM *geom);
|
||||
extern int lwgeom_npoints(uchar *serialized);
|
||||
|
||||
/**
|
||||
* Count the total number of rings in any #LWGEOM. Multipolygons
|
||||
* and other collections get counted, not the same as OGC st_numrings.
|
||||
*/
|
||||
extern int lwgeom_count_rings(const LWGEOM *geom);
|
||||
|
||||
|
||||
/**
|
||||
* Return true or false depending on whether a geometry has
|
||||
* a valid SRID set.
|
||||
|
@ -1637,9 +1644,6 @@ extern LWTRIANGLE *lwtriangle_from_lwline(const LWLINE *shell);
|
|||
extern const char *lwgeom_typeflags(uchar type);
|
||||
|
||||
|
||||
|
||||
extern int32 lwgeom_nrings_recursive(uchar *serialized);
|
||||
|
||||
/*
|
||||
* Given a point, returns the location of closest point on pointarray
|
||||
* as a fraction of total length (0: first point -- 1: last point).
|
||||
|
|
|
@ -1197,6 +1197,57 @@ int lwgeom_count_vertices(const LWGEOM *geom)
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count rings in an #LWGEOM.
|
||||
*/
|
||||
int lwgeom_count_rings(const LWGEOM *geom)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
/* Null? Empty? Zero. */
|
||||
if( ! geom || lwgeom_is_empty(geom) )
|
||||
return 0;
|
||||
|
||||
switch (TYPE_GETTYPE(geom->type))
|
||||
{
|
||||
case POINTTYPE:
|
||||
case CIRCSTRINGTYPE:
|
||||
case COMPOUNDTYPE:
|
||||
case MULTICURVETYPE:
|
||||
case MULTIPOINTTYPE:
|
||||
case MULTILINETYPE:
|
||||
case LINETYPE:
|
||||
result = 0;
|
||||
break;
|
||||
case TRIANGLETYPE:
|
||||
result = 1;
|
||||
break;
|
||||
case POLYGONTYPE:
|
||||
result = ((LWPOLY *)geom)->nrings;
|
||||
break;
|
||||
case CURVEPOLYTYPE:
|
||||
result = ((LWCURVEPOLY *)geom)->nrings;
|
||||
break;
|
||||
case MULTISURFACETYPE:
|
||||
case MULTIPOLYGONTYPE:
|
||||
case POLYHEDRALSURFACETYPE:
|
||||
case TINTYPE:
|
||||
case COLLECTIONTYPE:
|
||||
{
|
||||
LWCOLLECTION *col = (LWCOLLECTION*)geom;
|
||||
int i = 0;
|
||||
for( i = 0; i < col->ngeoms; i++ )
|
||||
result += lwgeom_count_rings(col->geoms[i]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
lwerror("lwgeom_count_rings: unsupported input geometry type: %s", lwtype_name(TYPE_GETTYPE(geom->type)));
|
||||
break;
|
||||
}
|
||||
LWDEBUGF(3, "counted %d rings", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int lwgeom_is_empty(const LWGEOM *geom)
|
||||
{
|
||||
int result = LW_FALSE;
|
||||
|
|
|
@ -223,127 +223,13 @@ Datum postgis_libxml_version(PG_FUNCTION_ARGS)
|
|||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Recursively count points in a SERIALIZED lwgeom
|
||||
*/
|
||||
int32
|
||||
lwgeom_npoints(uchar *serialized)
|
||||
{
|
||||
LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized);
|
||||
int i, j;
|
||||
int npoints=0;
|
||||
|
||||
/* now have to do a scan of each object */
|
||||
for (i=0; i<inspected->ngeometries; i++)
|
||||
{
|
||||
LWLINE *line=NULL;
|
||||
LWPOINT *point=NULL;
|
||||
LWPOLY *poly=NULL;
|
||||
LWTRIANGLE *triangle=NULL;
|
||||
LWCIRCSTRING *curve=NULL;
|
||||
uchar *subgeom=NULL;
|
||||
|
||||
point = lwgeom_getpoint_inspected(inspected, i);
|
||||
if (point !=NULL)
|
||||
{
|
||||
npoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
poly = lwgeom_getpoly_inspected(inspected, i);
|
||||
if (poly !=NULL)
|
||||
{
|
||||
for (j=0; j<poly->nrings; j++)
|
||||
{
|
||||
npoints += poly->rings[j]->npoints;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
line = lwgeom_getline_inspected(inspected, i);
|
||||
if (line != NULL)
|
||||
{
|
||||
npoints += line->points->npoints;
|
||||
continue;
|
||||
}
|
||||
|
||||
triangle = lwgeom_gettriangle_inspected(inspected, i);
|
||||
if (triangle != NULL)
|
||||
{
|
||||
npoints += triangle->points->npoints;
|
||||
continue;
|
||||
}
|
||||
|
||||
curve = lwgeom_getcircstring_inspected(inspected, i);
|
||||
if (curve != NULL)
|
||||
{
|
||||
npoints += curve->points->npoints;
|
||||
continue;
|
||||
}
|
||||
|
||||
subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
|
||||
if ( subgeom != NULL )
|
||||
{
|
||||
npoints += lwgeom_npoints(subgeom);
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR, "What ? lwgeom_getsubgeometry_inspected returned NULL??");
|
||||
}
|
||||
}
|
||||
return npoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively count rings in a SERIALIZED lwgeom
|
||||
*/
|
||||
int32
|
||||
lwgeom_nrings_recursive(uchar *serialized)
|
||||
{
|
||||
LWGEOM_INSPECTED *inspected;
|
||||
int i;
|
||||
int nrings=0;
|
||||
|
||||
inspected = lwgeom_inspect(serialized);
|
||||
|
||||
/* now have to do a scan of each object */
|
||||
for (i=0; i<inspected->ngeometries; i++)
|
||||
{
|
||||
LWPOLY *poly=NULL;
|
||||
uchar *subgeom=NULL;
|
||||
|
||||
subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
|
||||
|
||||
if ( lwgeom_getType(subgeom[0]) == POLYGONTYPE )
|
||||
{
|
||||
poly = lwpoly_deserialize(subgeom);
|
||||
nrings += poly->nrings;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( lwgeom_getType(subgeom[0]) == COLLECTIONTYPE )
|
||||
{
|
||||
nrings += lwgeom_nrings_recursive(subgeom);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
lwinspected_release(inspected);
|
||||
|
||||
return nrings;
|
||||
}
|
||||
|
||||
/** number of points in an object */
|
||||
PG_FUNCTION_INFO_V1(LWGEOM_npoints);
|
||||
Datum LWGEOM_npoints(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
LWGEOM *lwgeom = pglwgeom_deserialize(geom);
|
||||
int32 npoints = 0;
|
||||
int npoints = 0;
|
||||
|
||||
npoints = lwgeom_count_vertices(lwgeom);
|
||||
lwgeom_release(lwgeom);
|
||||
|
@ -357,9 +243,11 @@ PG_FUNCTION_INFO_V1(LWGEOM_nrings);
|
|||
Datum LWGEOM_nrings(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
int32 nrings = 0;
|
||||
LWGEOM *lwgeom = pglwgeom_deserialize(geom);
|
||||
int nrings = 0;
|
||||
|
||||
nrings = lwgeom_nrings_recursive(SERIALIZED_FORM(geom));
|
||||
nrings = lwgeom_count_rings(lwgeom);
|
||||
lwgeom_release(lwgeom);
|
||||
|
||||
PG_FREE_IF_COPY(geom, 0);
|
||||
PG_RETURN_INT32(nrings);
|
||||
|
@ -567,707 +455,6 @@ Datum LWGEOM_perimeter2d_poly(PG_FUNCTION_ARGS)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write to already allocated memory 'optr' a 3dz version of
|
||||
* the given serialized form.
|
||||
* Higher dimensions in input geometry are discarder.
|
||||
* If the given version is 2d Z is set to 0.
|
||||
* @return number bytes written in given int pointer.
|
||||
*/
|
||||
void
|
||||
lwgeom_force3dz_recursive(uchar *serialized, uchar *optr, size_t *retsize)
|
||||
{
|
||||
LWGEOM_INSPECTED *inspected;
|
||||
int i,j,k;
|
||||
size_t totsize=0;
|
||||
size_t size=0;
|
||||
int type;
|
||||
LWPOINT *point = NULL;
|
||||
LWLINE *line = NULL;
|
||||
LWCIRCSTRING *curve = NULL;
|
||||
LWPOLY *poly = NULL;
|
||||
LWTRIANGLE *triangle = NULL;
|
||||
POINTARRAY newpts;
|
||||
POINTARRAY **nrings;
|
||||
uchar *loc;
|
||||
POINT3DZ point3dz;
|
||||
|
||||
|
||||
LWDEBUG(2, "lwgeom_force3dz_recursive: call");
|
||||
|
||||
type = lwgeom_getType(serialized[0]);
|
||||
|
||||
if ( type == POINTTYPE )
|
||||
{
|
||||
point = lwpoint_deserialize(serialized);
|
||||
TYPE_SETZM(newpts.dims, 1, 0);
|
||||
newpts.npoints = 1;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT3DZ));
|
||||
loc = newpts.serialized_pointlist;
|
||||
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);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dz_recursive: it's a point, size:%d", *retsize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == LINETYPE )
|
||||
{
|
||||
line = lwline_deserialize(serialized);
|
||||
|
||||
LWDEBUG(3, "lwgeom_force3dz_recursive: it's a line");
|
||||
|
||||
TYPE_SETZM(newpts.dims, 1, 0);
|
||||
newpts.npoints = line->points->npoints;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT3DZ)*line->points->npoints);
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<line->points->npoints; j++)
|
||||
{
|
||||
getPoint3dz_p(line->points, j, &point3dz);
|
||||
memcpy(loc, &point3dz, sizeof(POINT3DZ));
|
||||
loc+=sizeof(POINT3DZ);
|
||||
}
|
||||
line->points = &newpts;
|
||||
TYPE_SETZM(line->type, 1, 0);
|
||||
lwline_serialize_buf(line, optr, retsize);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dz_recursive: it's a line, size:%d", *retsize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == CIRCSTRINGTYPE )
|
||||
{
|
||||
curve = lwcircstring_deserialize(serialized);
|
||||
|
||||
LWDEBUG(3, "lwgeom_force3dz_recursize: it's a circularstring");
|
||||
|
||||
TYPE_SETZM(newpts.dims, 1, 0);
|
||||
newpts.npoints = curve->points->npoints;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT3DZ)*curve->points->npoints);
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<curve->points->npoints; j++)
|
||||
{
|
||||
getPoint3dz_p(curve->points, j, &point3dz);
|
||||
memcpy(loc, &point3dz, sizeof(POINT3DZ));
|
||||
loc+=sizeof(POINT3DZ);
|
||||
}
|
||||
curve->points = &newpts;
|
||||
TYPE_SETZM(curve->type, 1, 0);
|
||||
lwcircstring_serialize_buf(curve, optr, retsize);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dz_recursive: it's a circularstring, size:%d", *retsize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == POLYGONTYPE )
|
||||
{
|
||||
poly = lwpoly_deserialize(serialized);
|
||||
TYPE_SETZM(newpts.dims, 1, 0);
|
||||
newpts.npoints = 0;
|
||||
newpts.serialized_pointlist = lwalloc(1);
|
||||
nrings = lwalloc(sizeof(POINTARRAY *)*poly->nrings);
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<poly->nrings; j++)
|
||||
{
|
||||
POINTARRAY *ring = poly->rings[j];
|
||||
POINTARRAY *nring = lwalloc(sizeof(POINTARRAY));
|
||||
TYPE_SETZM(nring->dims, 1, 0);
|
||||
nring->npoints = ring->npoints;
|
||||
nring->serialized_pointlist =
|
||||
lwalloc(ring->npoints*sizeof(POINT3DZ));
|
||||
loc = nring->serialized_pointlist;
|
||||
for (k=0; k<ring->npoints; k++)
|
||||
{
|
||||
getPoint3dz_p(ring, k, &point3dz);
|
||||
memcpy(loc, &point3dz, sizeof(POINT3DZ));
|
||||
loc+=sizeof(POINT3DZ);
|
||||
}
|
||||
nrings[j] = nring;
|
||||
}
|
||||
poly->rings = nrings;
|
||||
TYPE_SETZM(poly->type, 1, 0);
|
||||
lwpoly_serialize_buf(poly, optr, retsize);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dz_recursive: it's a poly, size:%d", *retsize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == TRIANGLETYPE )
|
||||
{
|
||||
triangle = lwtriangle_deserialize(serialized);
|
||||
|
||||
LWDEBUG(3, "lwgeom_force3dz_recursive: it's a triangle");
|
||||
|
||||
TYPE_SETZM(newpts.dims, 1, 0);
|
||||
newpts.npoints = triangle->points->npoints;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT3DZ)*triangle->points->npoints);
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<triangle->points->npoints; j++)
|
||||
{
|
||||
getPoint3dz_p(triangle->points, j, &point3dz);
|
||||
memcpy(loc, &point3dz, sizeof(POINT3DZ));
|
||||
loc+=sizeof(POINT3DZ);
|
||||
}
|
||||
triangle->points = &newpts;
|
||||
TYPE_SETZM(triangle->type, 1, 0);
|
||||
lwtriangle_serialize_buf(triangle, optr, retsize);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dz_recursive: it's a triangle, size:%d", *retsize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type != MULTIPOINTTYPE && type != MULTIPOLYGONTYPE &&
|
||||
type != MULTILINETYPE && type != COLLECTIONTYPE &&
|
||||
type != COMPOUNDTYPE && type != CURVEPOLYTYPE &&
|
||||
type != MULTICURVETYPE && type != MULTISURFACETYPE &&
|
||||
type != POLYHEDRALSURFACETYPE && type != TINTYPE )
|
||||
{
|
||||
lwerror("lwgeom_force3dz_recursive: unknown geometry: %d - %s",
|
||||
type, lwtype_name(type));
|
||||
}
|
||||
/*
|
||||
* OK, this is a collection, so we write down its metadata
|
||||
* first and then call us again
|
||||
*/
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dz_recursive: it's a collection (type:%d)", type);
|
||||
|
||||
/* Add type */
|
||||
*optr = lwgeom_makeType_full(1, 0, lwgeom_hasSRID(serialized[0]),
|
||||
type, lwgeom_hasBBOX(serialized[0]));
|
||||
optr++;
|
||||
totsize++;
|
||||
loc=serialized+1;
|
||||
|
||||
/* Add BBOX if any */
|
||||
if (lwgeom_hasBBOX(serialized[0]))
|
||||
{
|
||||
memcpy(optr, loc, sizeof(BOX2DFLOAT4));
|
||||
optr += sizeof(BOX2DFLOAT4);
|
||||
totsize += sizeof(BOX2DFLOAT4);
|
||||
loc += sizeof(BOX2DFLOAT4);
|
||||
}
|
||||
|
||||
/* Add SRID if any */
|
||||
if (lwgeom_hasSRID(serialized[0]))
|
||||
{
|
||||
memcpy(optr, loc, 4);
|
||||
optr += 4;
|
||||
totsize += 4;
|
||||
loc += 4;
|
||||
}
|
||||
|
||||
/* Add numsubobjects */
|
||||
memcpy(optr, loc, 4);
|
||||
optr += 4;
|
||||
totsize += 4;
|
||||
|
||||
LWDEBUGF(3, " collection header size:%d", totsize);
|
||||
|
||||
/* Now recurse for each suboject */
|
||||
inspected = lwgeom_inspect(serialized);
|
||||
for (i=0; i<inspected->ngeometries; i++)
|
||||
{
|
||||
uchar *subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
|
||||
lwgeom_force3dz_recursive(subgeom, optr, &size);
|
||||
totsize += size;
|
||||
optr += size;
|
||||
|
||||
LWDEBUGF(3, " elem %d size: %d (tot: %d)", i, size, totsize);
|
||||
}
|
||||
lwinspected_release(inspected);
|
||||
|
||||
*retsize = totsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write to already allocated memory 'optr' a 3dm version of
|
||||
* the given serialized form.
|
||||
* Higher dimensions in input geometry are discarder.
|
||||
* If the given version is 2d M is set to 0.
|
||||
* @return number bytes written in given int pointer.
|
||||
*/
|
||||
void
|
||||
lwgeom_force3dm_recursive(uchar *serialized, uchar *optr, size_t *retsize)
|
||||
{
|
||||
LWGEOM_INSPECTED *inspected;
|
||||
int i,j,k;
|
||||
size_t totsize=0;
|
||||
size_t size=0;
|
||||
int type;
|
||||
uchar newtypefl;
|
||||
LWPOINT *point = NULL;
|
||||
LWLINE *line = NULL;
|
||||
LWCIRCSTRING *curve = NULL;
|
||||
LWPOLY *poly = NULL;
|
||||
LWTRIANGLE *triangle = NULL;
|
||||
POINTARRAY newpts;
|
||||
POINTARRAY **nrings;
|
||||
POINT3DM p3dm;
|
||||
uchar *loc;
|
||||
|
||||
|
||||
LWDEBUG(2, "lwgeom_force3dm_recursive: call");
|
||||
|
||||
type = lwgeom_getType(serialized[0]);
|
||||
|
||||
if ( type == POINTTYPE )
|
||||
{
|
||||
point = lwpoint_deserialize(serialized);
|
||||
TYPE_SETZM(newpts.dims, 0, 1);
|
||||
newpts.npoints = 1;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT3DM));
|
||||
loc = newpts.serialized_pointlist;
|
||||
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);
|
||||
lwfree(newpts.serialized_pointlist);
|
||||
lwfree(point);
|
||||
|
||||
LWDEBUG(3, "lwgeom_force3dm_recursive returning");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == LINETYPE )
|
||||
{
|
||||
line = lwline_deserialize(serialized);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursive: it's a line with %d points", line->points->npoints);
|
||||
|
||||
TYPE_SETZM(newpts.dims, 0, 1);
|
||||
newpts.npoints = line->points->npoints;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT3DM)*line->points->npoints);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursive: %d bytes pointlist allocated", sizeof(POINT3DM)*line->points->npoints);
|
||||
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<line->points->npoints; j++)
|
||||
{
|
||||
getPoint3dm_p(line->points, j, &p3dm);
|
||||
memcpy(loc, &p3dm, sizeof(POINT3DM));
|
||||
loc+=sizeof(POINT3DM);
|
||||
}
|
||||
line->points = &newpts;
|
||||
TYPE_SETZM(line->type, 0, 1);
|
||||
lwline_serialize_buf(line, optr, retsize);
|
||||
lwfree(newpts.serialized_pointlist);
|
||||
lwfree(line);
|
||||
|
||||
LWDEBUG(3, "lwgeom_force3dm_recursive returning");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == CIRCSTRINGTYPE )
|
||||
{
|
||||
curve = lwcircstring_deserialize(serialized);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursize: it's a circularstring with %d points", curve->points->npoints);
|
||||
|
||||
TYPE_SETZM(newpts.dims, 0, 1);
|
||||
newpts.npoints = curve->points->npoints;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT3DM)*curve->points->npoints);
|
||||
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<curve->points->npoints; j++)
|
||||
{
|
||||
getPoint3dm_p(curve->points, j, &p3dm);
|
||||
memcpy(loc, &p3dm, sizeof(POINT3DM));
|
||||
loc+=sizeof(POINT3DM);
|
||||
}
|
||||
curve->points = &newpts;
|
||||
TYPE_SETZM(curve->type, 0, 1);
|
||||
lwcircstring_serialize_buf(curve, optr, retsize);
|
||||
lwfree(newpts.serialized_pointlist);
|
||||
lwfree(curve);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == POLYGONTYPE )
|
||||
{
|
||||
poly = lwpoly_deserialize(serialized);
|
||||
TYPE_SETZM(newpts.dims, 0, 1);
|
||||
newpts.npoints = 0;
|
||||
newpts.serialized_pointlist = lwalloc(1);
|
||||
nrings = lwalloc(sizeof(POINTARRAY *)*poly->nrings);
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<poly->nrings; j++)
|
||||
{
|
||||
POINTARRAY *ring = poly->rings[j];
|
||||
POINTARRAY *nring = lwalloc(sizeof(POINTARRAY));
|
||||
TYPE_SETZM(nring->dims, 0, 1);
|
||||
nring->npoints = ring->npoints;
|
||||
nring->serialized_pointlist =
|
||||
lwalloc(ring->npoints*sizeof(POINT3DM));
|
||||
loc = nring->serialized_pointlist;
|
||||
for (k=0; k<ring->npoints; k++)
|
||||
{
|
||||
getPoint3dm_p(ring, k, &p3dm);
|
||||
memcpy(loc, &p3dm, sizeof(POINT3DM));
|
||||
loc+=sizeof(POINT3DM);
|
||||
}
|
||||
nrings[j] = nring;
|
||||
}
|
||||
poly->rings = nrings;
|
||||
TYPE_SETZM(poly->type, 0, 1);
|
||||
lwpoly_serialize_buf(poly, optr, retsize);
|
||||
lwfree(poly);
|
||||
/** @todo TODO: free nrigs[*]->serialized_pointlist
|
||||
*/
|
||||
|
||||
LWDEBUG(3, "lwgeom_force3dm_recursive returning");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == TRIANGLETYPE )
|
||||
{
|
||||
triangle = lwtriangle_deserialize(serialized);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursive: it's a triangle with %d points", triangle->points->npoints);
|
||||
|
||||
TYPE_SETZM(newpts.dims, 0, 1);
|
||||
newpts.npoints = triangle->points->npoints;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT3DM)*triangle->points->npoints);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursive: %d bytes pointlist allocated",
|
||||
sizeof(POINT3DM)*triangle->points->npoints);
|
||||
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<triangle->points->npoints; j++)
|
||||
{
|
||||
getPoint3dm_p(triangle->points, j, &p3dm);
|
||||
memcpy(loc, &p3dm, sizeof(POINT3DM));
|
||||
loc+=sizeof(POINT3DM);
|
||||
}
|
||||
triangle->points = &newpts;
|
||||
TYPE_SETZM(triangle->type, 0, 1);
|
||||
lwtriangle_serialize_buf(triangle, optr, retsize);
|
||||
lwfree(newpts.serialized_pointlist);
|
||||
lwfree(triangle);
|
||||
|
||||
LWDEBUG(3, "lwgeom_force3dm_recursive returning");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type != MULTIPOINTTYPE && type != MULTIPOLYGONTYPE &&
|
||||
type != MULTILINETYPE && type != COLLECTIONTYPE &&
|
||||
type != COMPOUNDTYPE && type != CURVEPOLYTYPE &&
|
||||
type != MULTICURVETYPE && type != MULTISURFACETYPE &&
|
||||
type != POLYHEDRALSURFACETYPE && type != TINTYPE )
|
||||
{
|
||||
lwerror("lwgeom_force3dm_recursive: unknown geometry: %d - %s",
|
||||
type, lwtype_name(type));
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, this is a collection, so we write down its metadata
|
||||
* first and then call us again
|
||||
*/
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursive: it's a collection (%s)", lwtype_name(type));
|
||||
|
||||
|
||||
/* Add type */
|
||||
newtypefl = lwgeom_makeType_full(0, 1, lwgeom_hasSRID(serialized[0]),
|
||||
type, lwgeom_hasBBOX(serialized[0]));
|
||||
optr[0] = newtypefl;
|
||||
optr++;
|
||||
totsize++;
|
||||
loc=serialized+1;
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursive: added collection type (%s[%s]) - size:%d", lwtype_name(type), lwgeom_typeflags(newtypefl), totsize);
|
||||
|
||||
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]))
|
||||
{
|
||||
memcpy(optr, loc, sizeof(BOX2DFLOAT4));
|
||||
optr += sizeof(BOX2DFLOAT4);
|
||||
totsize += sizeof(BOX2DFLOAT4);
|
||||
loc += sizeof(BOX2DFLOAT4);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursive: added collection bbox - size:%d", totsize);
|
||||
}
|
||||
|
||||
/* Add SRID if any */
|
||||
if (lwgeom_hasSRID(serialized[0]))
|
||||
{
|
||||
memcpy(optr, loc, 4);
|
||||
optr += 4;
|
||||
totsize += 4;
|
||||
loc += 4;
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursive: added collection SRID - size:%d", totsize);
|
||||
}
|
||||
|
||||
/* Add numsubobjects */
|
||||
memcpy(optr, loc, sizeof(uint32));
|
||||
optr += sizeof(uint32);
|
||||
totsize += sizeof(uint32);
|
||||
loc += sizeof(uint32);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursive: added collection ngeoms - size:%d", totsize);
|
||||
|
||||
LWDEBUG(3, "lwgeom_force3dm_recursive: inspecting subgeoms");
|
||||
|
||||
/* Now recurse for each subobject */
|
||||
inspected = lwgeom_inspect(serialized);
|
||||
for (i=0; i<inspected->ngeometries; i++)
|
||||
{
|
||||
uchar *subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
|
||||
lwgeom_force3dm_recursive(subgeom, optr, &size);
|
||||
totsize += size;
|
||||
optr += size;
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force3dm_recursive: added elem %d size: %d (tot: %d)",
|
||||
i, size, totsize);
|
||||
}
|
||||
lwinspected_release(inspected);
|
||||
|
||||
LWDEBUG(3, "lwgeom_force3dm_recursive returning");
|
||||
|
||||
if ( retsize ) *retsize = totsize;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write to already allocated memory 'optr' a 4d version of
|
||||
* the given serialized form.
|
||||
* Pad dimensions are set to 0 (this might be z, m or both).
|
||||
* Return number bytes written in given int pointer.
|
||||
*/
|
||||
void
|
||||
lwgeom_force4d_recursive(uchar *serialized, uchar *optr, size_t *retsize)
|
||||
{
|
||||
LWGEOM_INSPECTED *inspected;
|
||||
int i,j,k;
|
||||
size_t totsize=0;
|
||||
size_t size=0;
|
||||
int type;
|
||||
LWPOINT *point = NULL;
|
||||
LWLINE *line = NULL;
|
||||
LWCIRCSTRING *curve = NULL;
|
||||
LWPOLY *poly = NULL;
|
||||
LWTRIANGLE *triangle = NULL;
|
||||
POINTARRAY newpts;
|
||||
POINTARRAY **nrings;
|
||||
POINT4D p4d;
|
||||
uchar *loc;
|
||||
|
||||
|
||||
LWDEBUG(2, "lwgeom_force4d_recursive: call");
|
||||
|
||||
type = lwgeom_getType(serialized[0]);
|
||||
|
||||
if ( type == POINTTYPE )
|
||||
{
|
||||
point = lwpoint_deserialize(serialized);
|
||||
TYPE_SETZM(newpts.dims, 1, 1);
|
||||
newpts.npoints = 1;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT4D));
|
||||
loc = newpts.serialized_pointlist;
|
||||
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);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force4d_recursive: it's a point, size:%d", *retsize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == LINETYPE )
|
||||
{
|
||||
LWDEBUG(3, "lwgeom_force4d_recursive: it's a line");
|
||||
|
||||
line = lwline_deserialize(serialized);
|
||||
TYPE_SETZM(newpts.dims, 1, 1);
|
||||
newpts.npoints = line->points->npoints;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT4D)*line->points->npoints);
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<line->points->npoints; j++)
|
||||
{
|
||||
getPoint4d_p(line->points, j, &p4d);
|
||||
memcpy(loc, &p4d, sizeof(POINT4D));
|
||||
loc+=sizeof(POINT4D);
|
||||
}
|
||||
line->points = &newpts;
|
||||
TYPE_SETZM(line->type, 1, 1);
|
||||
lwline_serialize_buf(line, optr, retsize);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force4d_recursive: it's a line, size:%d", *retsize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == CIRCSTRINGTYPE )
|
||||
{
|
||||
curve = lwcircstring_deserialize(serialized);
|
||||
TYPE_SETZM(newpts.dims, 1, 1);
|
||||
newpts.npoints = curve->points->npoints;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT4D)*curve->points->npoints);
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<curve->points->npoints; j++)
|
||||
{
|
||||
getPoint4d_p(curve->points, j, &p4d);
|
||||
memcpy(loc, &p4d, sizeof(POINT4D));
|
||||
loc+=sizeof(POINT4D);
|
||||
}
|
||||
curve->points = &newpts;
|
||||
TYPE_SETZM(curve->type, 1, 1);
|
||||
lwcircstring_serialize_buf(curve, optr, retsize);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force4d_recursive: it's a circularstring, size:%d", *retsize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == POLYGONTYPE )
|
||||
{
|
||||
poly = lwpoly_deserialize(serialized);
|
||||
TYPE_SETZM(newpts.dims, 1, 1);
|
||||
newpts.npoints = 0;
|
||||
newpts.serialized_pointlist = lwalloc(1);
|
||||
nrings = lwalloc(sizeof(POINTARRAY *)*poly->nrings);
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<poly->nrings; j++)
|
||||
{
|
||||
POINTARRAY *ring = poly->rings[j];
|
||||
POINTARRAY *nring = lwalloc(sizeof(POINTARRAY));
|
||||
TYPE_SETZM(nring->dims, 1, 1);
|
||||
nring->npoints = ring->npoints;
|
||||
nring->serialized_pointlist =
|
||||
lwalloc(ring->npoints*sizeof(POINT4D));
|
||||
loc = nring->serialized_pointlist;
|
||||
for (k=0; k<ring->npoints; k++)
|
||||
{
|
||||
getPoint4d_p(ring, k, &p4d);
|
||||
memcpy(loc, &p4d, sizeof(POINT4D));
|
||||
loc+=sizeof(POINT4D);
|
||||
}
|
||||
nrings[j] = nring;
|
||||
}
|
||||
poly->rings = nrings;
|
||||
TYPE_SETZM(poly->type, 1, 1);
|
||||
lwpoly_serialize_buf(poly, optr, retsize);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force4d_recursive: it's a poly, size:%d", *retsize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == TRIANGLETYPE )
|
||||
{
|
||||
LWDEBUG(3, "lwgeom_force4d_recursive: it's a triangle");
|
||||
|
||||
triangle = lwtriangle_deserialize(serialized);
|
||||
TYPE_SETZM(newpts.dims, 1, 1);
|
||||
newpts.npoints = triangle->points->npoints;
|
||||
newpts.serialized_pointlist = lwalloc(sizeof(POINT4D)*triangle->points->npoints);
|
||||
loc = newpts.serialized_pointlist;
|
||||
for (j=0; j<triangle->points->npoints; j++)
|
||||
{
|
||||
getPoint4d_p(triangle->points, j, &p4d);
|
||||
memcpy(loc, &p4d, sizeof(POINT4D));
|
||||
loc+=sizeof(POINT4D);
|
||||
}
|
||||
triangle->points = &newpts;
|
||||
TYPE_SETZM(triangle->type, 1, 1);
|
||||
lwtriangle_serialize_buf(triangle, optr, retsize);
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force4d_recursive: it's a triangle, size:%d", *retsize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type != MULTIPOINTTYPE && type != MULTIPOLYGONTYPE &&
|
||||
type != MULTILINETYPE && type != COLLECTIONTYPE &&
|
||||
type != COMPOUNDTYPE && type != CURVEPOLYTYPE &&
|
||||
type != MULTICURVETYPE && type != MULTISURFACETYPE &&
|
||||
type != POLYHEDRALSURFACETYPE && type != TINTYPE )
|
||||
{
|
||||
lwerror("lwgeom_force4d_recursive: unknown geometry: %d - %s",
|
||||
type, lwtype_name(type));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* OK, this is a collection, so we write down its metadata
|
||||
* first and then call us again
|
||||
*/
|
||||
|
||||
LWDEBUGF(3, "lwgeom_force4d_recursive: it's a collection (type:%d)", type);
|
||||
|
||||
/* Add type */
|
||||
*optr = lwgeom_makeType_full(
|
||||
1, 1,
|
||||
lwgeom_hasSRID(serialized[0]),
|
||||
type, lwgeom_hasBBOX(serialized[0]));
|
||||
optr++;
|
||||
totsize++;
|
||||
loc=serialized+1;
|
||||
|
||||
/* Add BBOX if any */
|
||||
if (lwgeom_hasBBOX(serialized[0]))
|
||||
{
|
||||
memcpy(optr, loc, sizeof(BOX2DFLOAT4));
|
||||
optr += sizeof(BOX2DFLOAT4);
|
||||
totsize += sizeof(BOX2DFLOAT4);
|
||||
loc += sizeof(BOX2DFLOAT4);
|
||||
}
|
||||
|
||||
/* Add SRID if any */
|
||||
if (lwgeom_hasSRID(serialized[0]))
|
||||
{
|
||||
memcpy(optr, loc, 4);
|
||||
optr += 4;
|
||||
totsize += 4;
|
||||
loc += 4;
|
||||
}
|
||||
|
||||
/* Add numsubobjects */
|
||||
memcpy(optr, loc, 4);
|
||||
optr += 4;
|
||||
totsize += 4;
|
||||
|
||||
LWDEBUGF(3, " collection header size:%d", totsize);
|
||||
|
||||
/* Now recurse for each suboject */
|
||||
inspected = lwgeom_inspect(serialized);
|
||||
for (i=0; i<inspected->ngeometries; i++)
|
||||
{
|
||||
uchar *subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
|
||||
lwgeom_force4d_recursive(subgeom, optr, &size);
|
||||
totsize += size;
|
||||
optr += size;
|
||||
|
||||
LWDEBUGF(3, " elem %d size: %d (tot: %d)", i, size, totsize);
|
||||
}
|
||||
lwinspected_release(inspected);
|
||||
|
||||
*retsize = totsize;
|
||||
}
|
||||
|
||||
/* transform input geometry to 2d if not 2d already */
|
||||
PG_FUNCTION_INFO_V1(LWGEOM_force_2d);
|
||||
Datum LWGEOM_force_2d(PG_FUNCTION_ARGS)
|
||||
|
|
Loading…
Reference in a new issue