2018-09-30 14:50:09 -04:00
|
|
|
/**
|
2019-04-27 08:36:17 -04:00
|
|
|
* Tileserver
|
|
|
|
* - routes for Express app
|
2019-09-17 13:11:42 -04:00
|
|
|
* - see rendererDefinition for actual rules of rendering
|
2018-09-30 14:50:09 -04:00
|
|
|
*/
|
2018-09-10 05:44:32 -04:00
|
|
|
import express from 'express';
|
|
|
|
|
2019-11-07 02:48:51 -05:00
|
|
|
import asyncController from '../api/routes/asyncController';
|
2019-02-24 07:17:59 -05:00
|
|
|
import { strictParseInt } from '../parse';
|
2019-11-07 02:48:51 -05:00
|
|
|
|
|
|
|
import { allTilesets, renderTile } from './rendererDefinition';
|
2019-09-17 13:11:42 -04:00
|
|
|
import { TileParams } from './types';
|
|
|
|
|
|
|
|
const handleTileRequest = asyncController(async function (req: express.Request, res: express.Response) {
|
|
|
|
try {
|
|
|
|
var tileParams = parseTileParams(req.params);
|
|
|
|
var dataParams = req.query;
|
|
|
|
} catch(err) {
|
|
|
|
console.error(err);
|
|
|
|
return res.status(400).send({error: err.message});
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2019-10-07 08:34:22 -04:00
|
|
|
const im = await renderTile(tileParams, dataParams);
|
2019-09-17 13:11:42 -04:00
|
|
|
res.writeHead(200, { 'Content-Type': 'image/png' });
|
|
|
|
res.end(im);
|
|
|
|
} catch(err) {
|
|
|
|
console.error(err);
|
|
|
|
res.status(500).send({ error: err });
|
|
|
|
}
|
|
|
|
});
|
2019-02-24 15:07:22 -05:00
|
|
|
|
2018-09-10 05:44:32 -04:00
|
|
|
// tiles router
|
2019-11-07 03:13:30 -05:00
|
|
|
const router = express.Router();
|
2018-09-10 05:44:32 -04:00
|
|
|
|
2019-09-17 13:11:42 -04:00
|
|
|
router.get('/:tileset/:z/:x/:y(\\d+):scale(@\\dx)?.png', handleTileRequest);
|
2018-09-10 05:44:32 -04:00
|
|
|
|
2019-09-17 13:11:42 -04:00
|
|
|
function parseTileParams(params: any): TileParams {
|
|
|
|
const { tileset, z, x, y, scale } = params;
|
2018-09-10 05:44:32 -04:00
|
|
|
|
2019-09-17 13:35:05 -04:00
|
|
|
if (!allTilesets.includes(tileset)) throw new Error('Invalid value for tileset');
|
|
|
|
|
2019-05-27 13:26:29 -04:00
|
|
|
const intZ = strictParseInt(z);
|
2019-09-17 13:11:42 -04:00
|
|
|
if (isNaN(intZ)) throw new Error('Invalid value for z');
|
2018-09-10 05:44:32 -04:00
|
|
|
|
2019-09-17 13:11:42 -04:00
|
|
|
const intX = strictParseInt(x);
|
|
|
|
if (isNaN(intX)) throw new Error('Invalid value for x');
|
2019-02-24 14:23:59 -05:00
|
|
|
|
2019-09-17 13:11:42 -04:00
|
|
|
const intY = strictParseInt(y);
|
|
|
|
if (isNaN(intY)) throw new Error('Invalid value for y');
|
2019-02-24 14:23:59 -05:00
|
|
|
|
2019-09-17 13:11:42 -04:00
|
|
|
let intScale: number;
|
|
|
|
if (scale === '@2x') {
|
|
|
|
intScale = 2;
|
|
|
|
} else if (scale === '@1x' || scale == undefined) {
|
|
|
|
intScale = 1;
|
2019-02-24 14:23:59 -05:00
|
|
|
} else {
|
2019-09-17 13:11:42 -04:00
|
|
|
throw new Error('Invalid value for scale');
|
2019-02-24 14:23:59 -05:00
|
|
|
}
|
2019-02-24 15:07:22 -05:00
|
|
|
|
2019-09-17 13:11:42 -04:00
|
|
|
return {
|
|
|
|
tileset,
|
|
|
|
z: intZ,
|
|
|
|
x: intX,
|
|
|
|
y: intY,
|
|
|
|
scale: intScale
|
|
|
|
};
|
2019-02-24 08:34:40 -05:00
|
|
|
}
|
2018-10-25 07:39:41 -04:00
|
|
|
|
2019-09-17 13:11:42 -04:00
|
|
|
router.use((req, res) => {
|
|
|
|
return res.status(404).send('Tile not found');
|
|
|
|
});
|
2019-01-19 11:55:30 -05:00
|
|
|
|
2018-09-10 05:44:32 -04:00
|
|
|
export default router;
|