2

I have been searching for a while for a way to correctly project the ST_AsMVT to ensure it fits to the map. The below query was the only suggestion I found that will correctly transform to the mapbox EPSG:3857 coord system.

However, I have noticed at the global extent zoom levels the bounding box is clipping it seems. Just wondered if there is anything obvious that I have missed here given that other than this it projects perfectly. The screenshot is using an example with natural earth country polygons imported into postgis.

I also noticed that sometimes there is a square cut out the middle too which when researching looked like a smilier issue with the way different systems cut the grid of the earth?

I have also seen a few Postgis BBox functions but none of them work like the SQL below.

    WITH webmercator(envelope) AS (
      SELECT ST_TileEnvelope(${z}, ${x}, ${y})
    ),
    wgs84(envelope) AS (
      SELECT ST_Transform((SELECT envelope FROM webmercator), 4326)
    ),
    geometries(wkb_geometry) AS (
      SELECT ST_Transform(wkb_geometry, 3857)
      FROM ${table}
      WHERE wkb_geometry && (SELECT envelope FROM wgs84)
    )
    SELECT ST_AsMVT(tile) as mvt FROM (
      SELECT  ST_AsMVTGeom(wkb_geometry, (SELECT envelope FROM webmercator))
      FROM geometries
    ) AS tile

enter image description here

Zooming and moving viewport, reveals the polygon (Just to show it does have all the data) enter image description here

1 Answer 1

5

Your geometries go beyond the range of validity for your projection, so those tiles are failing to render. You need to clip them before you transform (or alternately, clip your tile envelopes before you query, so they don't pull data that is out of range)

WITH webmercator(envelope) AS (
      SELECT ST_TileEnvelope(${z}, ${x}, ${y})
    ),
    wgs84(envelope) AS (
      SELECT ST_Transform((SELECT envelope FROM webmercator), 4326)
    ),
    b(bounds) AS (
      SELECT ST_MakeEnvelope(-180, -85.0511287798066, 180, 85.0511287798066, 4326)
    )
    geometries(wkb_geometry) AS (
      SELECT 
        CASE WHEN ST_Covers(b.bounds, wkb_geometry)
             THEN ST_Transform(wkb_geometry,3857) 
             ELSE ST_Transform(ST_Intersection(b.bounds, wkb_geometry),3857) 
             END
      FROM ${table}
      CROSS JOIN b
      WHERE wkb_geometry && (SELECT envelope FROM wgs84)
    )
    SELECT ST_AsMVT(tile) as mvt FROM (
      SELECT  ST_AsMVTGeom(wkb_geometry, (SELECT envelope FROM webmercator))
      FROM geometries
    ) AS tile
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.