From: Sandro Santilli Date: Wed, 5 Jan 2005 21:59:32 +0000 (+0000) Subject: Simplify reworked to use LWGEOM abstraction (no more flattening of input collection). X-Git-Tag: pgis_1_0_0RC1~82 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5acd93a5e56ad81270b089020fd6541d69eeffa9;p=postgis Simplify reworked to use LWGEOM abstraction (no more flattening of input collection). git-svn-id: http://svn.osgeo.org/postgis/trunk@1222 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/lwgeom/BBOXCACHE_BEHAVIOURS b/lwgeom/BBOXCACHE_BEHAVIOURS index bb232aff8..144c82ece 100644 --- a/lwgeom/BBOXCACHE_BEHAVIOURS +++ b/lwgeom/BBOXCACHE_BEHAVIOURS @@ -75,7 +75,7 @@ section also use it. [ TAINING ] GeometryN(geometry,integer) *LWG* InteriorRingN(geometry,integer) *LWG* - simplify(geometry, float8) *SRL* (*EXP*) + simplify(geometry, float8) *LWG* #### could use WHEN_SIMPLE #### translating and transforming an eventually present diff --git a/lwgeom/lwgeom_functions_analytic.c b/lwgeom/lwgeom_functions_analytic.c index 1c580e609..81c6eacab 100644 --- a/lwgeom/lwgeom_functions_analytic.c +++ b/lwgeom/lwgeom_functions_analytic.c @@ -23,8 +23,10 @@ /* Prototypes */ void DP_findsplit2d(POINTARRAY *pts, int p1, int p2, int *split, double *dist); POINTARRAY *DP_simplify2d(POINTARRAY *inpts, double epsilon); -LWLINE *simplify2d_lwline(LWLINE *iline, double dist); -LWPOLY *simplify2d_lwpoly(LWPOLY *ipoly, double dist); +LWLINE *simplify2d_lwline(const LWLINE *iline, double dist); +LWPOLY *simplify2d_lwpoly(const LWPOLY *ipoly, double dist); +LWCOLLECTION *simplify2d_collection(const LWCOLLECTION *igeom, double dist); +LWGEOM *simplify2d_lwgeom(const LWGEOM *igeom, double dist); Datum LWGEOM_simplify2d(PG_FUNCTION_ARGS); @@ -164,7 +166,7 @@ DP_simplify2d(POINTARRAY *inpts, double epsilon) } LWLINE * -simplify2d_lwline(LWLINE *iline, double dist) +simplify2d_lwline(const LWLINE *iline, double dist) { POINTARRAY *ipts; POINTARRAY *opts; @@ -183,7 +185,7 @@ simplify2d_lwline(LWLINE *iline, double dist) // TODO LWPOLY * -simplify2d_lwpoly(LWPOLY *ipoly, double dist) +simplify2d_lwpoly(const LWPOLY *ipoly, double dist) { POINTARRAY *ipts; POINTARRAY **orings = NULL; @@ -250,77 +252,67 @@ elog(NOTICE, "simplify_polygon3d: simplified polygon with %d rings", norings); return opoly; } -PG_FUNCTION_INFO_V1(LWGEOM_simplify2d); -Datum LWGEOM_simplify2d(PG_FUNCTION_ARGS) +LWCOLLECTION * +simplify2d_collection(const LWCOLLECTION *igeom, double dist) { - PG_LWGEOM *geom = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - LWGEOM_EXPLODED *exp = lwgeom_explode(SERIALIZED_FORM(geom)); - double dist = PG_GETARG_FLOAT8(1); - int i; - char **newlines; - int newlinesnum=0; - char **newpolys; - int newpolysnum=0; - PG_LWGEOM *result; - char *serialized; + unsigned int i; + unsigned int ngeoms=0; + LWGEOM **geoms = lwalloc(sizeof(LWGEOM *)*igeom->ngeoms); + LWCOLLECTION *out; - // no lines, no points... return input - if ( exp->nlines + exp->npolys == 0 ) + for (i=0; ingeoms; i++) { - pfree_exploded(exp); - PG_RETURN_POINTER(geom); + LWGEOM *ngeom = simplify2d_lwgeom(igeom->geoms[i], dist); + if ( ngeom ) geoms[ngeoms++] = ngeom; } - if ( exp->nlines ) - { -#if VERBOSE - elog(NOTICE, "%d lines in exploded geom", exp->nlines); -#endif - newlines = palloc(sizeof(char *)*exp->nlines); - for ( i=0; inlines; i++ ) - { - LWLINE *iline = lwline_deserialize(exp->lines[i]); -#if VERBOSE - elog(NOTICE, " line %d deserialized", i); -#endif - LWLINE *oline = simplify2d_lwline(iline, dist); -#if VERBOSE - elog(NOTICE, " line %d simplified", i); -#endif - if ( oline == NULL ) continue; - newlines[newlinesnum] = lwline_serialize(oline); - newlinesnum++; - } - pfree(exp->lines); - exp->lines = newlines; - exp->nlines = newlinesnum; - } + out = lwcollection_construct(TYPE_GETTYPE(igeom->type), igeom->SRID, + NULL, ngeoms, geoms); + + return out; +} - if ( exp->npolys ) +LWGEOM * +simplify2d_lwgeom(const LWGEOM *igeom, double dist) +{ + switch(TYPE_GETTYPE(igeom->type)) { - newpolys = palloc(sizeof(char *)*exp->npolys); - for ( i=0; inpolys; i++ ) - { - LWPOLY *ipoly = lwpoly_deserialize(exp->polys[i]); - LWPOLY *opoly = simplify2d_lwpoly(ipoly, dist); - if ( opoly == NULL ) continue; - newpolys[newpolysnum] = lwpoly_serialize(opoly); - newpolysnum++; - } - pfree(exp->polys); - exp->polys = newpolys; - exp->npolys = newpolysnum; + case POINTTYPE: + case MULTIPOINTTYPE: + return lwgeom_clone(igeom); + case LINETYPE: + return (LWGEOM *)simplify2d_lwline( + (LWLINE *)igeom, dist); + case POLYGONTYPE: + return (LWGEOM *)simplify2d_lwpoly( + (LWPOLY *)igeom, dist); + case MULTILINETYPE: + case MULTIPOLYGONTYPE: + case COLLECTIONTYPE: + return (LWGEOM *)simplify2d_collection( + (LWCOLLECTION *)igeom, dist); + default: + lwerror("simplify2d_lwgeom: unknown geometry type: %d", + TYPE_GETTYPE(igeom->type)); } + return NULL; +} + +PG_FUNCTION_INFO_V1(LWGEOM_simplify2d); +Datum LWGEOM_simplify2d(PG_FUNCTION_ARGS) +{ + PG_LWGEOM *geom = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + LWGEOM *in = lwgeom_deserialize(SERIALIZED_FORM(geom)); + LWGEOM *out; + PG_LWGEOM *result; + double dist = PG_GETARG_FLOAT8(1); - // copy 1 (when lwexploded_serialize_buf will be implemented this - // can be avoided) - serialized = lwexploded_serialize(exp, lwgeom_hasBBOX(geom->type)); - pfree_exploded(exp); + out = simplify2d_lwgeom(in, dist); + /* COMPUTE_BBOX TAINTING */ + if ( in->bbox ) lwgeom_addBBOX(out); - // copy 2 (see above) - result = PG_LWGEOM_construct(serialized, - pglwgeom_getSRID(geom), lwgeom_hasBBOX(geom->type)); + result = pglwgeom_serialize(out); PG_RETURN_POINTER(result); }