[postgis-tickets] r16858 - St_AsMVTGeom: Drop invalid geometries after simplification

Raul raul at rmr.ninja
Mon Oct 1 06:44:58 PDT 2018


Author: algunenano
Date: 2018-10-01 06:44:58 -0700 (Mon, 01 Oct 2018)
New Revision: 16858

Modified:
   branches/2.4/NEWS
   branches/2.4/postgis/mvt.c
   branches/2.4/regress/mvt.sql
   branches/2.4/regress/mvt_expected
Log:
St_AsMVTGeom: Drop invalid geometries after simplification

Closes #4183


Modified: branches/2.4/NEWS
===================================================================
--- branches/2.4/NEWS	2018-10-01 13:31:52 UTC (rev 16857)
+++ branches/2.4/NEWS	2018-10-01 13:44:58 UTC (rev 16858)
@@ -4,6 +4,7 @@
   * Bug Fixes and Enhancements
   - #4160, Use qualified names in topology extension install (Raúl Marín)
   - #4181, St_AsMVTGeom: Avoid type changes due to validation (Raúl Marín)
+  - #4183, St_AsMVTGeom: Drop invalid geometries after simplification (Raúl Marín)
 
 
 PostGIS 2.4.5

Modified: branches/2.4/postgis/mvt.c
===================================================================
--- branches/2.4/postgis/mvt.c	2018-10-01 13:31:52 UTC (rev 16857)
+++ branches/2.4/postgis/mvt.c	2018-10-01 13:44:58 UTC (rev 16858)
@@ -699,12 +699,37 @@
 			LWPOLY *lwenv = lwpoly_construct_envelope(0, x0, y0, x1, y1);
 			lwgeom_out = lwgeom_intersection(lwgeom, lwpoly_as_lwgeom(lwenv));
 			lwpoly_free(lwenv);
+			if (lwgeom_out == NULL || lwgeom_is_empty(lwgeom_out))
+			{
+				POSTGIS_DEBUG(3, "mvt_geom: no geometry after clip");
+				return NULL;
+			}
 #else
-			lwgeom_out = lwgeom_clip_by_rect(lwgeom, x0, y0, x1, y1);
+			const GBOX pre_clip_box = *lwgeom_get_bbox(lwgeom);
+			LWGEOM *clipped_geom = lwgeom_clip_by_rect(lwgeom, x0, y0, x1, y1);
+			if (clipped_geom == NULL || lwgeom_is_empty(clipped_geom))
+			{
+				POSTGIS_DEBUG(3, "mvt_geom: no geometry after clip");
+				return NULL;
+			}
+			/* For some polygons, the simplify step might have left them
+			 * as invalid, which can cause clipping to return the complementary
+			 * geometry of what it should */
+			if ((lwgeom->type == POLYGONTYPE ||
+				lwgeom->type == MULTIPOLYGONTYPE ||
+				lwgeom->type == COLLECTIONTYPE) &&
+			    !gbox_contains_2d(&pre_clip_box, lwgeom_get_bbox(clipped_geom)))
+			{
+				/* Other options would be to fix the geometry and
+				 * retry or to calculate the difference between the
+				 * 2 boxes */
+				POSTGIS_DEBUG(3, "mvt_geom: Invalid geometry after clipping");
+				lwgeom_free(clipped_geom);
+				return NULL;
+			}
+			lwgeom_out = clipped_geom;
 #endif
-			POSTGIS_DEBUG(3, "mvt_geom: no geometry after clip");
-			if (lwgeom_out == NULL || lwgeom_is_empty(lwgeom_out))
-				return NULL;
+
 		}
 	}
 

Modified: branches/2.4/regress/mvt.sql
===================================================================
--- branches/2.4/regress/mvt.sql	2018-10-01 13:31:52 UTC (rev 16857)
+++ branches/2.4/regress/mvt.sql	2018-10-01 13:44:58 UTC (rev 16858)
@@ -51,6 +51,14 @@
 	16,
 	true));
 
+-- Invalid geometry after simplification with invalid clipping
+SELECT 'PG45', ST_AsEWKT(ST_AsMVTGeom(
+	'SRID=3857;MULTIPOLYGON(((-8231365.02893734 4980355.83678553,-8231394.82332406 4980186.31880185,-8231367.43081065 4979982.17443372,-8231396.69199339 4980227.59327083,-8231365.02893734 4980355.83678553)))'::geometry,
+	'SRID=3857;POLYGON((-8238115.3789773 4970203.10870116,-8238115.3789773 4980063.48534995,-8228255.00232851 4980063.48534995,-8228255.00232851 4970203.10870116,-8238115.3789773 4970203.10870116))'::geometry,
+	4096,
+	16,
+	true));
+
 -- geometry encoding tests
 SELECT 'TG1', encode(ST_AsMVT(q, 'test', 4096, 'geom'), 'base64') FROM (SELECT 1 AS c1,
     ST_Normalize(ST_AsMVTGeom(ST_GeomFromText('POINT(25 17)'),

Modified: branches/2.4/regress/mvt_expected
===================================================================
--- branches/2.4/regress/mvt_expected	2018-10-01 13:31:52 UTC (rev 16857)
+++ branches/2.4/regress/mvt_expected	2018-10-01 13:44:58 UTC (rev 16858)
@@ -9,6 +9,7 @@
 PG9|POLYGON((0 0,0 4096,4096 4096,4096 0,0 0))
 PG10|
 PG44|
+PG45|
 TG1|GiEKBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBKIAgeAI=
 TG2|GiMKBHRlc3QSDhICAAAYASIGETTcPwECGgJjMSICKAEogCB4Ag==
 TG3|GiYKBHRlc3QSERICAAAYAiIJCQCAQArQD88PGgJjMSICKAEogCB4Ag==



More information about the postgis-tickets mailing list