Last active
March 3, 2022 09:01
-
-
Save chriswhong/762ceac7fb8a1420e7e7adceb770b707 to your computer and use it in GitHub Desktop.
Using ST_AsMVT() and ST_AsMVTGeom() in express to build a vector tile endpoint
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
/* GET /tiles/:z/:x/:y.mvt */ | |
/* Retreive a vector tile by tileid */ | |
router.get('/tiles/:z/:x/:y.mvt', async (req, res) => { | |
const { z, x, y } = req.params; | |
// calculate the bounding polygon for this tile | |
const bbox = mercator.bbox(x, y, z, false); | |
// Query the database, using ST_AsMVTGeom() to clip the geometries | |
// Wrap the whole query with ST_AsMVT(), which will create a protocol buffer | |
const SQL = ` | |
SELECT ST_AsMVT(q, 'internal-layer-name', 4096, 'geom') | |
FROM ( | |
SELECT | |
somecolumn, | |
ST_AsMVTGeom( | |
geom, | |
ST_MakeEnvelope(${bbox[0]}, ${bbox[1]}, ${bbox[2]}, ${bbox[3]}, 4326), | |
4096, | |
256, | |
false | |
) geom | |
FROM sometable c | |
) q | |
`; | |
try { | |
const tile = await db.one(SQL); | |
// set the response header content type | |
res.setHeader('Content-Type', 'application/x-protobuf'); | |
// trigger catch if the vector tile has no data, (return a 204) | |
if (tile.st_asmvt.length === 0) { | |
res.status(204); | |
} | |
// send the tile! | |
res.send(tile.st_asmvt); | |
} catch (e) { | |
res.status(404).send({ | |
error: e.toString(), | |
}); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment