From: Sandro Santilli <strk@keybit.net>
Date: Wed, 8 Sep 2004 10:25:26 +0000 (+0000)
Subject: Fixed a bug in the z() function.
X-Git-Tag: pgis_0_9_1~13
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3757c035df807b010a0dcafc4cc8ca6e8e060558;p=postgis

Fixed a bug in the z() function.
Added ! GEOS implementation of Centroid().


git-svn-id: http://svn.osgeo.org/postgis/trunk@781 b70326c6-7e19-0410-871a-916f4a2858ee
---

diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c
index 691aa23ef..1244ffecc 100644
--- a/lwgeom/lwgeom_functions_basic.c
+++ b/lwgeom/lwgeom_functions_basic.c
@@ -2334,3 +2334,70 @@ Datum LWGEOM_isempty(PG_FUNCTION_ARGS)
 		PG_RETURN_BOOL(TRUE);
 	PG_RETURN_BOOL(FALSE);
 }
+
+
+#if ! USE_GEOS
+PG_FUNCTION_INFO_V1(centroid);
+Datum centroid(PG_FUNCTION_ARGS)
+{
+	LWGEOM *geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+	int type = lwgeom_getType(geom->type);
+	int ndims = lwgeom_ndims(geom->type);
+	int SRID = lwgeom_getSRID(geom);
+	LWGEOM_EXPLODED *exp = lwgeom_explode(SERIALIZED_FORM(geom));
+	LWPOLY *poly;
+	LWPOINT *point;
+	LWGEOM *result;
+	POINTARRAY *ring;
+	POINT3D *p, cent;
+	int i,j,k;
+	uint32 num_points_tot = 0;
+	char *srl;
+	char wantbbox = 0;
+
+	if  (type != POLYGONTYPE && type != MULTIPOLYGONTYPE)
+		PG_RETURN_NULL();
+
+	//find the centroid
+	for (i=0; i<exp->npolys; i++)
+	{
+		poly = lwpoly_deserialize(exp->polys[i]);
+		for (j=0; j<poly->nrings; j++)
+		{
+			ring = poly->rings[j];
+			for (k=0; k<ring->npoints-1; k++)
+			{
+				p = (POINT3D *)getPoint(ring, k);
+				tot_x += p.x;
+				tot_y += p.y;
+				if ( ring->ndims > 2 ) tot_z += p.z;
+			}
+			num_points_tot += ring->npoints-1;
+		}
+		pfree_polygon(poly);
+	}
+	pfree_exploded(exp);
+
+	// Setup point
+	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(&cent, poly->ndims, 1);
+
+	// Construct LWPOINT
+	point = lwpoint_construct(ndims, SRID, pa);
+
+	// Serialize LWPOINT 
+	srl = lwpoint_serialize(point);
+
+	pfree_point(point);
+	pfree_POINTARRAY(pa);
+
+	// Construct output LWGEOM
+	result = LWGEOM_construct(srl, poly->SRID, wantbbox);
+
+	PG_RETURN_POINTER(result);
+}
+#endif // ! USE_GEOS
diff --git a/lwgeom/lwgeom_geos.c b/lwgeom/lwgeom_geos.c
index ce72dbbd1..b80d901c5 100644
--- a/lwgeom/lwgeom_geos.c
+++ b/lwgeom/lwgeom_geos.c
@@ -1716,11 +1716,4 @@ Datum unite_garray(PG_FUNCTION_ARGS)
 	PG_RETURN_NULL(); // never get here
 }
 
-PG_FUNCTION_INFO_V1(centroid);
-Datum centroid(PG_FUNCTION_ARGS)
-{
-	elog(ERROR, "postgis version of centroid calculation not ported yet");
-	PG_RETURN_NULL(); // never get here
-}
-
 #endif // ! USE_GEOS
diff --git a/lwgeom/lwgeom_ogc.c b/lwgeom/lwgeom_ogc.c
index 7e103f254..fb52d3c80 100644
--- a/lwgeom/lwgeom_ogc.c
+++ b/lwgeom/lwgeom_ogc.c
@@ -559,7 +559,7 @@ Datum LWGEOM_z_point(PG_FUNCTION_ARGS)
 	geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
 
 	// if there's no Z return 0
-	if ( lwgeom_ndims(geom->type) < 2 ) PG_RETURN_FLOAT8(0.0);
+	if ( lwgeom_ndims(geom->type) < 3 ) PG_RETURN_FLOAT8(0.0);
 
 	inspected = lwgeom_inspect(SERIALIZED_FORM(geom));
 
diff --git a/lwgeom/lwpostgis.sql.in b/lwgeom/lwpostgis.sql.in
index f0b27c48d..2313a3fe5 100644
--- a/lwgeom/lwpostgis.sql.in
+++ b/lwgeom/lwpostgis.sql.in
@@ -2484,7 +2484,7 @@ CREATEFUNCTION geometry(chip)
 -- 7.3+ explicit casting definitions
 #if USE_VERSION >= 73
 CREATE CAST (geometry AS box2d) WITH FUNCTION box2d(geometry) AS IMPLICIT;
-CREATE CAST (geometry AS box3d) WITH FUNCTION box3d(geometry) AS IMPLICI ;
+CREATE CAST (geometry AS box3d) WITH FUNCTION box3d(geometry) AS IMPLICIT;
 CREATE CAST (geometry AS box) WITH FUNCTION box(geometry) AS IMPLICIT;
 CREATE CAST (box3d AS box2d) WITH FUNCTION box2d(box3d) AS IMPLICIT;
 CREATE CAST (box2d AS box3d) WITH FUNCTION box3d(box2d) AS IMPLICIT;
@@ -2614,16 +2614,42 @@ CREATEFUNCTION overlaps(geometry,geometry)
    AS '@MODULE_FILENAME@'
    LANGUAGE 'C' WITH (isstrict);
 
-CREATEFUNCTION isvalid(geometry)
+CREATEFUNCTION IsValid(geometry)
    RETURNS boolean
-   AS '@MODULE_FILENAME@'
+   AS '@MODULE_FILENAME@', 'isvalid'
    LANGUAGE 'C' WITH (isstrict);
 
-CREATEFUNCTION geosnoop(geometry)
+CREATEFUNCTION GEOSnoop(geometry)
    RETURNS geometry
    AS '@MODULE_FILENAME@', 'GEOSnoop'
    LANGUAGE 'C' WITH (isstrict);
 
+-- This is also available w/out GEOS 
+CREATEFUNCTION Centroid(geometry)
+	RETURNS geometry
+	AS '@MODULE_FILENAME@'
+	LANGUAGE 'C' WITH (isstrict);
+
+CREATEFUNCTION IsRing(geometry)
+	RETURNS boolean
+	AS '@MODULE_FILENAME@'
+	LANGUAGE 'C' WITH (isstrict);
+
+CREATEFUNCTION PointOnSurface(geometry)
+	RETURNS geometry
+	AS '@MODULE_FILENAME@'
+	LANGUAGE 'C' WITH (isstrict);
+	
+CREATEFUNCTION IsSimple(geometry)
+	RETURNS boolean
+	AS '@MODULE_FILENAME@', 'issimple'
+	LANGUAGE 'C' WITH (isstrict,iscachable);
+
+CREATEFUNCTION Equals(geometry,geometry)
+	RETURNS boolean
+	AS '@MODULE_FILENAME@','geomequals'
+	LANGUAGE 'C' WITH (isstrict,iscachable);
+
 ---------------------------------------------------------------
 -- END
 ---------------------------------------------------------------