Skip to content

Instantly share code, notes, and snippets.

@cheeaun
Created April 29, 2021 13:01
Show Gist options
  • Save cheeaun/40cca99344bec74d5f476195bb46a740 to your computer and use it in GitHub Desktop.
Save cheeaun/40cca99344bec74d5f476195bb46a740 to your computer and use it in GitHub Desktop.
Render encoded polyline on SVG: polyline.svg#[ENCODED_POLYLINE_STRING]
Display the source blob
Display the rendered blob
Raw
<svg id="svg" xmlns="http://www.w3.org/2000/svg" style="transform: scaleY(-1);">
<polyline id="l" fill="none" stroke="black" vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" />
<g id="circles" />
<script>
// <![CDATA[
// @mabox/polyline
"use strict";var polyline={};function py2_round(e){return Math.floor(Math.abs(e)+.5)*(e>=0?1:-1)}function encode(e,o,n){var r=(e=py2_round(e*n))-(o=py2_round(o*n));r<<=1,e-o<0&&(r=~r);for(var t="";r>=32;)t+=String.fromCharCode(63+(32|31&r)),r>>=5;return t+=String.fromCharCode(r+63)}function flipped(e){for(var o=[],n=0;n<e.length;n++){var r=e[n].slice();o.push([r[1],r[0]])}return o}polyline.decode=function(e,o){for(var n,r=0,t=0,i=0,l=[],u=0,d=0,p=null,c=Math.pow(10,Number.isInteger(o)?o:5);r<e.length;){p=null,u=0,d=0;do{d|=(31&(p=e.charCodeAt(r++)-63))<<u,u+=5}while(p>=32);n=1&d?~(d>>1):d>>1,u=d=0;do{d|=(31&(p=e.charCodeAt(r++)-63))<<u,u+=5}while(p>=32);t+=n,i+=1&d?~(d>>1):d>>1,l.push([t/c,i/c])}return l},polyline.encode=function(e,o){if(!e.length)return"";for(var n=Math.pow(10,Number.isInteger(o)?o:5),r=encode(e[0][0],0,n)+encode(e[0][1],0,n),t=1;t<e.length;t++){var i=e[t],l=e[t-1];r+=encode(i[0],l[0],n),r+=encode(i[1],l[1],n)}return r},polyline.fromGeoJSON=function(e,o){if(e&&"Feature"===e.type&&(e=e.geometry),!e||"LineString"!==e.type)throw new Error("Input must be a GeoJSON LineString");return polyline.encode(flipped(e.coordinates),o)},polyline.toGeoJSON=function(e,o){return{type:"LineString",coordinates:flipped(polyline.decode(e,o))}},"object"==typeof module&&module.exports&&(module.exports=polyline);
const line = location.hash.slice(1) || 'olnG{`uyRX|AvDw@~EIyAt[NzBjCzKhB`DzCbCjCx@`CTnb@y@bE^jDfBnJtJ`DlC`BR`@I|AyBxCcSl@uAvAgA|A_@dAE`BVv@`@tG~GxI~LjA`AbPxDzBv@nA|@tAxBlClJxHfH~B~@`]`G`Bj@v@r@v@~A`EtS~M|@rbAhSrGjChLtHwFtFd\\raApC{A`U{O`ItXhGbYr@tG|E`v@pD|c@dB|KfT`~@lGjh@tHbt@zOvrANAO@dDdYhB~SbDpMpGjSI~IXhE`FjZl@`BtGrGzZr]rWdTfKxHzMnLdH|CjKpD|E`CpK~Hru@xl@lAvAzEvIFf@hHnJJrBYfADd@a@pE`@rGfAk@Ve@k@cG';
const points = polyline.decode(line);
let minX, minY, maxX, maxY;
points.forEach(p => {
const [y, x] = p;
if (!minX) minX = x;
if (!maxX) maxX = x;
if (!minY) minY = y;
if (!maxY) maxY = y;
if (x < minX) minX = x;
if (x > maxX) maxX = x;
if (y < minY) minY = y;
if (y > maxY) maxY = y;
});
const width = maxX - minX;
const height = maxY - minY;
const padding = Math.sqrt(width * width + height * height) * 2 / 100;
const coords = points.map(c => c.reverse());
document.getElementById('svg').setAttribute('viewBox', `${minX - padding} ${minY - padding} ${width + padding * 2} ${height + padding * 2}`);
document.getElementById('l').setAttribute('points', coords.join(' '));
document.getElementById('circles').innerHTML = coords.map(c => {
return `<circle cx="${c[0]}" cy="${c[1]}" r=".1%" fill="white" stroke="black" vector-effect="non-scaling-stroke" />`;
});
// ]]>
</script>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment