]> granicus.if.org Git - postgis/commitdiff
Simplify reworked to use LWGEOM abstraction (no more flattening of input collection).
authorSandro Santilli <strk@keybit.net>
Wed, 5 Jan 2005 21:59:32 +0000 (21:59 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 5 Jan 2005 21:59:32 +0000 (21:59 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@1222 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/BBOXCACHE_BEHAVIOURS
lwgeom/lwgeom_functions_analytic.c

index bb232aff87ae070b10662e47766027a3abf8485e..144c82ece5e5e7e1e61a566a96701ece12f3de30 100644 (file)
@@ -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
index 1c580e609f8d806872b1b440c3601266103f7255..81c6eacab21b3b25b9463af7adbe2e1a255280d2 100644 (file)
 /* 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; i<igeom->ngeoms; 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; i<exp->nlines; 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; i<exp->npolys; 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);
 }