Commit 35db4ea0 authored by Raúl Marín Rodríguez's avatar Raúl Marín Rodríguez
Browse files

St_AsMVTGeom: Fix bug when clipping an invalid geometry

If the geometry becomes invalid after simplifying, the clipping
could be invalid too. For those cases we drop the geometry.


git-svn-id: http://svn.osgeo.org/postgis/trunk@16856 b70326c6-7e19-0410-871a-916f4a2858ee
parent a8ba4a75
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ PostGIS 3.0.0
  - #4161, MVT: Drop geometries smaller than the resolution (Raúl Marín)
  - #4176, ST_Intersects supports GEOMETRYCOLLECTION (Darafei Praliaskouski)
  - #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.5.0
2018/09/23
+23 −3
Original line number Diff line number Diff line
@@ -894,11 +894,31 @@ LWGEOM *mvt_geom(LWGEOM *lwgeom, const GBOX *gbox, uint32_t extent, uint32_t buf
			double y0 = bgbox.ymin;
			double x1 = bgbox.xmax;
			double y1 = bgbox.ymax;
			lwgeom = 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");
			if (lwgeom == NULL || lwgeom_is_empty(lwgeom))
				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)))
			{
				/* TODO: Adapt this when and if Exception Policies are introduced.
				 * 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 = clipped_geom;
		}
	}

	/* transform to tile coordinate space */
+8 −0
Original line number Diff line number Diff line
@@ -265,6 +265,14 @@ SELECT 'PG44', ST_AsEWKT(ST_AsMVTGeom(
	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_AsMVTGeom(ST_GeomFromText('POINT(25 17)'),
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ PG42 - OFF|LINESTRING(0 10,0 0,1 0)
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)))
PG44|
PG45|
TG1|GiEKBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBKIAgeAI=
TG2|GiMKBHRlc3QSDhICAAAYASIGETLePwIBGgJjMSICKAEogCB4Ag==
TG3|GiYKBHRlc3QSERICAAAYAiIJCQCAQArQD88PGgJjMSICKAEogCB4Ag==