From: Daniel Baston Date: Mon, 25 Apr 2016 21:02:23 +0000 (+0000) Subject: #3424, ST_MinimumClearance X-Git-Tag: 2.3.0beta1~142 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e5e8645730c81d4f93772a549e78424e4037724e;p=postgis #3424, ST_MinimumClearance git-svn-id: http://svn.osgeo.org/postgis/trunk@14856 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/NEWS b/NEWS index 016785e0b..bf8c34375 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,7 @@ PostGIS 2.3.0 - #3339 ST_GeneratePoints (Paul Ramsey) - #3362 ST_ClusterDBSCAN (Dan Baston) - #3364 ST_GeometricMedian (Dan Baston) + - #3424 ST_MinimumClearance (Dan Baston) - #3428 ST_Points (Dan Baston) - #3465 ST_ClusterKMeans (Paul Ramsey) - #3469 ST_MakeLine with MULTIPOINTs (Paul Norman) diff --git a/doc/introduction.xml b/doc/introduction.xml index 35194c0c8..829ee79b6 100644 --- a/doc/introduction.xml +++ b/doc/introduction.xml @@ -264,6 +264,7 @@ Hunter Systems Group, Lidwala Consulting Engineers, LisaSoft, Logical Tracking & Tracing International AG, +Maponics, Michigan Tech Research Institute, Natural Resources Canada, Norwegian Forest and Landscape Institute, diff --git a/doc/reference_measure.xml b/doc/reference_measure.xml index b817a5dd0..cfd2e2900 100644 --- a/doc/reference_measure.xml +++ b/doc/reference_measure.xml @@ -2361,6 +2361,133 @@ FROM (SELECT + + + ST_MinimumClearance + Returns the minimum clearance of a geometry, a measure a geometry's robustness. + + + + + + float ST_MinimumClearance + geometry g + + + + + + Description + + + It is not uncommon to have a geometry that, while meeting the criteria for validity according to ST_IsValid (polygons) + or ST_IsSimple (lines), would become invalid if one of the vertices moved by a slight distance, as can happen during + conversion to text-based formats (such as WKT, KML, GML GeoJSON), or binary formats that do not use double-precision + floating point coordinates (MapInfo TAB). + + + + A geometry's "minimum clearance" is the smallest distance by which a vertex of the geometry could be moved to produce + an invalid geometry. It can be thought of as a quantitative measure of a geometry's robustness, where increasing values + of minimum clearance indicate increasing robustness. + + + + If a geometry has a minimum clearance of e, it can be said that: + + + + No two distinct vertices in the geometry are separated by less than e. + + + + + No vertex is closer than e to a line segement of which it is not an endpoint. + + + + + + + If no minimum clearance exists for a geometry (for example, a single point, or a multipoint whose points are identical), then + ST_MinimumClearance will return Infinity. + + + Availability: 2.3.0 - requires GEOS >= 3.6.0 + + + + + Examples + +SELECT ST_MinimumClearance('POLYGON ((0 0, 1 0, 1 1, 0.5 3.2e-4, 0 0))'); + st_minimumclearance +--------------------- + 0.00032 + + + + + + See Also + + + + + + + + + + ST_MinimumClearanceLine + Returns the two-point LineString spanning a geometry's minimum clearance. + + + + + + Geometry ST_MinimumClearanceLine + + geometry + g + + + + + + + Description + + + Returns the two-point LineString spanning a geometry's minimum clearance. If the geometry does not have a minimum + clearance, LINESTRING EMPTY will be returned. + + + Availability: 2.3.0 - requires GEOS >= 3.6.0 + + + + + Examples + +SELECT ST_AsText(ST_MinimumClearanceLine('POLYGON ((0 0, 1 0, 1 1, 0.5 3.2e-4, 0 0))')); +st_astext +------------------------------- +LINESTRING(0.5 0.00032,0.5 0) + + + + + See Also + + + + + + + + + ST_HausdorffDistance diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index 61079bce6..6678a9c12 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -3662,3 +3662,98 @@ Datum ST_Voronoi(PG_FUNCTION_ARGS) #endif /* POSTGIS_GEOS_VERSION >= 35 */ } + +/****************************************** + * + * ST_MinimumClearance + * + * Returns the minimum clearance of a geometry. + * + ******************************************/ +Datum ST_MinimumClearance(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(ST_MinimumClearance); +Datum ST_MinimumClearance(PG_FUNCTION_ARGS) +{ +#if POSTGIS_GEOS_VERSION < 36 + lwpgerror("The GEOS version this PostGIS binary " + "was compiled against (%d) doesn't support " + "'ST_MinimumClearance' function (3.6.0+ required)", + POSTGIS_GEOS_VERSION); + PG_RETURN_NULL(); +#else /* POSTGIS_GEOS_VERSION >= 36 */ + GSERIALIZED* input; + GEOSGeometry* input_geos; + int error; + double result; + + initGEOS(lwpgnotice, lwgeom_geos_error); + + input = PG_GETARG_GSERIALIZED_P(0); + input_geos = POSTGIS2GEOS(input); + if (!input_geos) /* exception thrown at construction */ + { + HANDLE_GEOS_ERROR("Geometry could not be converted to GEOS"); + PG_RETURN_NULL(); + } + + error = GEOSMinimumClearance(input_geos, &result); + GEOSGeom_destroy(input_geos); + if (error) + { + HANDLE_GEOS_ERROR("Error computing minimum clearance"); + PG_RETURN_NULL(); + } + + PG_FREE_IF_COPY(input, 0); + PG_RETURN_FLOAT8(result); +#endif +} + +/****************************************** + * + * ST_MinimumClearanceLine + * + * Returns the minimum clearance line of a geometry. + * + ******************************************/ +Datum ST_MinimumClearanceLine(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(ST_MinimumClearanceLine); +Datum ST_MinimumClearanceLine(PG_FUNCTION_ARGS) +{ +#if POSTGIS_GEOS_VERSION < 36 + lwpgerror("The GEOS version this PostGIS binary " + "was compiled against (%d) doesn't support " + "'ST_MinimumClearanceLine' function (3.6.0+ required)", + POSTGIS_GEOS_VERSION); + PG_RETURN_NULL(); +#else /* POSTGIS_GEOS_VERSION >= 36 */ + GSERIALIZED* input; + GSERIALIZED* result; + GEOSGeometry* input_geos; + GEOSGeometry* result_geos; + + initGEOS(lwpgnotice, lwgeom_geos_error); + + input = PG_GETARG_GSERIALIZED_P(0); + input_geos = POSTGIS2GEOS(input); + if (!input_geos) /* exception thrown at construction */ + { + HANDLE_GEOS_ERROR("Geometry could not be converted to GEOS"); + PG_RETURN_NULL(); + } + + result_geos = GEOSMinimumClearanceLine(input_geos); + GEOSGeom_destroy(input_geos); + if (!result_geos) + { + HANDLE_GEOS_ERROR("Error computing minimum clearance"); + PG_RETURN_NULL(); + } + + result = GEOS2POSTGIS(result_geos, LW_FALSE); + GEOSGeom_destroy(result_geos); + + PG_FREE_IF_COPY(input, 0); + PG_RETURN_POINTER(result); +#endif +} diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in index a01d0bc09..8fdcc3e7b 100644 --- a/postgis/postgis.sql.in +++ b/postgis/postgis.sql.in @@ -4001,6 +4001,18 @@ CREATE OR REPLACE FUNCTION ST_IsValid(geometry) LANGUAGE 'c' IMMUTABLE STRICT COST 100; +-- Availability: 2.3.0 +CREATE OR REPLACE FUNCTION ST_MinimumClearance(geometry) + RETURNS float8 + AS 'MODULE_PATHNAME', 'ST_MinimumClearance' + LANGUAGE 'c' IMMUTABLE STRICT; + +-- Availability: 2.3.0 +CREATE OR REPLACE FUNCTION ST_MinimumClearanceLine(geometry) + RETURNS geometry + AS 'MODULE_PATHNAME', 'ST_MinimumClearanceLine' + LANGUAGE 'c' IMMUTABLE STRICT; + -- PostGIS equivalent function: Centroid(geometry) CREATE OR REPLACE FUNCTION ST_Centroid(geometry) RETURNS geometry diff --git a/regress/Makefile.in b/regress/Makefile.in index 0fb564bbc..defdcfe8b 100644 --- a/regress/Makefile.in +++ b/regress/Makefile.in @@ -216,6 +216,12 @@ ifeq ($(shell expr $(POSTGIS_GEOS_VERSION) ">=" 35),1) voronoi endif +ifeq ($(shell expr $(POSTGIS_GEOS_VERSION) ">=" 36),1) + # GEOS-3.6 adds: + # ST_MinimumClearance + TESTS += \ + minimum_clearance +endif ifeq ($(HAVE_JSON),yes) # JSON-C adds: