[postgis-tickets] r15378 - Rework ST_AsMVTGeom clipping logic

bjorn at wololo.org bjorn at wololo.org
Fri Apr 28 14:07:50 PDT 2017


Author: bjornharrtell
Date: 2017-04-28 14:07:50 -0700 (Fri, 28 Apr 2017)
New Revision: 15378

Modified:
   trunk/postgis/lwgeom_out_mvt.c
   trunk/postgis/mvt.c
   trunk/regress/mvt.sql
   trunk/regress/mvt_expected
Log:
Rework ST_AsMVTGeom clipping logic
Closes #3740

Modified: trunk/postgis/lwgeom_out_mvt.c
===================================================================
--- trunk/postgis/lwgeom_out_mvt.c	2017-04-28 17:27:48 UTC (rev 15377)
+++ trunk/postgis/lwgeom_out_mvt.c	2017-04-28 21:07:50 UTC (rev 15378)
@@ -62,6 +62,8 @@
 	clip_geom = PG_ARGISNULL(4) ? true : PG_GETARG_BOOL(4);
 	lwgeom_out = mvt_geom(lwgeom_in, bounds, extent, buffer, clip_geom);
 	lwgeom_free(lwgeom_in);
+	if (lwgeom_out == NULL)
+		PG_RETURN_NULL();
 	geom_out = geometry_serialize(lwgeom_out);
 	lwgeom_free(lwgeom_out);
 	PG_FREE_IF_COPY(geom_in, 0);

Modified: trunk/postgis/mvt.c
===================================================================
--- trunk/postgis/mvt.c	2017-04-28 17:27:48 UTC (rev 15377)
+++ trunk/postgis/mvt.c	2017-04-28 21:07:50 UTC (rev 15378)
@@ -497,6 +497,9 @@
 	double resy = height / extent;
 	double fx = extent / width;
 	double fy = -(extent / height);
+	double buffer_map_xunits = resx * buffer;
+	double buffer_map_yunits = resy * buffer;
+	const GBOX *ggbox = lwgeom_get_bbox(lwgeom);
 
 	if (width == 0 || height == 0)
 		lwerror("mvt_geom: bounds width or height cannot be 0");
@@ -505,19 +508,28 @@
 		lwerror("mvt_geom: extent cannot be 0");
 
 	if (clip_geom) {
-		double buffer_map_xunits = resx * buffer;
-		double buffer_map_yunits = resy * buffer;
-		double x0 = gbox->xmin - buffer_map_xunits;
-		double y0 = gbox->ymin - buffer_map_yunits;
-		double x1 = gbox->xmax + buffer_map_xunits;
-		double y1 = gbox->ymax + buffer_map_yunits;
+		GBOX *bgbox = gbox_copy(gbox);
+		gbox_expand(bgbox, buffer_map_xunits);
+		if (!gbox_overlaps_2d(ggbox, bgbox)) {
+			POSTGIS_DEBUG(3, "mvt_geom: geometry outside clip box");
+			return NULL;
+		}
+		if (!gbox_contains_2d(bgbox, ggbox)) {
+			double x0 = bgbox->xmin;
+			double y0 = bgbox->ymin;
+			double x1 = bgbox->xmax;
+			double y1 = bgbox->ymax;
 #if POSTGIS_GEOS_VERSION < 35
-		LWPOLY *lwenv = lwpoly_construct_envelope(0, x0, y0, x1, y1);
-		lwgeom = lwgeom_intersection(lwgeom, lwpoly_as_lwgeom(lwenv));
-		lwpoly_free(lwenv);
+			LWPOLY *lwenv = lwpoly_construct_envelope(0, x0, y0, x1, y1);
+			lwgeom = lwgeom_intersection(lwgeom, lwpoly_as_lwgeom(lwenv));
+			lwpoly_free(lwenv);
 #else
-		lwgeom = lwgeom_clip_by_rect(lwgeom, x0, y0, x1, y1);
+			lwgeom = lwgeom_clip_by_rect(lwgeom, x0, y0, x1, y1);
 #endif
+			POSTGIS_DEBUG(3, "mvt_geom: no geometry after clip");
+			if (lwgeom == NULL || lwgeom_is_empty(lwgeom))
+				return NULL;
+		}
 	}
 
 	AFFINE affine;
@@ -552,6 +564,9 @@
 		lwgeom_out = lwgeom_homogenize(lwgeom_out);
 	}
 
+	if (lwgeom == NULL || lwgeom_is_empty(lwgeom))
+		return NULL;
+
 	return lwgeom_out;
 }
 

Modified: trunk/regress/mvt.sql
===================================================================
--- trunk/regress/mvt.sql	2017-04-28 17:27:48 UTC (rev 15377)
+++ trunk/regress/mvt.sql	2017-04-28 21:07:50 UTC (rev 15378)
@@ -35,6 +35,10 @@
     ST_GeomFromText('GEOMETRYCOLLECTION(MULTIPOLYGON (((0 0, 10 0, 10 5, 0 -5, 0 0))))'),
     ST_MakeBox2D(ST_Point(0, 0), ST_Point(4096, 4096)),
     4096, 0, false));
+select 'PG9', ST_AsText(ST_AsMVTGeom(
+	ST_GeomFromText('POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))'),
+	ST_MakeBox2D(ST_Point(0, 0), ST_Point(5, 5)),
+	4096, 0, true));
 
 -- geometry encoding tests
 SELECT 'TG1', encode(ST_AsMVT('test', 4096, 'geom', q), 'base64') FROM (SELECT 1 AS c1,

Modified: trunk/regress/mvt_expected
===================================================================
--- trunk/regress/mvt_expected	2017-04-28 17:27:48 UTC (rev 15377)
+++ trunk/regress/mvt_expected	2017-04-28 21:07:50 UTC (rev 15378)
@@ -6,6 +6,7 @@
 PG6|POLYGON((894 2704,2791 594,600 594,894 2704))
 PG7|POLYGON((1252 1904,1251 1904,1252 1905,1253 1906,1253 1905,1252 1904))
 PG8|MULTIPOLYGON(((5 4096,10 4096,10 4091,5 4096)),((0 4096,0 4101,5 4096,0 4096)))
+PG9|POLYGON((0 4096,4096 4096,4096 0,0 0,0 4096))
 TG1|GiEKBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBKIAgeAI=
 TG2|GiMKBHRlc3QSDhICAAAYASIGETLePwIBGgJjMSICKAEogCB4Ag==
 TG3|GiYKBHRlc3QSERICAAAYAiIJCQCAQArQD88PGgJjMSICKAEogCB4Ag==



More information about the postgis-tickets mailing list