Use common app.get for images and static images

Co-Authored-By: Andrew Calcutt <acalcutt@techidiots.net>
This commit is contained in:
acalcutt 2024-12-29 22:15:33 -05:00
parent 70d6986a9e
commit e1460fbf67

View file

@ -624,35 +624,34 @@ const respondImage = async (
}); });
}; };
const existingFonts = {}; /**
let maxScaleFactor = 2; * Handles requests for tile images.
* @param {object} options - Configuration options for the server.
export const serve_rendered = { * @param {object} repo - The repository object holding style data.
/** * @param {object} req - Express request object.
* Initializes the serve_rendered module. * @param {object} res - Express response object.
* @param {object} options Configuration options. * @param {Function} next - Express next middleware function.
* @param {object} repo Repository object. * @param {number} maxScaleFactor - The maximum scale factor allowed.
* @returns {Promise<express.Application>} A promise that resolves to the Express app. * @returns {Promise<void>}
*/ */
init: async function (options, repo) { async function handleTileRequest(
maxScaleFactor = Math.min(Math.floor(options.maxScaleFactor || 3), 9); options,
const app = express().disable('x-powered-by'); repo,
req,
app.get( res,
`/:id{/:tileSize}/:z/:x/:y{@:scale}{.:format}`, next,
async (req, res, next) => { maxScaleFactor,
try { ) {
console.log(req.params); const {
if ( id,
req.params.z === 'static' || p2: zParam,
(req.params.tileSize && p3: xParam,
req.params.tileSize != 256 && p4: yParam,
req.params.tileSize != 512) scale: scaleParam,
) { format,
//workaroud for /:id/static{/:raw}{/:type}/:width{x:height}{@:scale}{.:format} p1: tileSize,
next('route'); } = req.params;
} else { const item = repo[id];
const item = repo[req.params.id];
if (!item) { if (!item) {
return res.sendStatus(404); return res.sendStatus(404);
} }
@ -664,13 +663,11 @@ export const serve_rendered = {
return res.sendStatus(304); return res.sendStatus(304);
} }
} }
const z = parseFloat(zParam) | 0;
const z = req.params.z | 0; const x = parseFloat(xParam) | 0;
const x = req.params.x | 0; const y = parseFloat(yParam) | 0;
const y = req.params.y | 0; const scale = parseScale(scaleParam, maxScaleFactor);
const scale = parseScale(req.params.scale, maxScaleFactor); const parsedTileSize = parseInt(tileSize, 10) || 256;
const format = req.params.format;
const tileSize = parseInt(req.params.tileSize, 10) || 256;
if ( if (
scale == null || scale == null ||
z < 0 || z < 0 ||
@ -684,63 +681,74 @@ export const serve_rendered = {
} }
const tileCenter = mercator.ll( const tileCenter = mercator.ll(
[ [((x + 0.5) / (1 << z)) * (256 << z), ((y + 0.5) / (1 << z)) * (256 << z)],
((x + 0.5) / (1 << z)) * (256 << z),
((y + 0.5) / (1 << z)) * (256 << z),
],
z, z,
); );
// prettier-ignore // prettier-ignore
return await respondImage( return await respondImage(
options, item, z, tileCenter[0], tileCenter[1], 0, 0, tileSize, tileSize, scale, format, res, options, item, z, tileCenter[0], tileCenter[1], 0, 0, parsedTileSize, parsedTileSize, scale, format, res,
);
}
} catch (e) {
console.log(e);
next('route');
}
},
); );
}
if (options.serveStaticMaps !== false) { /**
app.get( * Handles requests for static map images.
`/:id/static{/:raw}{/:type}/:width{x:height}{@:scale}{.:format}`, * @param {object} options - Configuration options for the server.
async (req, res, next) => { * @param {object} repo - The repository object holding style data.
try { * @param {object} req - Express request object.
const item = repo[req.params.id]; * @param {object} res - Express response object.
console.log(req.params); * @param {Function} next - Express next middleware function.
const format = req.params.format; * @param {number} maxScaleFactor - The maximum scale factor allowed.
const w = parseInt(req.params.width) || 512; * @returns {Promise<void>}
const h = parseInt(req.params.height) || 512; */
const scale = parseScale(req.params.scale, maxScaleFactor); async function handleStaticRequest(
let raw = req.params.raw !== undefined; options,
let type = req.params.type; repo,
if (!type) { req,
res,
next,
maxScaleFactor,
) {
const {
id,
scale: scaleParam,
format,
p2: raw,
p3: type,
p4: width,
p5: height,
} = req.params;
const item = repo[id];
const parsedWidth = parseInt(width) || 512;
const parsedHeight = parseInt(height) || 512;
const scale = parseScale(scaleParam, maxScaleFactor);
let isRaw = raw !== undefined;
let staticType = type;
if (!staticType) {
//workaround for type when raw is not set //workaround for type when raw is not set
type = req.params.raw; staticType = raw;
raw = false; isRaw = false;
} }
if (!item || !type || !format || !scale) { if (!item || !staticType || !format || !scale) {
return res.sendStatus(404); return res.sendStatus(404);
} }
const staticTypeMatch = type.match(staticTypeRegex); const staticTypeMatch = staticType.match(staticTypeRegex);
console.log(staticTypeMatch.groups); console.log(staticTypeMatch);
if (staticTypeMatch.groups.lon) { if (staticTypeMatch.groups.lon) {
// Center Based Static Image // Center Based Static Image
const z = staticTypeMatch.groups.zoom; const z = parseFloat(staticTypeMatch.groups.zoom) || 0;
let x = staticTypeMatch.groups.lon; let x = parseFloat(staticTypeMatch.groups.lon) || 0;
let y = staticTypeMatch.groups.lat; let y = parseFloat(staticTypeMatch.groups.lat) || 0;
const bearing = staticTypeMatch.groups.bearing; const bearing = parseFloat(staticTypeMatch.groups.bearing) || 0;
const pitch = staticTypeMatch.groups.pitch; const pitch = parseInt(staticTypeMatch.groups.pitch) || 0;
if (z < 0) { if (z < 0) {
return res.status(404).send('Invalid zoom'); return res.status(404).send('Invalid zoom');
} }
const transformer = raw const transformer = isRaw
? mercator.inverse.bind(mercator) ? mercator.inverse.bind(mercator)
: item.dataProjWGStoInternalWGS; : item.dataProjWGStoInternalWGS;
@ -751,20 +759,16 @@ export const serve_rendered = {
} }
const paths = extractPathsFromQuery(req.query, transformer); const paths = extractPathsFromQuery(req.query, transformer);
const markers = extractMarkersFromQuery( const markers = extractMarkersFromQuery(req.query, options, transformer);
req.query,
options,
transformer,
);
// prettier-ignore // prettier-ignore
const overlay = await renderOverlay( const overlay = await renderOverlay(
z, x, y, bearing, pitch, w, h, scale, paths, markers, req.query, z, x, y, bearing, pitch, parsedWidth, parsedHeight, scale, paths, markers, req.query,
); );
// prettier-ignore // prettier-ignore
return await respondImage( return await respondImage(
options, item, z, x, y, bearing, pitch, w, h, scale, format, res, overlay, 'static', options, item, z, x, y, bearing, pitch, parsedWidth, parsedHeight, scale, format, res, overlay, 'static',
); );
} else if (staticTypeMatch.groups.minx) { } else if (staticTypeMatch.groups.minx) {
// Area Based Static Image // Area Based Static Image
@ -776,7 +780,7 @@ export const serve_rendered = {
]; ];
let center = [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2]; let center = [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2];
const transformer = raw const transformer = isRaw
? mercator.inverse.bind(mercator) ? mercator.inverse.bind(mercator)
: item.dataProjWGStoInternalWGS; : item.dataProjWGStoInternalWGS;
@ -790,43 +794,33 @@ export const serve_rendered = {
center = transformer(center); center = transformer(center);
} }
const z = calcZForBBox(bbox, w, h, req.query); const z = calcZForBBox(bbox, parsedWidth, parsedHeight, req.query);
const x = center[0]; const x = center[0];
const y = center[1]; const y = center[1];
const bearing = 0; const bearing = 0;
const pitch = 0; const pitch = 0;
const paths = extractPathsFromQuery(req.query, transformer); const paths = extractPathsFromQuery(req.query, transformer);
const markers = extractMarkersFromQuery( const markers = extractMarkersFromQuery(req.query, options, transformer);
req.query,
options,
transformer,
);
// prettier-ignore // prettier-ignore
const overlay = await renderOverlay( const overlay = await renderOverlay(
z, x, y, bearing, pitch, w, h, scale, paths, markers, req.query, z, x, y, bearing, pitch, parsedWidth, parsedHeight, scale, paths, markers, req.query,
); );
// prettier-ignore // prettier-ignore
return await respondImage( return await respondImage(
options, item, z, x, y, bearing, pitch, w, h, scale, format, res, overlay, 'static', options, item, z, x, y, bearing, pitch, parsedWidth, parsedHeight, scale, format, res, overlay, 'static',
); );
} else if (staticTypeMatch.groups.auto) { } else if (staticTypeMatch.groups.auto) {
// Area Static Image // Area Static Image
const bearing = 0; const bearing = 0;
const pitch = 0; const pitch = 0;
const transformer = raw const transformer = isRaw
? mercator.inverse.bind(mercator) ? mercator.inverse.bind(mercator)
: item.dataProjWGStoInternalWGS; : item.dataProjWGStoInternalWGS;
const paths = extractPathsFromQuery(req.query, transformer); const paths = extractPathsFromQuery(req.query, transformer);
const markers = extractMarkersFromQuery( const markers = extractMarkersFromQuery(req.query, options, transformer);
req.query,
options,
transformer,
);
// Extract coordinates from markers // Extract coordinates from markers
const markerCoordinates = []; const markerCoordinates = [];
@ -858,7 +852,7 @@ export const serve_rendered = {
// Calculate zoom level // Calculate zoom level
const maxZoom = parseFloat(req.query.maxzoom); const maxZoom = parseFloat(req.query.maxzoom);
let z = calcZForBBox(bbox, w, h, req.query); let z = calcZForBBox(bbox, parsedWidth, parsedHeight, req.query);
if (maxZoom > 0) { if (maxZoom > 0) {
z = Math.min(z, maxZoom); z = Math.min(z, maxZoom);
} }
@ -868,22 +862,66 @@ export const serve_rendered = {
// prettier-ignore // prettier-ignore
const overlay = await renderOverlay( const overlay = await renderOverlay(
z, x, y, bearing, pitch, w, h, scale, paths, markers, req.query, z, x, y, bearing, pitch, parsedWidth, parsedHeight, scale, paths, markers, req.query,
); );
// prettier-ignore // prettier-ignore
return await respondImage( return await respondImage(
options, item, z, x, y, bearing, pitch, w, h, scale, format, res, overlay, 'static', options, item, z, x, y, bearing, pitch, parsedWidth, parsedHeight, scale, format, res, overlay, 'static',
); );
} else { } else {
return res.sendStatus(404); return res.sendStatus(404);
} }
}
const existingFonts = {};
let maxScaleFactor = 2;
export const serve_rendered = {
/**
* Initializes the serve_rendered module.
* @param {object} options Configuration options.
* @param {object} repo Repository object.
* @returns {Promise<express.Application>} A promise that resolves to the Express app.
*/
init: async function (options, repo) {
maxScaleFactor = Math.min(Math.floor(options.maxScaleFactor || 3), 9);
const app = express().disable('x-powered-by');
app.get(
`/:id{/:p1}/:p2/:p3/:p4{x:p5}{@:scale}{.:format}`,
async (req, res, next) => {
try {
const { p2 } = req.params;
if (p2 === 'static') {
// Route to static if p2 is static
if (options.serveStaticMaps !== false) {
return handleStaticRequest(
options,
repo,
req,
res,
next,
maxScaleFactor,
);
}
return res.sendStatus(404);
}
return handleTileRequest(
options,
repo,
req,
res,
next,
maxScaleFactor,
);
} catch (e) { } catch (e) {
next('route'); console.log(e);
return next(e);
} }
}, },
); );
}
app.get('{/:tileSize}/:id.json', (req, res, next) => { app.get('{/:tileSize}/:id.json', (req, res, next) => {
const item = repo[req.params.id]; const item = repo[req.params.id];