t-rex-tileserver / t-rex

t-rex is a vector tile server specialized on publishing MVT tiles from your own data
https://t-rex.tileserver.ch/
MIT License
556 stars 69 forks source link

Buffer region not served as part of the vector tile #314

Closed hamarituc closed 6 months ago

hamarituc commented 7 months ago

I encountered an issue where the buffer region of tiles is not served to the client.

Steps to reproduce

  1. Consider the following data in a PostGIS database
BEGIN;
CREATE TABLE "public"."test" ( "ogc_fid" SERIAL, CONSTRAINT "test_pk" PRIMARY KEY ("ogc_fid") );
SELECT AddGeometryColumn('public','test','wkb_geometry',25833,'POLYGON',2);
CREATE INDEX "test_wkb_geometry_geom_idx" ON "public"."test" USING GIST ("wkb_geometry");
INSERT INTO "public"."test" ("wkb_geometry" , "ogc_fid" ) VALUES ('0103000020E964000001000000050000009AA6C935869C154110164AAEEB7D55410E92AED1A09C15410E9FB145EE7D554178EADB7FCD9C15413B2A246DEB7D55418E44E7E2989C15411D3A977BEA7D55419AA6C935869C154110164AAEEB7D5541', 1);
INSERT INTO "public"."test" ("wkb_geometry" , "ogc_fid" ) VALUES ('0103000020E9640000010000000500000092E008F4179D1541534A8CE8EF7D5541BA518FE92F9D1541A47BCA5FED7D5541341B6238FA9C154171581624EC7D5541C3CA4C05DF9C15413675F754F07D554192E008F4179D1541534A8CE8EF7D5541', 2);
INSERT INTO "public"."test" ("wkb_geometry" , "ogc_fid" ) VALUES ('0103000020E96400000100000006000000023A12A91A9D154167CE46A0F37D55413236D5033A9D15413FFE54E8F27D5541DCBE1A20359D1541CABD12D9F17D55413E4F782A419D1541078DD709F07D554118FCCDC60E9D154136BDE349F07D5541023A12A91A9D154167CE46A0F37D5541', 3);
INSERT INTO "public"."test" ("wkb_geometry" , "ogc_fid" ) VALUES ('0103000020E9640000010000000400000023173BB3B89C1541FD196035EA7D55415954A095C79C1541A63D3AA9E87D5541AB142256D79C154159990D34EA7D554123173BB3B89C1541FD196035EA7D5541', 4);
INSERT INTO "public"."test" ("wkb_geometry" , "ogc_fid" ) VALUES ('0103000020E964000001000000050000002EE515095A9C15417FC68947F47D5541704A76218B9C1541618A4738F77D5541DFE97506CC9C1541E1C4BEF9F17D5541133529E45A9C15413048178FF17D55412EE515095A9C15417FC68947F47D5541', 5);
INSERT INTO "public"."test" ("wkb_geometry" , "ogc_fid" ) VALUES ('0103000020E964000001000000050000005C84D2275C9C15418E1EA353F07D554176BCCBA6819C15411D415EFCEF7D55410C1A04257F9C1541F43B6077EE7D55414C1200FB4C9C1541E9A6B3E9EE7D55415C84D2275C9C15418E1EA353F07D5541', 6);
INSERT INTO "public"."test" ("wkb_geometry" , "ogc_fid" ) VALUES ('0103000020E9640000010000000500000055487DCD589C154156222501EE7D5541C714C0706E9C154184D3A3C3ED7D554156540F1E6C9C1541D7E2667EEC7D55412966C7475C9C15415A164C7FEC7D554155487DCD589C154156222501EE7D5541', 7);
INSERT INTO "public"."test" ("wkb_geometry" , "ogc_fid" ) VALUES ('0103000020E96400000100000005000000147B7306D69C154124585008F67D55413EC200D2D99C1541356B1CEBF27D55413D5F9FE8FC9C1541397C7E6BF27D554106D8B1FEFA9C1541043E24ADF57D5541147B7306D69C154124585008F67D5541', 8);
COMMIT;
  1. Configure T-Rex to serve tiles from this database
