]> granicus.if.org Git - postgis/commitdiff
ST_AsMVTGeom: Clip using tile coordinates also for buffer 0
authorRaúl Marín Rodríguez <rmrodriguez@carto.com>
Tue, 17 Jul 2018 09:02:10 +0000 (09:02 +0000)
committerRaúl Marín Rodríguez <rmrodriguez@carto.com>
Tue, 17 Jul 2018 09:02:10 +0000 (09:02 +0000)
Closes https://github.com/postgis/postgis/pull/272
References #4120

git-svn-id: http://svn.osgeo.org/postgis/trunk@16648 b70326c6-7e19-0410-871a-916f4a2858ee

postgis/mvt.c
regress/mvt.sql
regress/mvt_expected

index 2cdb2e86c2cd382ffa9025a296d19e8f794578c6..d36191135be83be78ad16e57c9aab41a330b0871 100644 (file)
@@ -696,11 +696,7 @@ LWGEOM *mvt_geom(LWGEOM *lwgeom, const GBOX *gbox, uint32_t extent, uint32_t buf
        gridspec grid;
        double width = gbox->xmax - gbox->xmin;
        double height = gbox->ymax - gbox->ymin;
-       double resx = width / extent;
-       double resy = height / extent;
-       double res = (resx < resy ? resx : resy)/2;
-       double fx = extent / width;
-       double fy = -(extent / height);
+       double resx, resy, res, fx, fy;
        int preserve_collapsed = LW_TRUE;
        POSTGIS_DEBUG(2, "mvt_geom called");
 
@@ -714,6 +710,12 @@ LWGEOM *mvt_geom(LWGEOM *lwgeom, const GBOX *gbox, uint32_t extent, uint32_t buf
        if (extent == 0)
                elog(ERROR, "mvt_geom: extent cannot be 0");
 
+       resx = width / extent;
+       resy = height / extent;
+       res = (resx < resy ? resx : resy)/2;
+       fx = extent / width;
+       fy = -(extent / height);
+
        /* Remove all non-essential points (under the output resolution) */
        lwgeom_remove_repeated_points_in_place(lwgeom, res);
        lwgeom_simplify_in_place(lwgeom, res, preserve_collapsed);
@@ -726,10 +728,9 @@ LWGEOM *mvt_geom(LWGEOM *lwgeom, const GBOX *gbox, uint32_t extent, uint32_t buf
        {
                // We need to add an extra half pixel to include the points that
                // fall into the bbox only after the coordinate transformation
-               double buffer_map_xunits = !buffer ?
-                       0.0 : nextafterf(resx * (buffer + 0.5), 0.0);
+               double buffer_map_xunits = nextafterf(res, 0.0) + resx * buffer;
                GBOX bgbox;
-               const GBOX *lwgeom_gbox = lwgeom_get_bbox(lwgeom);;
+               const GBOX *lwgeom_gbox = lwgeom_get_bbox(lwgeom);
                bgbox = *gbox;
                gbox_expand(&bgbox, buffer_map_xunits);
                if (!gbox_overlaps_2d(lwgeom_gbox, &bgbox))
index a4bb0aad4b71b49a4dcc319c762835f30ee80fe0..10f8cc3da982a77dde150a5b3c06c6e4a390e3cb 100644 (file)
@@ -204,6 +204,59 @@ SELECT 'PG38', ST_AsText(ST_AsMVTGeom(
        ST_MakeBox2D(ST_Point(0, 0), ST_Point(4096, 4096)),
        4096, 256, true));
 
+SELECT 'PG39 - ON ', ST_AsText(ST_AsMVTGeom(
+       ST_GeomFromText('POLYGON((0 100, 100 100, 100 90, 94 90, 94 96, 90 96, 90 80, 100 80, 100 0, 0 0, 0 100))'),
+       ST_MakeBox2D(ST_Point(0, 0), ST_Point(100, 100)),
+       10, 0, true));
+
+SELECT 'PG39 - OFF', ST_AsText(ST_AsMVTGeom(
+       ST_GeomFromText('POLYGON((0 100, 100 100, 100 90, 94 90, 94 96, 90 96, 90 80, 100 80, 100 0, 0 0, 0 100))'),
+       ST_MakeBox2D(ST_Point(0, 0), ST_Point(100, 100)),
+       10, 0, false));
+
+-- Clipping isn't done since all points fall into the tile after grid
+SELECT 'PG40 - ON ', ST_AsText(ST_AsMVTGeom(
+       ST_GeomFromText('LINESTRING(0 0, 2 20, -2 40, -4 60, 4 80, 0 100)'),
+       ST_MakeBox2D(ST_Point(0, 0), ST_Point(100, 100)),
+       10, 0, true));
+
+SELECT 'PG40 - OFF', ST_AsText(ST_AsMVTGeom(
+       ST_GeomFromText('LINESTRING(0 0, 2 20, -2 40, -4 60, 4 80, 0 100)'),
+       ST_MakeBox2D(ST_Point(0, 0), ST_Point(100, 100)),
+       10, 0, false));
+
+-- Clipping isn't done since all points fall into the tile after grid
+SELECT 'PG41 - ON ', ST_AsText(ST_AsMVTGeom(
+       ST_GeomFromText('LINESTRING(0 0, 2 20, -2 40, -4 60, 4 80, 0 100, 10 100)'),
+       ST_MakeBox2D(ST_Point(0, 0), ST_Point(100, 100)),
+       10, 0, true));
+
+SELECT 'PG41 - OFF', ST_AsText(ST_AsMVTGeom(
+       ST_GeomFromText('LINESTRING(0 0, 2 20, -2 40, -4 60, 4 80, 0 100, 10 100)'),
+       ST_MakeBox2D(ST_Point(0, 0), ST_Point(100, 100)),
+       10, 0, false));
+
+SELECT 'PG42 - ON ', ST_AsText(ST_AsMVTGeom(
+       ST_GeomFromText('LINESTRING(0 0, 2 20, -2 40, -4 60, 4 80, 0 100, 11 100)'),
+       ST_MakeBox2D(ST_Point(0, 0), ST_Point(100, 100)),
+       10, 0, true));
+
+SELECT 'PG42 - OFF', ST_AsText(ST_AsMVTGeom(
+       ST_GeomFromText('LINESTRING(0 0, 2 20, -2 40, -4 60, 4 80, 0 100, 11 100)'),
+       ST_MakeBox2D(ST_Point(0, 0), ST_Point(100, 100)),
+       10, 0, false));
+
+-- Invalid polygon (intersection)
+SELECT 'PG43 - ON ', ST_AsText(ST_AsMVTGeom(
+       ST_GeomFromText('POLYGON((-10 -10, 110 110, -10 110, 110 -10, -10 -10))'),
+       ST_MakeBox2D(ST_Point(0, 0), ST_Point(100, 100)),
+       10, 0, true));
+
+SELECT 'PG43 - OFF', ST_AsText(ST_AsMVTGeom(
+       ST_GeomFromText('POLYGON((-10 -10, 110 110, -10 110, 110 -10, -10 -10))'),
+       ST_MakeBox2D(ST_Point(0, 0), ST_Point(100, 100)),
+       10, 0, false));
+
 -- 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)'),
index 35926ccf311c4efe50fc6c1839921737a65c69cb..830a94d2d590d1b322c63badec3a969d26a1b8c9 100644 (file)
@@ -36,6 +36,20 @@ PG35|POINT(4352 4352)
 PG36|
 PG37|
 PG38|
+PG39 - ON |POLYGON((0 0,10 0,9 2,10 2,10 10,0 10,0 0))
+PG39 - OFF|POLYGON((0 0,10 0,9 2,10 2,10 10,0 10,0 0))
+PG40 - ON |LINESTRING(0 10,0 0)
+PG40 - OFF|LINESTRING(0 10,0 0)
+PG41 - ON |LINESTRING(0 10,0 4,0 2,0 0,1 0)
+PG41 - OFF|LINESTRING(0 10,0 4,0 2,0 0,1 0)
+PG42 - ON |LINESTRING(0 10,0 0,1 0)
+PG42 - OFF|LINESTRING(0 10,0 0,1 0)
+NOTICE:  lwgeom_intersection: GEOS Error: TopologyException: Input geom 0 is invalid: Self-intersection
+NOTICE:  Self-intersection
+NOTICE:  Your geometry dataset is not valid per OGC Specification. Please fix it with manual review of entries that are not ST_IsValid(geom). Retrying GEOS operation with ST_MakeValid of your input.
+NOTICE:  Self-intersection
+PG43 - ON |MULTIPOLYGON(((0 10,5 5,10 10,0 10)),((5 5,0 0,10 0,5 5)))
+PG43 - OFF|MULTIPOLYGON(((5 5,-1 -1,11 -1,5 5)),((5 5,11 11,-1 11,5 5)))
 TG1|GiEKBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBKIAgeAI=
 TG2|GiMKBHRlc3QSDhICAAAYASIGETLePwIBGgJjMSICKAEogCB4Ag==
 TG3|GiYKBHRlc3QSERICAAAYAiIJCQCAQArQD88PGgJjMSICKAEogCB4Ag==