]> granicus.if.org Git - postgis/commitdiff
Revert lwgeom_clip_by_rect to use GEOSClipByRect
authorDaniel Baston <dbaston@gmail.com>
Wed, 1 Aug 2018 15:37:26 +0000 (15:37 +0000)
committerDaniel Baston <dbaston@gmail.com>
Wed, 1 Aug 2018 15:37:26 +0000 (15:37 +0000)
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
doc/reference_processing.xml
liblwgeom/lwgeom_geos.c
regress/clipbybox2d_expected
regress/mvt_expected

diff --git a/NEWS b/NEWS
index d1dcd958d1472dd764d9ebb5d03e62508ccb5180..7fdf5ba1e211ee9446bdbc2715aeae2e5d8754e4 100644 (file)
--- 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)
index 6149b5fe5240f4d666dafc0356aae4d242f1415e..dd412603c148bb893ddc416e852aa9de9a42522a 100644 (file)
@@ -489,15 +489,16 @@ FROM (SELECT ST_Buffer(
          <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 &gt;= 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>
 
index 1ad52b023ab3af74fc4e88e9e5a8d5667cc7753c..9d4ac9cb46aeaec84c134a2438cd71077200a260 100644 (file)
@@ -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;
 }
index f02439f13805616651cd1d5363df0db46446be54..8986b641e7219b46c5299dee650f1fed70bb8b6b 100644 (file)
@@ -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)
index 830a94d2d590d1b322c63badec3a969d26a1b8c9..ea5f234eac018f8c2f68b66092f9cd6dde60addc 100644 (file)
@@ -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==