Opened 4 weeks ago

Closed 3 weeks ago

#5799 closed defect (fixed)

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 (9)

comment:1 by mdavis, 4 weeks ago

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

	/* Clip y-axis to the given bounds */
	if (y1 < bbox.ymin) y1 = bbox.ymin;
	if (y2 > bbox.ymax) y2 = bbox.ymax;
Last edited 4 weeks ago by mdavis (previous) (diff)

comment:2 by mdavis, 4 weeks 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, 4 weeks 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;

comment:4 by Paul Ramsey <pramsey@…>, 4 weeks ago

In 26eb973/git:

ST_TileEnvelope with margin is not clipped fully to WM extent, references #5799

comment:5 by Paul Ramsey <pramsey@…>, 4 weeks ago

In 7b24bdf/git:

ST_TileEnvelope with margin is not clipped fully to WM extent, references #5799

comment:6 by Paul Ramsey <pramsey@…>, 4 weeks ago

In 8c26a6ed/git:

ST_TileEnvelope with margin is not clipped fully to WM extent, references #5799

comment:7 by Paul Ramsey <pramsey@…>, 4 weeks ago

In 496db9d/git:

ST_TileEnvelope with margin is not clipped fully to WM extent, references #5799

comment:8 by Paul Ramsey <pramsey@…>, 4 weeks ago

In 8939d50/git:

ST_TileEnvelope with margin is not clipped fully to WM extent, references #5799

comment:9 by pramsey, 3 weeks ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.