[postgis-tickets] r16679 - Revert lwgeom_clip_by_rect to use GEOSClipByRect

Daniel Baston dbaston at gmail.com
Wed Aug 1 08:37:26 PDT 2018


Author: dbaston
Date: 2018-08-01 08:37:26 -0700 (Wed, 01 Aug 2018)
New Revision: 16679

Modified:
   trunk/NEWS
   trunk/doc/reference_processing.xml
   trunk/liblwgeom/lwgeom_geos.c
   trunk/regress/clipbybox2d_expected
   trunk/regress/mvt_expected
Log:
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



Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2018-08-01 15:21:08 UTC (rev 16678)
+++ trunk/NEWS	2018-08-01 15:37:26 UTC (rev 16679)
@@ -93,8 +93,7 @@
   - #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)

Modified: trunk/doc/reference_processing.xml
===================================================================
--- trunk/doc/reference_processing.xml	2018-08-01 15:21:08 UTC (rev 16678)
+++ trunk/doc/reference_processing.xml	2018-08-01 15:37:26 UTC (rev 16679)
@@ -489,15 +489,16 @@
 	  <refsection>
 		<title>Description</title>
 
-    <para>
-Clips a geometry by a 2D box.</para>
+		<para>
+			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.
+		</para>
 
 		<para>Performed by the GEOS module.</para>
 		<note><para>Requires GEOS 3.5.0+</para></note>
 
 		<para>Availability: 2.2.0 - requires GEOS >= 3.5.0.</para>
-                <para>Changed: 2.5.0 - wrapper around ST_Intersection to work around GEOS bugs.
-                      No longer supports invalid input geometry.</para>
 
 	  </refsection>
 

Modified: trunk/liblwgeom/lwgeom_geos.c
===================================================================
--- trunk/liblwgeom/lwgeom_geos.c	2018-08-01 15:21:08 UTC (rev 16678)
+++ trunk/liblwgeom/lwgeom_geos.c	2018-08-01 15:37:26 UTC (rev 16679)
@@ -858,36 +858,32 @@
 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();
 
-	/* clean up stray points on geometry boundary */
-	lwgeom_simplify_in_place(result, 0.0, LW_TRUE);
+	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();
+
+	result->srid = geom1->srid;
+
 	return result;
 }
 

Modified: trunk/regress/clipbybox2d_expected
===================================================================
--- trunk/regress/clipbybox2d_expected	2018-08-01 15:21:08 UTC (rev 16678)
+++ trunk/regress/clipbybox2d_expected	2018-08-01 15:37:26 UTC (rev 16679)
@@ -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)

Modified: trunk/regress/mvt_expected
===================================================================
--- trunk/regress/mvt_expected	2018-08-01 15:21:08 UTC (rev 16678)
+++ trunk/regress/mvt_expected	2018-08-01 15:37:26 UTC (rev 16679)
@@ -6,7 +6,7 @@
 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 - 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==



More information about the postgis-tickets mailing list