From f4e7bcead07cd8a8094e2372852f9281e17d80f6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bj=C3=B6rn=20Harrtell?= Date: Fri, 28 Apr 2017 21:07:50 +0000 Subject: [PATCH] Rework ST_AsMVTGeom clipping logic Closes #3740 git-svn-id: http://svn.osgeo.org/postgis/trunk@15378 b70326c6-7e19-0410-871a-916f4a2858ee --- postgis/lwgeom_out_mvt.c | 2 ++ postgis/mvt.c | 35 +++++++++++++++++++++++++---------- regress/mvt.sql | 4 ++++ regress/mvt_expected | 1 + 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/postgis/lwgeom_out_mvt.c b/postgis/lwgeom_out_mvt.c index b797773c8..107ce428e 100644 --- a/postgis/lwgeom_out_mvt.c +++ b/postgis/lwgeom_out_mvt.c @@ -62,6 +62,8 @@ Datum ST_AsMVTGeom(PG_FUNCTION_ARGS) 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); diff --git a/postgis/mvt.c b/postgis/mvt.c index a2e039ff6..d125d0024 100644 --- a/postgis/mvt.c +++ b/postgis/mvt.c @@ -497,6 +497,9 @@ LWGEOM *mvt_geom(LWGEOM *lwgeom, GBOX *gbox, uint32_t extent, uint32_t buffer, 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 @@ LWGEOM *mvt_geom(LWGEOM *lwgeom, GBOX *gbox, uint32_t extent, uint32_t buffer, 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 *mvt_geom(LWGEOM *lwgeom, GBOX *gbox, uint32_t extent, uint32_t buffer, lwgeom_out = lwgeom_homogenize(lwgeom_out); } + if (lwgeom == NULL || lwgeom_is_empty(lwgeom)) + return NULL; + return lwgeom_out; } diff --git a/regress/mvt.sql b/regress/mvt.sql index 68b156d66..4dc84fa87 100644 --- a/regress/mvt.sql +++ b/regress/mvt.sql @@ -35,6 +35,10 @@ select 'PG8', ST_AsText(ST_AsMVTGeom( 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, diff --git a/regress/mvt_expected b/regress/mvt_expected index b90af1bdb..2f20a1387 100644 --- a/regress/mvt_expected +++ b/regress/mvt_expected @@ -6,6 +6,7 @@ PG5|POINT(0 4096) 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== -- 2.50.1