#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];
}
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 *)¢, 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