From: Sandro Santilli Date: Mon, 22 Feb 2010 20:58:37 +0000 (+0000) Subject: Let ST_CleanGeometry down to C [RT-SIGTA] X-Git-Tag: 2.0.0alpha1~3198 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f82ff12fa23bd7227ef730df24505898957710d2;p=postgis Let ST_CleanGeometry down to C [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@5307 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/postgis/lwgeom_geos_clean.c b/postgis/lwgeom_geos_clean.c index fd631c530..c98b64f54 100644 --- a/postgis/lwgeom_geos_clean.c +++ b/postgis/lwgeom_geos_clean.c @@ -837,8 +837,8 @@ Datum ST_CleanGeometry(PG_FUNCTION_ARGS) #else /* POSTGIS_GEOS_VERSION >= 33 */ PG_LWGEOM *in, *out; - LWGEOM *lwgeom_in; - int is3d; + LWGEOM *lwgeom_in, *lwgeom_out; + /* int is3d; */ in = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); lwgeom_in = lwgeom_deserialize(SERIALIZED_FORM(in)); @@ -851,10 +851,44 @@ Datum ST_CleanGeometry(PG_FUNCTION_ARGS) PG_RETURN_POINTER(out); } - is3d = TYPE_HASZ(lwgeom_in->type); + /* is3d = TYPE_HASZ(lwgeom_in->type); */ + lwgeom_out = lwgeom_make_valid(lwgeom_in); + if ( ! lwgeom_out ) { + PG_FREE_IF_COPY(in, 0); + PG_RETURN_NULL(); + } + + /* Check dimensionality is the same as input */ + if ( lwgeom_dimensionality(lwgeom_in) != lwgeom_dimensionality(lwgeom_out) ) + { + lwnotice("ST_CleanGeometry: dimensional collapse (%d to %d)", + lwgeom_dimensionality(lwgeom_in), lwgeom_dimensionality(lwgeom_out)); + + PG_FREE_IF_COPY(in, 0); + PG_RETURN_NULL(); + } + + /* Check that the output is not a collection if the input wasn't */ + if ( TYPE_GETTYPE(lwgeom_out->type) == COLLECTIONTYPE && + TYPE_GETTYPE(lwgeom_in->type) != COLLECTIONTYPE ) + { + lwnotice("ST_CleanGeometry: mixed-type output (%s) from single-type input (%s)", + lwgeom_typename(TYPE_GETTYPE(lwgeom_out->type)), + lwgeom_typename(TYPE_GETTYPE(lwgeom_in->type))); + PG_FREE_IF_COPY(in, 0); + PG_RETURN_NULL(); + } + + /* Force right-hand-rule (will only affect polygons) */ + /* gout := ST_ForceRHR(gout); */ + + /* Remove repeated duplicated points ? */ + /* gout = ST_RemoveRepeatedPoints(gout); */ + + out = pglwgeom_serialize(lwgeom_out); + PG_RETURN_POINTER(out); - PG_RETURN_NULL(); #endif /* POSTGIS_GEOS_VERSION >= 33 */ } diff --git a/postgis/postgis.sql.in.c b/postgis/postgis.sql.in.c index 3400c6041..450322e7e 100644 --- a/postgis/postgis.sql.in.c +++ b/postgis/postgis.sql.in.c @@ -4075,48 +4075,9 @@ CREATE OR REPLACE FUNCTION ST_MakeValid(geometry) -- Availability: 2.0.0 CREATE OR REPLACE FUNCTION ST_CleanGeometry(geometry) RETURNS geometry - AS $$ -DECLARE - gin alias for $1; - pin geometry; - pout geometry; - pdif geometry; - gout geometry; -BEGIN - - RAISE DEBUG 'ST_CleanGeometry: in: %', ST_GeometryType(gin); - - -- Short-circuit: empty geometry are the cleanest ! - IF ST_isEmpty(gin) THEN - RETURN gin; - END IF; - - gout := ST_MakeValid(gin); - - -- Check dimensionality is the same as input - IF ST_Dimension(gin) != ST_Dimension(gout) THEN - RAISE NOTICE 'ST_CleanGeometry: dimensional collapse (% to %)', - ST_Dimension(gin), ST_Dimension(gout); - RETURN NULL; - END IF; - - -- Check that the output is not a collection if the input wasn't - IF ST_GeometryType(gin) != 'ST_GeometryCollection' AND ST_GeometryType(gout) = 'ST_GeometryCollection' THEN - RAISE NOTICE 'ST_CleanGeometry: mixed-type output (%) from single-type input (%)', - ST_GeometryType(gout), ST_GeometryType(gin); - RETURN NULL; - END IF; - - -- Force right-hand-rule (will only affect polygons) - gout := ST_ForceRHR(gout); - - -- Remove repeated duplicated points ? - -- gout = ST_RemoveRepeatedPoints(gout); - - RETURN gout; - -END -$$ LANGUAGE plpgsql; + AS 'MODULE_PATHNAME', 'ST_CleanGeometry' + LANGUAGE 'C' IMMUTABLE STRICT + COST 100; -------------------------------------------------------------------------------- -- Aggregates and their supporting functions