cleanup sever_rendered.js

Co-Authored-By: Andrew Calcutt <acalcutt@techidiots.net>
This commit is contained in:
acalcutt 2024-12-29 02:58:59 -05:00
parent b6537b58a0
commit d52154605a

View file

@ -68,7 +68,13 @@ const httpTester = /^https?:\/\//i;
const mercator = new SphericalMercator(); const mercator = new SphericalMercator();
const parseScale = (scale, maxScaleDigit = 9) => { /**
* Parses a scale string to a number.
* @param {string} scale The scale string (e.g., '2x', '4x').
* @param {number} maxScaleDigit Maximum allowed scale digit.
* @returns {number|null} The parsed scale as a number or null if invalid.
*/
function parseScale(scale, maxScaleDigit = 9) {
if (scale === undefined) { if (scale === undefined) {
return 1; return 1;
} }
@ -80,7 +86,7 @@ const parseScale = (scale, maxScaleDigit = 9) => {
} }
return parseInt(scale.slice(0, -1), 10); return parseInt(scale.slice(0, -1), 10);
}; }
mlgl.on('message', (e) => { mlgl.on('message', (e) => {
if (e.severity === 'WARNING' || e.severity === 'ERROR') { if (e.severity === 'WARNING' || e.severity === 'ERROR') {
@ -111,6 +117,7 @@ const cachedEmptyResponses = {
* @param {string} format The format (a sharp format or 'pbf'). * @param {string} format The format (a sharp format or 'pbf').
* @param {string} color The background color (or empty string for transparent). * @param {string} color The background color (or empty string for transparent).
* @param {Function} callback The mlgl callback. * @param {Function} callback The mlgl callback.
* @returns {void}
*/ */
function createEmptyResponse(format, color, callback) { function createEmptyResponse(format, color, callback) {
if (!format || format === 'pbf') { if (!format || format === 'pbf') {
@ -163,11 +170,12 @@ function createEmptyResponse(format, color, callback) {
/** /**
* Parses coordinate pair provided to pair of floats and ensures the resulting * Parses coordinate pair provided to pair of floats and ensures the resulting
* pair is a longitude/latitude combination depending on lnglat query parameter. * pair is a longitude/latitude combination depending on lnglat query parameter.
* @param {List} coordinatePair Coordinate pair. * @param {Array<string>} coordinatePair Coordinate pair.
* @param coordinates * @param coordinates
* @param {object} query Request query parameters. * @param {object} query Request query parameters.
* @returns {Array<number>|null} Parsed coordinate pair as [longitude, latitude] or null if invalid
*/ */
const parseCoordinatePair = (coordinates, query) => { function parseCoordinatePair(coordinates, query) {
const firstCoordinate = parseFloat(coordinates[0]); const firstCoordinate = parseFloat(coordinates[0]);
const secondCoordinate = parseFloat(coordinates[1]); const secondCoordinate = parseFloat(coordinates[1]);
@ -183,15 +191,16 @@ const parseCoordinatePair = (coordinates, query) => {
} }
return [firstCoordinate, secondCoordinate]; return [firstCoordinate, secondCoordinate];
}; }
/** /**
* Parses a coordinate pair from query arguments and optionally transforms it. * Parses a coordinate pair from query arguments and optionally transforms it.
* @param {List} coordinatePair Coordinate pair. * @param {Array<string>} coordinatePair Coordinate pair.
* @param {object} query Request query parameters. * @param {object} query Request query parameters.
* @param {Function} transformer Optional transform function. * @param {Function} transformer Optional transform function.
* @returns {Array<number>|null} Transformed coordinate pair or null if invalid.
*/ */
const parseCoordinates = (coordinatePair, query, transformer) => { function parseCoordinates(coordinatePair, query, transformer) {
const parsedCoordinates = parseCoordinatePair(coordinatePair, query); const parsedCoordinates = parseCoordinatePair(coordinatePair, query);
// Transform coordinates // Transform coordinates
@ -200,14 +209,15 @@ const parseCoordinates = (coordinatePair, query, transformer) => {
} }
return parsedCoordinates; return parsedCoordinates;
}; }
/** /**
* Parses paths provided via query into a list of path objects. * Parses paths provided via query into a list of path objects.
* @param {object} query Request query parameters. * @param {object} query Request query parameters.
* @param {Function} transformer Optional transform function. * @param {Function} transformer Optional transform function.
* @returns {Array<Array<Array<number>>>} Array of paths.
*/ */
const extractPathsFromQuery = (query, transformer) => { function extractPathsFromQuery(query, transformer) {
// Initiate paths array // Initiate paths array
const paths = []; const paths = [];
// Return an empty list if no paths have been provided // Return an empty list if no paths have been provided
@ -259,17 +269,18 @@ const extractPathsFromQuery = (query, transformer) => {
} }
} }
return paths; return paths;
}; }
/** /**
* Parses marker options provided via query and sets corresponding attributes * Parses marker options provided via query and sets corresponding attributes
* on marker object. * on marker object.
* Options adhere to the following format * Options adhere to the following format
* [optionName]:[optionValue] * [optionName]:[optionValue]
* @param {List[String]} optionsList List of option strings. * @param {Array<string>} optionsList List of option strings.
* @param {object} marker Marker object to configure. * @param {object} marker Marker object to configure.
* @returns {void}
*/ */
const parseMarkerOptions = (optionsList, marker) => { function parseMarkerOptions(optionsList, marker) {
for (const options of optionsList) { for (const options of optionsList) {
const optionParts = options.split(':'); const optionParts = options.split(':');
// Ensure we got an option name and value // Ensure we got an option name and value
@ -296,15 +307,16 @@ const parseMarkerOptions = (optionsList, marker) => {
break; break;
} }
} }
}; }
/** /**
* Parses markers provided via query into a list of marker objects. * Parses markers provided via query into a list of marker objects.
* @param {object} query Request query parameters. * @param {object} query Request query parameters.
* @param {object} options Configuration options. * @param {object} options Configuration options.
* @param {Function} transformer Optional transform function. * @param {Function} transformer Optional transform function.
* @returns {Array<object>} An array of marker objects.
*/ */
const extractMarkersFromQuery = (query, options, transformer) => { function extractMarkersFromQuery(query, options, transformer) {
// Return an empty list if no markers have been provided // Return an empty list if no markers have been provided
if (!query.marker) { if (!query.marker) {
return []; return [];
@ -380,9 +392,16 @@ const extractMarkersFromQuery = (query, options, transformer) => {
markers.push(marker); markers.push(marker);
} }
return markers; return markers;
}; }
/**
const calcZForBBox = (bbox, w, h, query) => { * Calculates the zoom level for a given bounding box.
* @param {Array<number>} bbox Bounding box as [minx, miny, maxx, maxy].
* @param {number} w Width of the image.
* @param {number} h Height of the image.
* @param {object} query Request query parameters.
* @returns {number} Calculated zoom level.
*/
function calcZForBBox(bbox, w, h, query) {
let z = 25; let z = 25;
const padding = query.padding !== undefined ? parseFloat(query.padding) : 0.1; const padding = query.padding !== undefined ? parseFloat(query.padding) : 0.1;
@ -401,9 +420,27 @@ const calcZForBBox = (bbox, w, h, query) => {
z = Math.max(Math.log(Math.max(w, h) / 256) / Math.LN2, Math.min(25, z)); z = Math.max(Math.log(Math.max(w, h) / 256) / Math.LN2, Math.min(25, z));
return z; return z;
}; }
const respondImage = ( /**
* Responds with an image.
* @param {object} options Configuration options.
* @param {object} item Item object containing map and other information.
* @param {number} z Zoom level.
* @param {number} lon Longitude of the center.
* @param {number} lat Latitude of the center.
* @param {number} bearing Map bearing.
* @param {number} pitch Map pitch.
* @param {number} width Width of the image.
* @param {number} height Height of the image.
* @param {number} scale Scale factor.
* @param {string} format Image format.
* @param {object} res Express response object.
* @param {Buffer|null} overlay Optional overlay image.
* @param {string} mode Rendering mode ('tile' or 'static').
* @returns {Promise<void>}
*/
const respondImage = async (
options, options,
item, item,
z, z,
@ -451,7 +488,7 @@ const respondImage = (
} else { } else {
pool = item.map.renderersStatic[scale]; pool = item.map.renderersStatic[scale];
} }
pool.acquire((err, renderer) => { pool.acquire(async (err, renderer) => {
// For 512px tiles, use the actual maplibre-native zoom. For 256px tiles, use zoom - 1 // For 512px tiles, use the actual maplibre-native zoom. For 256px tiles, use zoom - 1
let mlglZ; let mlglZ;
if (width === 512) { if (width === 512) {
@ -591,7 +628,13 @@ const existingFonts = {};
let maxScaleFactor = 2; let maxScaleFactor = 2;
export const serve_rendered = { export const serve_rendered = {
init: async (options, repo) => { /**
* 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); maxScaleFactor = Math.min(Math.floor(options.maxScaleFactor || 3), 9);
const app = express().disable('x-powered-by'); const app = express().disable('x-powered-by');
@ -864,7 +907,17 @@ export const serve_rendered = {
Object.assign(existingFonts, fonts); Object.assign(existingFonts, fonts);
return app; return app;
}, },
add: async (options, repo, params, id, publicUrl, dataResolver) => { /**
* Adds a new item to the repository.
* @param {object} options Configuration options.
* @param {object} repo Repository object.
* @param {object} params Parameters object.
* @param {string} id ID of the item.
* @param {string} publicUrl Public URL.
* @param {Function} dataResolver Function to resolve data.
* @returns {Promise<void>}
*/
add: async function (options, repo, params, id, publicUrl, dataResolver) {
const map = { const map = {
renderers: [], renderers: [],
renderersStatic: [], renderersStatic: [],
@ -873,7 +926,21 @@ export const serve_rendered = {
}; };
let styleJSON; let styleJSON;
/**
* Creates a pool of renderers.
* @param {number} ratio Pixel ratio
* @param {string} mode Rendering mode ('tile' or 'static').
* @param {number} min Minimum pool size.
* @param {number} max Maximum pool size.
* @returns {object} The created pool
*/
const createPool = (ratio, mode, min, max) => { const createPool = (ratio, mode, min, max) => {
/**
* Creates a renderer
* @param {number} ratio Pixel ratio
* @param {Function} createCallback Function that returns the renderer when created
* @returns {void}
*/
const createRenderer = (ratio, createCallback) => { const createRenderer = (ratio, createCallback) => {
const renderer = new mlgl.Map({ const renderer = new mlgl.Map({
mode, mode,
@ -1278,7 +1345,13 @@ export const serve_rendered = {
); );
} }
}, },
remove: (repo, id) => { /**
* Removes an item from the repository.
* @param {object} repo Repository object.
* @param {string} id ID of the item to remove.
* @returns {void}
*/
remove: function (repo, id) {
const item = repo[id]; const item = repo[id];
if (item) { if (item) {
item.map.renderers.forEach((pool) => { item.map.renderers.forEach((pool) => {