From: Sandro Santilli 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; inpolys; i++) + { + poly = lwpoly_deserialize(exp->polys[i]); + for (j=0; jnrings; j++) + { + ring = poly->rings[j]; + for (k=0; knpoints-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(¢, 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 ---------------------------------------------------------------