ST_AsMVTGeom assumes the input geometries to be projected in EPSG:3857; while it will happily return a scaled geometry for any coordinates within the (default or custom) bounds, they will not fit into the ST_TileEnvelope passed to ST_AsMVT.

Likewise, ST_TileEnvelope returns a Polygon projected in EPSG:3857; running an ST_Intersects check against geometries with any other CRS reference will fail.

Instead, wrap your geometries in ST_Transform:

WITH mvtgeom AS
(
  SELECT u_id,
         ST_AsMVTGeom(
           ST_Transform(feat_polygon.geom, 3857),
           ST_TileEnvelope(19, 369963, 215620)
         ) AS geom
  FROM   feat_polygon
  WHERE  ST_Intersects(
           ST_Transform(feat_polygon.geom, 3857),
           ST_TileEnvelope(19, 369963, 215620)
         )
)
SELECT ST_AsMVT(mvtgeom.*,  feature_id_name => 'u_id')
FROM   mvtgeom
;

Note that you may want to either create a functional index on the projected geometries, i.e.

CREATE INDEX ON feat_polygon USING GIST ((ST_Transform(geom, 3857));

or reproject and REINDEX the table, i.e.

ALTER TABLE feat_polygon
  ALTER COLUMN geom TYPE GEOMETRY(POLYGON, 3857)
    USING ST_Transform(geom, 3857)
;

to utilize the index in your filter.

Pedantic note: you may also want to move the main CTE into a subquery, while outsourcing the ST_TileEnvelope into a CTE and JOIN with feat_polygon to avoid multiple calls.


ST_AsMVT returns a BYTEA value that holds a protobuf (pbf) encoded Vector Tile: you should be able to serialize a binary protobuf response body using

content_type="application/octet-stream"

and pass it to whatever mapping framework that can decode the pbf according to the Vector Tile specs.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top