Last active
January 9, 2021 18:41
-
-
Save dschep/221918f28bcf204ef3533387cdaa9a42 to your computer and use it in GitHub Desktop.
ST_TileEnvelope backport
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- ported from https://github.com/pramsey/minimal-mvt/blob/58f3e695a305f42024dcf0ba395590bf39b0b573/minimal-mvt.py#L63-L81 | |
CREATE OR REPLACE FUNCTION ST_TileEnvelope(tileZoom integer, tileX integer, tileY integer) RETURNS geometry AS $$ | |
-- Width of world in EPSG:3857 | |
DECLARE worldMercMax float = 20037508.3427892; | |
DECLARE worldMercMin float = -1 * worldMercMax; | |
DECLARE worldMercSize float = worldMercMax - worldMercMin; | |
-- Width in tiles | |
DECLARE worldTileSize float = power(2, tileZoom); | |
-- Tile width in EPSG:3857 | |
DECLARE tileMercSize float = worldMercSize / worldTileSize; | |
-- Calculate geographic bounds from tile coordinates | |
-- XYZ tile coordinates are in "image space" so origin is | |
-- top-left, not bottom right | |
DECLARE xmin float = worldMercMin + tileMercSize * tileX; | |
DECLARE xmax float = worldMercMin + tileMercSize * (tileX + 1); | |
DECLARE ymin float = worldMercMax - tileMercSize * (tileY + 1); | |
DECLARE ymax float = worldMercMax - tileMercSize * (tileY); | |
BEGIN | |
RETURN ST_MakeEnvelope(xmin, ymin, xmax, ymax, 3857); | |
END; | |
$$ LANGUAGE 'plpgsql' IMMUTABLE; | |
-- OR... copied from https://github.com/CrunchyData/pg_tileserv | |
CREATE OR REPLACE | |
FUNCTION ST_TileEnvelope(z integer, x integer, y integer) | |
RETURNS geometry | |
AS $$ | |
DECLARE | |
size float8; | |
zp integer = pow(2, z); | |
gx float8; | |
gy float8; | |
BEGIN | |
IF y >= zp OR y < 0 OR x >= zp OR x < 0 THEN | |
RAISE EXCEPTION 'invalid tile coordinate (%, %, %)', z, x, y; | |
END IF; | |
size := 40075016.6855784 / zp; | |
gx := (size * x) - (40075016.6855784/2); | |
gy := (40075016.6855784/2) - (size * y); | |
RETURN ST_SetSRID(ST_MakeEnvelope(gx, gy, gx + size, gy - size), 3857); | |
END; | |
$$ | |
LANGUAGE 'plpgsql' | |
IMMUTABLE | |
STRICT | |
PARALLEL SAFE; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment