From: Sandro Santilli Date: Wed, 16 Feb 2011 10:19:22 +0000 (+0000) Subject: Expose versions of ST_IsValid and ST_IsValidReason accepting "the ESRI flag" and... X-Git-Tag: 2.0.0alpha1~1972 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=876edb5576377f1a85f3b95164f8551c945234ec;p=postgis Expose versions of ST_IsValid and ST_IsValidReason accepting "the ESRI flag" and implemented as wrappers to ST_IsValidDetail. Only available when building against GEOS-3.3+. Commit includes documentation and regress-testing. Closes ticket #831 [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@6828 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/doc/reference_accessor.xml b/doc/reference_accessor.xml index fe159e8c9..ad6d9368c 100644 --- a/doc/reference_accessor.xml +++ b/doc/reference_accessor.xml @@ -1057,6 +1057,12 @@ FROM (SELECT 'LINESTRING(0 0, 0 1, 1 0, 1 1, 0 0)'::geometry AS the_geom) AS foo geometry g + + boolean ST_IsValid + + geometry g + integer flags + @@ -1066,15 +1072,24 @@ FROM (SELECT 'LINESTRING(0 0, 0 1, 1 0, 1 1, 0 0)'::geometry AS the_geom) AS foo Test if an ST_Geometry value is well formed. For geometries that are invalid, the PostgreSQL NOTICE will provide details of why it is not valid. For more information on the OGC's definition of geometry simplicity and validity, refer - to "Ensuring OpenGIS compliancy of geometries" + to "Ensuring OpenGIS compliancy of geometries" + SQL-MM defines the result of ST_IsValid(NULL) to be 0, while PostGIS returns NULL. + +The version accepting flags is available starting with 2.0.0 +and requires GEOS >= 3.3.0. Such version does not print a NOTICE +explaining the invalidity. +Allowed flags are documented in . + + &sfs_compliant; &sqlmm_compliant; SQL-MM 3: 5.1.9 + @@ -1115,6 +1130,11 @@ NOTICE: Self-intersection at or near point 0 0 text ST_IsValidReason geometry geomA + + text ST_IsValidReason + geometry geomA + integer flags + @@ -1124,7 +1144,13 @@ NOTICE: Self-intersection at or near point 0 0 Returns text stating if a geometry is valid or not an if not valid, a reason why. Useful in combination with ST_IsValid to generate a detailed report of invalid geometries and reasons. + + +Allowed flags are documented in . + + Availability: 1.4 - requires GEOS >= 3.1.0. + Availability: 2.0 - requires GEOS >= 3.3.0 for the version taking flags. diff --git a/postgis/postgis.sql.in.c b/postgis/postgis.sql.in.c index 751fbc73c..f6593fc95 100644 --- a/postgis/postgis.sql.in.c +++ b/postgis/postgis.sql.in.c @@ -2945,6 +2945,31 @@ CREATE OR REPLACE FUNCTION ST_IsValidDetail(geometry, int4) LANGUAGE 'C' IMMUTABLE STRICT COST 100; +#if POSTGIS_GEOS_VERSION >= 33 +-- Requires GEOS >= 3.3.0 +-- Availability: 2.0.0 +CREATE OR REPLACE FUNCTION ST_IsValidReason(geometry, int4) + RETURNS text + AS $$ +SELECT CASE WHEN valid THEN 'Valid Geometry' ELSE reason END FROM ( + SELECT (ST_isValidDetail($1, $2)).* +) foo + $$ + LANGUAGE 'sql' IMMUTABLE STRICT + COST 100; +#endif + +#if POSTGIS_GEOS_VERSION >= 33 +-- Requires GEOS >= 3.3.0 +-- Availability: 2.0.0 +CREATE OR REPLACE FUNCTION ST_IsValid(geometry, int4) + RETURNS boolean + AS 'SELECT (ST_isValidDetail($1, $2)).valid' + LANGUAGE 'sql' IMMUTABLE STRICT + COST 100; +#endif + + #if POSTGIS_GEOS_VERSION >= 32 -- Requires GEOS >= 3.2.0 -- Availability: 1.5.0 diff --git a/regress/isvaliddetail.sql b/regress/isvaliddetail.sql index 552ae1c2e..994d57f50 100644 --- a/regress/isvaliddetail.sql +++ b/regress/isvaliddetail.sql @@ -30,6 +30,10 @@ select 5, valid, reason, st_astext(location) FROM ( 0 -- No flags )).* ) foo; +select '5s', ST_IsValid( +'POLYGON ((70 250, 40 500, 100 400, 70 250, 80 350, 60 350, 70 250))' , 0); +select '5r', ST_IsValidReason( +'POLYGON ((70 250, 40 500, 100 400, 70 250, 80 350, 60 350, 70 250))' , 0); -- Self-touching ring forming hole with ESRI flag select 6, valid, reason, st_astext(location) FROM ( @@ -39,3 +43,9 @@ select 6, valid, reason, st_astext(location) FROM ( 1 -- ESRI flag )).* ) foo; +select '6s', ST_IsValid( +'POLYGON ((70 250, 40 500, 100 400, 70 250, 80 350, 60 350, 70 250))' , 1); +select '5r', ST_IsValidReason( +'POLYGON ((70 250, 40 500, 100 400, 70 250, 80 350, 60 350, 70 250))' , 1); + + diff --git a/regress/isvaliddetail_expected b/regress/isvaliddetail_expected index 50a057ca5..1ae00d1b6 100644 --- a/regress/isvaliddetail_expected +++ b/regress/isvaliddetail_expected @@ -3,4 +3,8 @@ 3|f|Self-intersection|POINT(70 400) 4|f|Self-intersection|POINT(70 400) 5|f|Ring Self-intersection|POINT(70 250) +5s|f +5r|Ring Self-intersection 6|t|| +6s|t +5r|Valid Geometry