[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