diff --git a/docs/endpoints.rst b/docs/endpoints.rst index 0eb8dcb..ef14aed 100644 --- a/docs/endpoints.rst +++ b/docs/endpoints.rst @@ -35,13 +35,14 @@ Static images * All the static image endpoints additionally support following query parameters: - * ``path`` - comma-separated ``lng,lat``, pipe-separated pairs - - * e.g. ``5.9,45.8|5.9,47.8|10.5,47.8|10.5,45.8|5.9,45.8`` - * can be provided multiple times - * or pass the path as per `Maptiler Cloud API `_ - * Match pattern: ((fill|stroke|width)\:[^\|]+\|)*((enc:.+)|((-?\d+\.?\d*,-?\d+\.?\d*\|)+(-?\d+\.?\d*,-?\d+\.?\d*))) - + * ``path`` + * can be provided multiple times + * syntax + * comma-separated ``lng,lat``, pipe-separated pairs + * e.g. ``path=5.9,45.8|5.9,47.8|10.5,47.8|10.5,45.8|5.9,45.8`` + * Match pattern with options ``((fill|stroke|width)\:[^\|]+\|)*((enc:.+)|((-?\d+\.?\d*,-?\d+\.?\d*\|)+(-?\d+\.?\d*,-?\d+\.?\d*)))`` + * e.g. ``path=stroke:yellow|width:2|fill:green|5.9,45.8|5.9,47.8|10.5,47.8|10.5,45.8|5.9,45.8`` or ``stroke:blue|enc:_p~iF~ps|U_ulLnnqC_mqNvxq`@`` + * 'enc:' is specified in `Google Encoded Polyline Format `. If used, the rest of the path parameter is considered to be part of the encoded polyline string -- do not specify the coordinate pairs. * ``latlng`` - indicates coordinates are in ``lat,lng`` order rather than the usual ``lng,lat`` * ``fill`` - color to use as the fill (e.g. ``red``, ``rgba(255,255,255,0.5)``, ``#0000ff``) * ``stroke`` - color of the path stroke diff --git a/src/serve_rendered.js b/src/serve_rendered.js index ee0a5b7..fc9982f 100644 --- a/src/serve_rendered.js +++ b/src/serve_rendered.js @@ -162,21 +162,12 @@ const extractPathsFromQuery = (query, transformer) => { providedPath.includes('enc:') && PATH_PATTERN.test(decodeURIComponent(providedPath)) ) { - const encodedPaths = providedPath.split(','); - for (const path of encodedPaths) { - const line = path - .split('|') - .filter( - (x) => - !x.startsWith('fill') && - !x.startsWith('stroke') && - !x.startsWith('width'), - ) - .join('') - .replace('enc:', ''); - const coords = polyline.decode(line).map(([lat, lng]) => [lng, lat]); - paths.push(coords); - } + // +4 because 'enc:' is 4 characters, everything after 'enc:' is considered to be part of the polyline + const encIndex = providedPath.indexOf('enc:') + 4; + const coords = polyline + .decode(providedPath.substring(encIndex)) + .map(([lat, lng]) => [lng, lat]); + paths.push(coords); } else { // Iterate through paths, parse and validate them const currentPath = []; @@ -520,8 +511,8 @@ const drawPath = (ctx, path, query, pathQuery, z) => { if ('stroke' in query) { ctx.strokeStyle = query.stroke; } - // Path Width gets higher priority - if (pathHasWidth) { + // Path Stroke gets higher priority + if (pathHasStroke) { ctx.strokeStyle = splitPaths .find((x) => x.startsWith('stroke:')) .replace('stroke:', ''); diff --git a/test/static.js b/test/static.js index 547d673..302becb 100644 --- a/test/static.js +++ b/test/static.js @@ -171,6 +171,18 @@ describe('Static endpoints', function () { '?path=-10,-10|-20,-20', ); }); + + describe('encoded path', function () { + testStatic( + prefix, + 'auto/20x20', + 'png', + 200, + 2, + /image\/png/, + '?path=' + decodeURIComponent('enc:{{biGwvyGoUi@s_A|{@'), + ); + }); }); describe('invalid requests return 4xx', function () {