Opened 16 hours ago

Last modified 14 hours ago

#5799 new defect

ST_TileEnvelope with margin is not clipped fully to WM extent

Reported by: mdavis Owned by: pramsey
Priority: medium Milestone: PostGIS 3.5.1
Component: postgis Version: 3.5.x
Keywords: Cc:

Description

When executing ST_TileEnvelope with a margin parameter the resulting polygon is only partially clipped to the WebMercator maximum extents. This causes problems in downstream processing (e.g. when converting to geodetic via ST_Transform( env, 4326)).

For example, the tile envelope for (z=1, x=0, y=1) is:

SELECT ST_AsText( ST_TileEnvelope(1,0,1));

POLYGON((-20037508.342789244 -20037508.342789244,-20037508.342789244 0,0 0,0 -20037508.342789244,-20037508.342789244 -20037508.342789244))

With a margin of 0.1 the result is:

SELECT ST_AsText( ST_TileEnvelope(1,0,1, margin => 0.1));

POLYGON((-22041259.17706817 -20037508.342789244,-22041259.17706817 2003750.834278924,2003750.8342789263 2003750.834278924,2003750.8342789263 -20037508.342789244,-22041259.17706817 -20037508.342789244))

This is clipped in the Y dimension to the WM extents (-20037508.342789 -20037508.342789, 20037508.342789 20037508.342789). But it extends beyond the X extent to the left. It should also be clipped in the X dimension, to avoid causing problems with further computation.

Change History (3)

comment:1 by mdavis, 15 hours ago

The code clips the Y dimension, but not the X dimension.

Version 0, edited 15 hours ago by mdavis (next)

comment:2 by mdavis, 15 hours ago

A workaround is to clip the generated envelope to the WM bounds:

-- clip tile envelope to WebMercator bounds
ST_Intersection(
     ST_MakeEnvelope(-20037508.342789, -20037508.342789,20037508.342789, 20037508.342789, 3857),
     ST_TileEnvelope(z, x, y, margin => 0.125) )

comment:3 by mdavis, 14 hours ago

Here's a drop-in function to fix the clipping behaviour:

CREATE OR REPLACE FUNCTION ST_TileEnvelopeClip(zoom integer, x integer, y integer, bounds geometry DEFAULT 'SRID=3857;LINESTRING(-20037508.342789244 -20037508.342789244, 20037508.342789244 20037508.342789244)'::geometry, margin float8 DEFAULT 0.0)
	RETURNS geometry
AS $$
    SELECT ST_Intersection( ST_Envelope(bounds), ST_TileEnvelope(zoom, x, y, bounds, margin))
$$
LANGUAGE 'sql' STABLE STRICT PARALLEL SAFE;
Note: See TracTickets for help on using tickets.