2
votes

Our platform currently uses pbf tiles(on s3) to render vector layers on Mapbox on the frontend. The pbf tiles have separate layers within them and we use Mapbox layers' source-layer property to style them as separate layers. We are now moving to PostGIS and we want to avoid s3 and directly render the vector tiles as mvt on the frontend.

I am trying to get separate layers from the mvt but the only layer I see is a 'default' layer. I identified this using this vizualizer tool. I am currently getting the mvt using this query -

WITH mvtgeom AS (     
SELECT ST_AsMVTGeom(ST_Transform(ST_Force2D(geom), 3857), 
ST_TileEnvelope(${z}, ${x}, ${y})) 
   AS geom,
   layer, 
   gid
   FROM site-name
   WHERE ST_Intersects(geom, ST_Transform(ST_TileEnvelope(${z}, ${x}, ${y}), 4326)))
SELECT ST_AsMVT(mvtgeom.*) AS mvt FROM mvtgeom;

This issue is very close to my problem but the answer suggests using a UNION, which I want to avoid if possible considering we have to render hundreds of layers. I also tried this. In this case, when I put the values of my layer-ids into an IN, I see that those set of layers are rendered as one layer.

(Is there something I need to explore in order to understand how vector tiles are generated so I know how exactly the separate layers are generated? I am new to PostGIS, and I'm not sure if I'm doing something wrong or missing something. Any suggestions are appreciated)

1

1 Answers

1
votes

Below is the full return signature of ST_AsMvt

bytea ST_AsMVT(anyelement row, text name, integer extent, text geom_name, text feature_id_name);

Later in the docs:

name is the name of the layer. Default is the string "default".

Try using the id (or label, or some other thing specific to each layer) to create a distinct layer name for each layer:

WITH mvtgeom AS (     
   SELECT
     ST_AsMVTGeom(ST_Transform(ST_Force2D(geom), 3857) AS geom
     , layer
     , gid
   FROM
     site-name
   WHERE
     ST_Intersects(
       geom,
       ST_Transform(ST_TileEnvelope(${z}, ${x}, ${y}), 4326)
     )
)
SELECT
  ST_AsMVT(
    mvtgeom.*,
    'layer_' || layer -- this is the layer name argument
  ) AS mvt
FROM
  mvtgeom
GROUP BY
  layer;

This name property, by the way, is what mapbox uses as the "source layer"