Tiles along the antimeridian are always empty for table sources with a positive buffer and a SRID of 4326 #982
Description
I'm working with a polygonal table with srid 4326 in PostGIS, whose extents span the non-contiguous United States. I'd like to be able to visualize the entire dataset at once, which means I need to generate tiles at a very low zoom level. I have Martin set up with the simplest table source configuration imaginable, specifically something like the following:
table_id:
schema: public
table: table_name
geometry_column: geometry
srid: 4326
minzoom: 2
maxzoom: 13
geometry_type: POLYGON
Martin is impressively fast at generating a zoom level 2 tile for the eastern US (tile (2, 1, 1)), but generates an empty tile for the western US (tile (2, 0, 1)), despite there being quite a bit of data within the extents of the tile.
In looking into it, I've found that seemingly all tiles along the antimeridian (those for which the tile coordinate x = 0 or x = 2^n - 1) end up empty when a positive buffer is specified on a table source with SRID 4326. The crux of the issue is that the search bounding box for such tiles ends up crossing the antimeridian when there is a positive buffer. But SRID 4326 polygons that cross the antimeridian don't operate well with bounding box intersections due to the circular nature of longitudes. So when Martin tries to get geometries within the bounding box, it actually ends up getting features only outside of the actual tile area.
One can find the erroneous code in table_source.rs. Specifically, the buffered bounding box is calculated as something akin to: ST_TileEnvelope(z, x, y, margin => buffer / extent)
. The features that go into tile are then queried via something akin to
SELECT ... FROM table WHERE geometry && ST_Transform(buffered_bounding_box, srid)
For the case of tile (2, 0, 1) above, the default buffer of 64, and the default extent of 4096, the post-transform buffered bounding box ends up being POLYGON((178.59375 -1.406108835435152,178.59375 67.06743335108297,-88.59375 67.06743335108297,-88.59375 -1.406108835435152,178.59375 -1.406108835435152))
, which does not intersect the actual tile in SRID 4326. Indeed, the result of
SELECT ST_Transform(ST_TileEnvelope(2, 0, 1, margin => 0.0), 4326) && ST_Transform(ST_TileEnvelope(2, 0, 1, margin => 64.0 / 4096.0), 4326);
is false, which implies that any geometry within the expected tile will not make its way into the resulting tile.
A workaround is to use a buffer of zero, which enforces that the tile envelope doesn't cross the antimeridian. But that is unideal for some purposes, so I am requesting a more permanent solution that properly handles this case.
One possible solution is to use the ST_ShiftLongitude
function when working with a tile of zoom greater than one along the antimeridian. Another might be to transform the feature geometry into SRID 3857 (Web Mercator) instead of converting the bounding box to the table's SRID, but I'm unsure of if that would work in all cases.