[service.mvt]
viewer = false

[[datasource]]
name = "test"
dbconn = "as required"

[grid]
predefined = "web_mercator"

[[tileset]]
name = "test"
#minzoom = 15
#maxzoom = 22
extent = { minx = 12.9053, maxx = 12.9609, miny = 50.7920, maxy = 50.8538 }
center = [ 12.92804, 50.83904 ]
start_zoom = 17

[[tileset.layer]]
name = "test"
datasource = "test"
geometry_field = "geom"
geometry_type = "POLYGON"
srid = 25833
fid_field = "ogc_fid"
# Clip polygons with a buffer
buffer_size = 200
simplify = false

  [[tileset.layer.query]]
  minzoom = 17
  maxzoom = 24
  sql = "SELECT ogc_fid, wkb_geometry AS geom FROM test WHERE wkb_geometry && !bbox!"

[cache.file]
base = "/tmp/trex/cache"

[webserver]
bind = "localhost"
port = 6767
  1. Fetch a tile from /vector/test/19/280971/175891.pbf

Observed Behavior

The buffer region of the tile is not served to the client. Loading 175891.pbf into QGis shows:

grafik

Expected Behavior

The served tile should contain a buffer region of 200 pixels as specified in the configuration file.

grafik

The mid-blue polygon should be served instead of the light-blue polygon.

The geometry of the mid-blue polygon was derived from the SQL statement I found on the trace logs.

SELECT
  ST_Transform(
    ST_Multi(
      ST_Buffer(
        ST_Intersection(
          geom,
          ST_Transform(
            ST_Segmentize(
              ST_MakeEnvelope(
                1439079.9315250143-12.5*0.2985821417389698::FLOAT8,
                6592846.563653022-12.5*0.2985821417389698::FLOAT8,
                1439156.3685532995+12.5*0.2985821417389698::FLOAT8,
                6592923.000681307+12.5*0.2985821417389698::FLOAT8,3857),
                (1439156.3685532995-1439079.9315250143)/512),
                25833
              )
            ),
            0.0
          )
        ),
        3857
      ) AS geom,"ogc_fid"
FROM
(
  SELECT ogc_fid, wkb_geometry AS geom
  FROM test
  WHERE wkb_geometry &&
    ST_Transform(
      ST_Segmentize(
        ST_MakeEnvelope(
          1439079.9315250143-12.5*0.2985821417389698::FLOAT8,
          6592846.563653022-12.5*0.2985821417389698::FLOAT8,
          1439156.3685532995+12.5*0.2985821417389698::FLOAT8,
          6592923.000681307+12.5*0.2985821417389698::FLOAT8,
          3857
        ),
        (1439156.3685532995-1439079.9315250143)/512
      ),
      25833
    )
)
AS _q

It seems the buffered geometry is delivered correctly to T-Rex, but there further clipping is applied. When configuring a buffer size, I expect the buffered geometry to be served. Otherwise it wouldn't make sense to specify a buffer.

The buffer is necessary as some renderers require this buffer for proper rendering. If you choose to draw an area with a thick border line style for example, tile borders might get rendered as polygon borders, too as the renderer is unable to distinguish between tile boundaries and polygon boundaries.

pka commented 6 months ago

Thanks fo rthe very detailed report. I tried to reproduce the problem with bbox the successor of t-rex. The result displayed by QGIS looks exactly the same:

image

BBOX does use PostGIS ST_AsMvt with the given buffer size which should give the same result as the t-rex query above.

My explanation is, that QGIS does only shows the part of the geomtry within the tile bounds and not the buffer around the tile. So probably the geometry content is the one you expect, but not fully displayed. Maybe you find a MVT debugging tool, which shows also the geometry part of the buffer around the tile?

hamarituc commented 6 months ago

Indeed. I thought I double checked for it. I now learned the CLIP option for the MVT import driver only works, if the driver is able to guess the tile coordinates which requires a file name like {Z}-{X}-{Y}.pbf. Setting CLIP to NO reveals the buffer.

Now the border artifacts in my original application are gone. It seems there was some other error which lead me to this assumption.