From: Sandro Santilli Date: Wed, 14 Dec 2011 18:25:05 +0000 (+0000) Subject: Regress test all behaviors involving EMPTY geometries X-Git-Tag: 2.0.0alpha1~458 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c35cc257f983151aade662d81689423190c97417;p=postgis Regress test all behaviors involving EMPTY geometries See http://trac.osgeo.org/postgis/wiki/DevWikiEmptyGeometry Changes ST_NumPoints and ST_ExteriorRing to behave requested. Keeps ST_InteriorRingN returning NULL, as per "n is out of range" Closes #692 git-svn-id: http://svn.osgeo.org/postgis/trunk@8415 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/postgis/lwgeom_ogc.c b/postgis/lwgeom_ogc.c index 4fa45f77d..114af9ff9 100644 --- a/postgis/lwgeom_ogc.c +++ b/postgis/lwgeom_ogc.c @@ -223,7 +223,11 @@ Datum LWGEOM_numgeometries_collection(PG_FUNCTION_ARGS) int32 ret = 1; lwgeom = lwgeom_from_gserialized(geom); - if ( lwgeom_is_collection(lwgeom) ) + if ( lwgeom_is_empty(lwgeom) ) + { + ret = 0; + } + else if ( lwgeom_is_collection(lwgeom) ) { LWCOLLECTION *col = lwgeom_as_lwcollection(lwgeom); ret = col->ngeoms; @@ -336,12 +340,12 @@ Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS) if( lwgeom_is_empty(lwgeom) ) { - PG_RETURN_NULL(); - lwgeom_free(lwgeom); - PG_FREE_IF_COPY(geom, 0); + line = lwline_construct_empty(lwgeom->srid, + lwgeom_has_z(lwgeom), + lwgeom_has_m(lwgeom)); + result = geometry_serialize(lwline_as_lwgeom(line)); } - - if ( lwgeom->type == POLYGONTYPE ) + else if ( lwgeom->type == POLYGONTYPE ) { LWPOLY *poly = lwgeom_as_lwpoly(lwgeom); diff --git a/regress/empty.sql b/regress/empty.sql index 6085cb022..784688b5b 100644 --- a/regress/empty.sql +++ b/regress/empty.sql @@ -29,3 +29,107 @@ SELECT 'T3.15', ST_AsGML(3,'POLYGON EMPTY'::geometry); SELECT 'T3.16', ST_AsGML(3,'MULTIPOLYGON EMPTY'::geometry); SELECT 'T3.17', ST_AsGML(3,'MULTILINESTRING EMPTY'::geometry); SELECT 'T3.18', ST_AsGML(3,'GEOMETRYCOLLECTION EMPTY'::geometry); + +-- See http://trac.osgeo.org/postgis/wiki/DevWikiEmptyGeometry + +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry, + 120 as tolerance + ) SELECT 'ST_Buffer(empty, tolerance) == empty', ST_Buffer(empty, tolerance) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Union(geometry, empty) == geometry', ST_Union(geometry, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_Union(empty, empty) == empty', ST_Union(empty, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Intersection(geometry, empty) == geometry', ST_Intersection(geometry, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_Intersection(empty, empty) == empty', ST_Intersection(empty, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Difference(geometry, empty) == geometry', ST_Difference(geometry, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Difference(empty, geometry) == empty', ST_Difference(empty, geometry) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Distance(geometry, empty) == NULL', ST_Distance(geometry, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry, + 120 as tolerance + ) SELECT 'ST_DWithin(geometry, empty, tolerance) == FALSE', ST_DWithin(geometry, empty, tolerance) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Within(geometry, empty) == FALSE', ST_Within(geometry, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Contains(empty, geometry) == FALSE', ST_Contains(empty, geometry) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Within(empty, geometry) == FALSE', ST_Within(empty, geometry) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_Contains(empty, empty) == FALSE', ST_Contains(empty, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Intersects(geometry, empty) == FALSE', ST_Intersects(geometry, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_Intersects(empty, empty) == FALSE', ST_Intersects(empty, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Disjoint(empty, empty) == TRUE', ST_Disjoint(empty, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 'POLYGON((0 0, 10 0, 5 5, 0 0))'::geometry as geometry + ) SELECT 'ST_Disjoint(geometry, empty) == TRUE', ST_Disjoint(geometry, empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_IsSimple(empty) == TRUE', ST_IsSimple(empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_IsValid(empty) == TRUE', ST_IsValid(empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_NumGeometries(empty) == 0', ST_NumGeometries(empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_NRings(empty) == 0', ST_NRings(empty) FROM inp; +WITH inp AS (SELECT + 'LINESTRING EMPTY'::geometry as empty + ) SELECT 'ST_NumPoints(empty) == 0', ST_NumPoints(empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_NPoints(empty) == 0', ST_NPoints(empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 1 as n + ) SELECT 'ST_GeometryN(empty, n) == empty', ST_GeometryN(empty, n) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_ExteriorRing(empty) == empty', ST_ExteriorRing(empty) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty, + 1 as n + ) SELECT 'ST_InteriorRingN(empty, n) == NULL', ST_InteriorRingN(empty, n) FROM inp; +WITH inp AS (SELECT + 'POLYGON EMPTY'::geometry as empty + ) SELECT 'ST_Area(empty) == 0', ST_Area(empty) FROM inp; +WITH inp AS (SELECT + 'LINESTRING EMPTY'::geometry as empty + ) SELECT 'ST_Length(empty) == 0', ST_Length(empty) FROM inp; diff --git a/regress/empty_expected b/regress/empty_expected index becccfec5..2c26d135b 100644 --- a/regress/empty_expected +++ b/regress/empty_expected @@ -23,3 +23,31 @@ T3.15| T3.16| T3.17| T3.18| +ST_Buffer(empty, tolerance) == empty|010300000000000000 +ST_Union(geometry, empty) == geometry|0103000000010000000400000000000000000000000000000000000000000000000000244000000000000000000000000000001440000000000000144000000000000000000000000000000000 +ST_Union(empty, empty) == empty|010300000000000000 +ST_Intersection(geometry, empty) == geometry|010300000000000000 +ST_Intersection(empty, empty) == empty|010300000000000000 +ST_Difference(geometry, empty) == geometry|0103000000010000000400000000000000000000000000000000000000000000000000244000000000000000000000000000001440000000000000144000000000000000000000000000000000 +ST_Difference(empty, geometry) == empty|010300000000000000 +ST_Distance(geometry, empty) == NULL| +ST_DWithin(geometry, empty, tolerance) == FALSE|f +ST_Within(geometry, empty) == FALSE|f +ST_Contains(empty, geometry) == FALSE|f +ST_Within(empty, geometry) == FALSE|f +ST_Contains(empty, empty) == FALSE|f +ST_Intersects(geometry, empty) == FALSE|f +ST_Intersects(empty, empty) == FALSE|f +ST_Disjoint(empty, empty) == TRUE|t +ST_Disjoint(geometry, empty) == TRUE|t +ST_IsSimple(empty) == TRUE|t +ST_IsValid(empty) == TRUE|t +ST_NumGeometries(empty) == 0|0 +ST_NRings(empty) == 0|0 +ST_NumPoints(empty) == 0|0 +ST_NPoints(empty) == 0|0 +ST_GeometryN(empty, n) == empty|010300000000000000 +ST_ExteriorRing(empty) == empty|010200000000000000 +ST_InteriorRingN(empty, n) == NULL| +ST_Area(empty) == 0|0 +ST_Length(empty) == 0|0