]> granicus.if.org Git - postgis/commitdiff
Fixed non-GEOS centroid() function to avoid obsoleted LWGEOM_EXPLODED funx
authorSandro Santilli <strk@keybit.net>
Thu, 24 Mar 2005 15:07:59 +0000 (15:07 +0000)
committerSandro Santilli <strk@keybit.net>
Thu, 24 Mar 2005 15:07:59 +0000 (15:07 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@1560 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/lwgeom_functions_basic.c

index a0d3697edf171b8c186e9b93aeb07226b4ad731d..8d11d799af00447003a01e01d30a5c7d01aa7ec8 100644 (file)
@@ -2298,32 +2298,25 @@ Datum LWGEOM_isempty(PG_FUNCTION_ARGS)
 
 
 #if ! USE_GEOS && ! USE_JTS
-Datum centroid(PG_FUNCTION_ARGS);
-PG_FUNCTION_INFO_V1(centroid);
-Datum centroid(PG_FUNCTION_ARGS)
+
+LWGEOM *lwgeom_centroid(LWGEOM *in);
+
+LWGEOM *
+lwgeom_centroid(LWGEOM *in)
 {
-       PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       int type = lwgeom_getType(geom->type);
-       int SRID = pglwgeom_getSRID(geom);
-       LWGEOM_EXPLODED *exp = lwgeom_explode(SERIALIZED_FORM(geom));
-       LWPOLY *poly=NULL;
+       int type = lwgeom_getType(in->type);
+       LWPOLY *poly;
        LWPOINT *point;
-       PG_LWGEOM *result;
+       LWMPOLY *mpoly;
        POINTARRAY *ring, *pa;
-       POINT3DZ p, cent;
+       POINT3DZ p, *cent;
        int i,j,k;
        uint32 num_points_tot = 0;
-       uchar *srl;
-       char wantbbox = 0;
        double tot_x=0, tot_y=0, tot_z=0;
 
-       if  (type != POLYGONTYPE && type != MULTIPOLYGONTYPE)
-               PG_RETURN_NULL();
-
-       //find the centroid
-       for (i=0; i<exp->npolys; i++)
+       if (type == POLYGONTYPE)
        {
-               poly = lwpoly_deserialize(exp->polys[i]);
+               poly = (LWPOLY*)in;
                for (j=0; j<poly->nrings; j++)
                {
                        ring = poly->rings[j];
@@ -2336,32 +2329,60 @@ Datum centroid(PG_FUNCTION_ARGS)
                        }
                        num_points_tot += ring->npoints-1;
                }
-               pfree_polygon(poly);
        }
-       pfree_exploded(exp);
+       else if ( type == MULTIPOLYGONTYPE )
+       {
+               mpoly = (LWMPOLY*)in;
+               for (i=0; i<mpoly->ngeoms; i++)
+               {
+                       poly = mpoly->geoms[i];
+                       for (j=0; j<poly->nrings; j++)
+                       {
+                               ring = poly->rings[j];
+                               for (k=0; k<ring->npoints-1; k++)
+                               {
+                                       getPoint3dz_p(ring, k, &p);
+                                       tot_x += p.x;
+                                       tot_y += p.y;
+                                       if ( TYPE_HASZ(ring->dims) ) tot_z += p.z;
+                               }
+                               num_points_tot += ring->npoints-1;
+                       }
+               }
+       }
+       else
+       {
+               return NULL;
+       }
 
        // Setup point
-       cent.x = tot_x/num_points_tot;
-       cent.y = tot_y/num_points_tot;
-       cent.z = tot_z/num_points_tot;
+       cent = lwalloc(sizeof(POINT3DZ));
+       cent->x = tot_x/num_points_tot;
+       cent->y = tot_y/num_points_tot;
+       cent->z = tot_z/num_points_tot;
 
        // Construct POINTARRAY (paranoia?)
-       pa = pointArray_construct((uchar *)&cent, 1, 0, 1);
+       pa = pointArray_construct((uchar *)cent, 1, 0, 1);
 
        // Construct LWPOINT
-       point = lwpoint_construct(SRID, NULL, pa);
+       point = lwpoint_construct(in->SRID, NULL, pa);
 
-       // Serialize LWPOINT 
-       srl = lwpoint_serialize(point);
+       return (LWGEOM *)point;
+}
 
-       pfree_point(point);
-       pfree_POINTARRAY(pa);
+Datum centroid(PG_FUNCTION_ARGS);
+PG_FUNCTION_INFO_V1(centroid);
+Datum centroid(PG_FUNCTION_ARGS)
+{
+       PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       LWGEOM *lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom));
+       LWGEOM *centroid = lwgeom_centroid(lwgeom);
+       lwgeom_release(lwgeom);
+       if ( ! centroid ) PG_RETURN_NULL();
+       PG_LWGEOM *ret = pglwgeom_serialize(centroid);
+       lwgeom_release((LWGEOM *)centroid);
        PG_FREE_IF_COPY(geom, 0);
-
-       // Construct output PG_LWGEOM
-       result = PG_LWGEOM_construct(srl, SRID, wantbbox);
-
-       PG_RETURN_POINTER(result);
+       PG_RETURN_POINTER(ret);
 }
 #endif // ! USE_GEOS && ! USE_JTS