refactor!: update static map endpoint path

Signed-off-by: Vinayak Kulkarni <19776877+vinayakkulkarni@users.noreply.github.com>
This commit is contained in:
Vinayak Kulkarni 2023-01-05 22:34:05 +05:30
parent a1f60e16b5
commit 4b7f41d620
No known key found for this signature in database
GPG key ID: B8C8194CED989C08

View file

@ -21,6 +21,8 @@ import request from 'request';
import { getFontsPbf, getTileUrls, fixTileJSONCenter } from './utils.js'; import { getFontsPbf, getTileUrls, fixTileJSONCenter } from './utils.js';
const FLOAT_PATTERN = '[+-]?(?:\\d+|\\d+.?\\d+)'; const FLOAT_PATTERN = '[+-]?(?:\\d+|\\d+.?\\d+)';
const PATH_PATTERN =
/^((fill|stroke|width)\:[^\|]+\|)*((enc:.+)|((-?\d+\.?\d*,-?\d+\.?\d*\|)+(-?\d+\.?\d*,-?\d+\.?\d*)))/;
const httpTester = /^(http(s)?:)?\/\//; const httpTester = /^(http(s)?:)?\/\//;
const mercator = new SphericalMercator(); const mercator = new SphericalMercator();
@ -150,58 +152,63 @@ const parseCoordinates = (coordinatePair, query, transformer) => {
const extractPathsFromQuery = (query, transformer) => { const extractPathsFromQuery = (query, transformer) => {
const paths = []; const paths = [];
// Return an empty list if no paths have been provided // Return an empty list if no paths have been provided
if ( if ('path' in query && !query.path) {
('path' in query && !query.path) ||
('encodedpath' in query && !query.encodedpath)
) {
return paths; return paths;
} }
// Parse paths provided via path query argument // Parse paths provided via path query argument
if ('path' in query) { if ('path' in query && PATH_PATTERN.test(query.path)) {
// Check if multiple paths have been provided and mimic a list if it's a if (query.path.includes('enc:')) {
// single path. const splitPaths = query.path.split('|');
const providedPaths = Array.isArray(query.path) ? query.path : [query.path]; const line = splitPaths
.filter(
(x) =>
!x.startsWith('fill') &&
!x.startsWith('stroke') &&
!x.startsWith('width'),
)
.join('')
.replace('enc:', '');
// Iterate through paths, parse and validate them const coords = polyline.decode(line).map(([lat, lng]) => [lng, lat]);
for (const providedPath of providedPaths) { paths.push(coords);
const currentPath = []; } else {
// Check if multiple paths have been provided and mimic a list if it's a
// single path.
const providedPaths = Array.isArray(query.path)
? query.path
: [query.path];
// Extract coordinate-list from path // Iterate through paths, parse and validate them
const pathParts = (providedPath || '').split('|'); for (const providedPath of providedPaths) {
const currentPath = [];
// Iterate through coordinate-list, parse the coordinates and validate them // Extract coordinate-list from path
for (const pair of pathParts) { const pathParts = (providedPath || '').split('|');
// Extract coordinates from coordinate pair
const pairParts = pair.split(',');
// Ensure we have two coordinates // Iterate through coordinate-list, parse the coordinates and validate them
if (pairParts.length === 2) { for (const pair of pathParts) {
const pair = parseCoordinates(pairParts, query, transformer); // Extract coordinates from coordinate pair
const pairParts = pair.split(',');
// Ensure we have two coordinates
if (pairParts.length === 2) {
const pair = parseCoordinates(pairParts, query, transformer);
// Ensure coordinates could be parsed and skip them if not // Ensure coordinates could be parsed and skip them if not
if (pair === null) { if (pair === null) {
continue; continue;
}
// Add the coordinate-pair to the current path if they are valid
currentPath.push(pair);
} }
}
// Add the coordinate-pair to the current path if they are valid // Extend list of paths with current path if it contains coordinates
currentPath.push(pair); if (currentPath.length) {
paths.push(currentPath);
} }
} }
// Extend list of paths with current path if it contains coordinates
if (currentPath.length) {
paths.push(currentPath);
}
} }
} }
// Check if encoded paths have been provided
if ('encodedpath' in query) {
// silly lat/lng switch 🤷‍♂️
const coords = polyline
.decode(query.encodedpath)
.map(([lat, lng]) => [lng, lat]);
paths.push(coords);
}
return paths; return paths;
}; };
@ -435,6 +442,9 @@ const drawMarkers = async (ctx, markers, z) => {
* @param {number} z Map zoom level. * @param {number} z Map zoom level.
*/ */
const drawPath = (ctx, path, query, z) => { const drawPath = (ctx, path, query, z) => {
// Check if path in query is valid
const splitPaths = query.path.split('|');
if (!path || path.length < 2) { if (!path || path.length < 2) {
return null; return null;
} }
@ -456,16 +466,36 @@ const drawPath = (ctx, path, query, z) => {
} }
// Optionally fill drawn shape with a rgba color from query // Optionally fill drawn shape with a rgba color from query
if (query.fill !== undefined) { const pathHasFill = splitPaths.filter((x) => x.startsWith('fill')).length > 0;
ctx.fillStyle = query.fill; if (query.fill !== undefined || pathHasFill) {
if ('fill' in query) {
ctx.fillStyle = query.fill;
}
if (pathHasFill) {
ctx.fillStyle = splitPaths
.find((x) => x.startsWith('fill:'))
.replace('fill:', '');
console.log('path has fill', ctx.fillStyle);
}
ctx.fill(); ctx.fill();
} }
// Get line width from query and fall back to 1 if not provided // Get line width from query and fall back to 1 if not provided
const lineWidth = query.width !== undefined ? parseFloat(query.width) : 1; const pathHasWidth =
splitPaths.filter((x) => x.startsWith('width')).length > 0;
// Ensure line width is valid if (query.width !== undefined || pathHasWidth) {
if (lineWidth > 0) { let lineWidth = 1;
// Get line width from query
if ('width' in query) {
lineWidth = Number(query.width);
}
// Get line width from path in query
if (pathHasWidth) {
lineWidth = Number(
splitPaths.find((x) => x.startsWith('width:')).replace('width:', ''),
);
console.log('line width', lineWidth);
}
// Get border width from query and fall back to 10% of line width // Get border width from query and fall back to 10% of line width
const borderWidth = const borderWidth =
query.borderwidth !== undefined query.borderwidth !== undefined
@ -490,9 +520,21 @@ const drawPath = (ctx, path, query, z) => {
ctx.strokeStyle = query.border; ctx.strokeStyle = query.border;
ctx.stroke(); ctx.stroke();
} }
ctx.lineWidth = lineWidth; ctx.lineWidth = lineWidth;
ctx.strokeStyle = query.stroke || 'rgba(0,64,255,0.7)'; }
const pathHasStroke =
splitPaths.filter((x) => x.startsWith('stroke')).length > 0;
if (query.stroke !== undefined || pathHasStroke) {
if ('stroke' in query) {
ctx.strokeStyle = query.stroke || 'rgba(0,64,255,0.7)';
}
// Path Width gets higher priority
if (pathHasWidth) {
ctx.strokeStyle = splitPaths
.find((x) => x.startsWith('stroke:'))
.replace('stroke:', '');
}
ctx.stroke(); ctx.stroke();
} }
}; };