From b35d731fe9a4c26e2adb8ad0ec2f8184d4c3371e Mon Sep 17 00:00:00 2001 From: Daniel Baston Date: Wed, 1 Aug 2018 15:37:26 +0000 Subject: [PATCH] Revert lwgeom_clip_by_rect to use GEOSClipByRect This commit reverts lwgeom_clip_by_rect to its implementation in PostGIS 2.2 - 2.4. It makes trivial modifications to the MVT tests to reflect the different results returned by GEOSClipByRect instead of GEOSIntersection. The changed results are topologically equivalent to the previous results, and their orientation is unchanged. No tests have been commented out or made version-dependent. Closes #4134 Closes #4135 References #4038 Closes https://github.com/postgis/postgis/pull/282 git-svn-id: http://svn.osgeo.org/postgis/trunk@16679 b70326c6-7e19-0410-871a-916f4a2858ee --- NEWS | 3 +-- doc/reference_processing.xml | 9 ++++---- liblwgeom/lwgeom_geos.c | 44 ++++++++++++++++-------------------- regress/clipbybox2d_expected | 6 ++--- regress/mvt_expected | 8 ++----- 5 files changed, 31 insertions(+), 39 deletions(-) diff --git a/NEWS b/NEWS index d1dcd958d..7fdf5ba1e 100644 --- a/NEWS +++ b/NEWS @@ -93,8 +93,7 @@ PostGIS 2.5.0 - #4006, ST_GeomFromGeoJSON support for json and jsonb as input (Paul Ramsey, Regina Obe) - #4038, ST_Subdivide now selects pivot for geometry split that reuses input - vertices. ST_ClipByBox2D is stubbed with ST_Intersection because of - robustness issues. (Darafei Praliaskouski) + vertices. (Darafei Praliaskouski) - #4025, #4032 Fixed precision issue in ST_ClosestPointOfApproach, ST_DistanceCPA, and ST_CPAWithin (Paul Ramsey, Darafei Praliaskouski) - #4076, Reduce use of GEOS in topology implementation (Björn Harrtell) diff --git a/doc/reference_processing.xml b/doc/reference_processing.xml index 6149b5fe5..dd412603c 100644 --- a/doc/reference_processing.xml +++ b/doc/reference_processing.xml @@ -489,15 +489,16 @@ FROM (SELECT ST_Buffer( Description - -Clips a geometry by a 2D box. + + Clips a geometry by a 2D box in a fast but possibly dirty way. + The output geometry is not guaranteed to be valid (self-intersections for a polygon may be introduced). + Topologically invalid input geometries do not result in exceptions being thrown. + Performed by the GEOS module. Requires GEOS 3.5.0+ Availability: 2.2.0 - requires GEOS >= 3.5.0. - Changed: 2.5.0 - wrapper around ST_Intersection to work around GEOS bugs. - No longer supports invalid input geometry. diff --git a/liblwgeom/lwgeom_geos.c b/liblwgeom/lwgeom_geos.c index 1ad52b023..9d4ac9cb4 100644 --- a/liblwgeom/lwgeom_geos.c +++ b/liblwgeom/lwgeom_geos.c @@ -858,35 +858,31 @@ LWGEOM * lwgeom_clip_by_rect(const LWGEOM *geom1, double x1, double y1, double x2, double y2) { LWGEOM *result; - LWGEOM *tmp; + GEOSGeometry *g1, *g3; + int is3d; - /* This lwgeom_intersection should be a call to GEOSClipByRect: - * g3 = GEOSClipByRect(g1, x1, y1, x2, y2); - * Unfortunately as of GEOS 3.7 it chokes on practical inputs. - * GEOS ticket: https://trac.osgeo.org/geos/ticket/865 - */ + /* A.Intersection(Empty) == Empty */ + if ( lwgeom_is_empty(geom1) ) + return lwgeom_clone_deep(geom1); - LWGEOM *envelope = (LWGEOM *)lwpoly_construct_envelope(geom1->srid, x1, y1, x2, y2); - result = lwgeom_intersection(geom1, envelope); - lwgeom_free(envelope); + is3d = FLAGS_GET_Z(geom1->flags); - if (!result) return NULL; + initGEOS(lwnotice, lwgeom_geos_error); - /* clipping should not produce lower dimension objects */ - if ( - /* input has exact dimensionality, isn't a generic collection */ - geom1->type != COLLECTIONTYPE && - /* output may have different things inside */ - result->type == COLLECTIONTYPE) - { - tmp = lwcollection_as_lwgeom(lwcollection_extract(lwgeom_as_lwcollection(result), lwgeom_dimension(geom1) + 1)); - lwfree(result); - result = tmp; - if (!result) return NULL; - } + if (!(g1 = LWGEOM2GEOS(geom1, AUTOFIX))) + GEOS_FAIL(); + + if (!(g3 = GEOSClipByRect(g1, x1, y1, x2, y2))) + GEOS_FREE_AND_FAIL(g1); + + GEOS_FREE(g1); + result = GEOS2LWGEOM(g3, is3d); + GEOS_FREE(g3); + + if (!result) + GEOS_FAIL(); - /* clean up stray points on geometry boundary */ - lwgeom_simplify_in_place(result, 0.0, LW_TRUE); + result->srid = geom1->srid; return result; } diff --git a/regress/clipbybox2d_expected b/regress/clipbybox2d_expected index f02439f13..8986b641e 100644 --- a/regress/clipbybox2d_expected +++ b/regress/clipbybox2d_expected @@ -1,9 +1,9 @@ 1|BOX(5 5,10 10) 2|BOX(5 5,8 8) 3|BOX(2 2,8 8) -4|MULTIPOINT(0 0,2 2) -ERROR: lwgeom_intersection: GEOS Error: TopologyException: Input geom 0 is invalid: Self-intersection -6|MULTIPOLYGON(((2.5 2,5 4,5 5,10 5,10 2,2.5 2))) +4|POINT(2 2) +5|POLYGON((2 2,8 2,2 8,8 8,2 2)) +6|POLYGON((2.5 2,5 4,5 5,5 4,7.5 2,2.5 2)) 7|POLYGON((2 2,2 5,5 5,5 2,2 2)) 8|SRID=3857;POLYGON EMPTY 9|SRID=4326;POINT(0 0) diff --git a/regress/mvt_expected b/regress/mvt_expected index 830a94d2d..ea5f234ea 100644 --- a/regress/mvt_expected +++ b/regress/mvt_expected @@ -6,7 +6,7 @@ PG5| PG6|POLYGON((894 2704,600 594,2791 594,894 2704)) PG7|POLYGON((1252 1904,1253 1905,1253 1906,1251 1904,1252 1904)) PG8|MULTIPOLYGON(((5 4096,10 4091,10 4096,5 4096)),((5 4096,0 4101,0 4096,5 4096))) -PG9|POLYGON((4096 4096,0 4096,0 0,4096 0,4096 4096)) +PG9|POLYGON((0 4096,0 0,4096 0,4096 4096,0 4096)) PG10| PG11|POLYGON((0 10,0 0,10 0,10 10,0 10)) PG12|POLYGON((0 10,0 0,10 0,10 10,0 10)) @@ -44,11 +44,7 @@ PG41 - ON |LINESTRING(0 10,0 4,0 2,0 0,1 0) PG41 - OFF|LINESTRING(0 10,0 4,0 2,0 0,1 0) PG42 - ON |LINESTRING(0 10,0 0,1 0) PG42 - OFF|LINESTRING(0 10,0 0,1 0) -NOTICE: lwgeom_intersection: GEOS Error: TopologyException: Input geom 0 is invalid: Self-intersection -NOTICE: Self-intersection -NOTICE: Your geometry dataset is not valid per OGC Specification. Please fix it with manual review of entries that are not ST_IsValid(geom). Retrying GEOS operation with ST_MakeValid of your input. -NOTICE: Self-intersection -PG43 - ON |MULTIPOLYGON(((0 10,5 5,10 10,0 10)),((5 5,0 0,10 0,5 5))) +PG43 - ON |MULTIPOLYGON(((5 5,0 0,10 0,5 5)),((0 10,5 5,10 10,0 10))) PG43 - OFF|MULTIPOLYGON(((5 5,-1 -1,11 -1,5 5)),((5 5,11 11,-1 11,5 5))) TG1|GiEKBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBKIAgeAI= TG2|GiMKBHRlc3QSDhICAAAYASIGETLePwIBGgJjMSICKAEogCB4Ag== -- 2.40.0