UNPKG

@goshawk22/leaflet-elevation

Version:

A Leaflet plugin that allows to add elevation profiles using d3js

1 lines 5.87 kB
!function(root,plugin){"function"==typeof define&&define.amd?define(["leaflet"],plugin):"object"==typeof exports?module.exports=plugin:plugin(root.L)}(window,(function(L){if(L.Hotline)return L;var Hotline=function(canvas){if(!(this instanceof Hotline))return new Hotline(canvas);var defaultPalette={0:"green",.5:"yellow",1:"red"};this._canvas=canvas="string"==typeof canvas?document.getElementById(canvas):canvas,this._ctx=canvas.getContext("2d"),this._width=canvas.width,this._height=canvas.height,this._weight=5,this._outlineWidth=1,this._outlineColor="black",this._min=0,this._max=1,this._data=[],this.palette(defaultPalette)};Hotline.prototype={width:function(width){return this._width=width,this},height:function(height){return this._height=height,this},weight:function(weight){return this._weight=weight,this},outlineWidth:function(outlineWidth){return this._outlineWidth=outlineWidth,this},outlineColor:function(outlineColor){return this._outlineColor=outlineColor,this},palette:function(palette){var canvas=document.createElement("canvas"),ctx=canvas.getContext("2d"),gradient=ctx.createLinearGradient(0,0,0,256);for(var i in canvas.width=1,canvas.height=256,palette)gradient.addColorStop(i,palette[i]);return ctx.fillStyle=gradient,ctx.fillRect(0,0,1,256),this._palette=ctx.getImageData(0,0,1,256).data,this},min:function(min){return this._min=min,this},max:function(max){return this._max=max,this},data:function(data){return this._data=data,this},add:function(path){return this._data.push(path),this},draw:function(){var ctx=this._ctx;return ctx.globalCompositeOperation="source-over",ctx.lineCap="round",this._drawOutline(ctx),this._drawHotline(ctx),this},getRGBForValue:function(value){var valueRelative=Math.min(Math.max((value-this._min)/(this._max-this._min),0),.999),paletteIndex=4*Math.floor(256*valueRelative);return[this._palette[paletteIndex],this._palette[paletteIndex+1],this._palette[paletteIndex+2]]},_drawOutline:function(ctx){var i,j,dataLength,path,pathLength,pointStart,pointEnd;if(this._outlineWidth)for(i=0,dataLength=this._data.length;i<dataLength;i++)for(path=this._data[i],ctx.lineWidth=this._weight+2*this._outlineWidth,j=1,pathLength=path.length;j<pathLength;j++)pointStart=path[j-1],pointEnd=path[j],ctx.strokeStyle=this._outlineColor,ctx.beginPath(),ctx.moveTo(pointStart.x,pointStart.y),ctx.lineTo(pointEnd.x,pointEnd.y),ctx.stroke()},_drawHotline:function(ctx){var i,j,dataLength,path,pathLength,pointStart,pointEnd,gradient,gradientStartRGB,gradientEndRGB;for(ctx.lineWidth=this._weight,i=0,dataLength=this._data.length;i<dataLength;i++)for(j=1,pathLength=(path=this._data[i]).length;j<pathLength;j++)pointStart=path[j-1],pointEnd=path[j],gradient=ctx.createLinearGradient(pointStart.x,pointStart.y,pointEnd.x,pointEnd.y),gradientStartRGB=this.getRGBForValue(pointStart.z),gradientEndRGB=this.getRGBForValue(pointEnd.z),gradient.addColorStop(0,"rgb("+gradientStartRGB.join(",")+")"),gradient.addColorStop(1,"rgb("+gradientEndRGB.join(",")+")"),ctx.strokeStyle=gradient,ctx.beginPath(),ctx.moveTo(pointStart.x,pointStart.y),ctx.lineTo(pointEnd.x,pointEnd.y),ctx.stroke()}};var Renderer=L.Canvas.extend({_initContainer:function(){L.Canvas.prototype._initContainer.call(this),this._hotline=new Hotline(this._container)},_update:function(){L.Canvas.prototype._update.call(this),this._hotline.width(this._container.width),this._hotline.height(this._container.height)},_updatePoly:function(layer){if(this._drawing){var parts=layer._parts;parts.length&&(this._updateOptions(layer),this._hotline.data(parts).draw())}},_updateOptions:function(layer){null!=layer.options.min&&this._hotline.min(layer.options.min),null!=layer.options.max&&this._hotline.max(layer.options.max),null!=layer.options.weight&&this._hotline.weight(layer.options.weight),null!=layer.options.outlineWidth&&this._hotline.outlineWidth(layer.options.outlineWidth),null!=layer.options.outlineColor&&this._hotline.outlineColor(layer.options.outlineColor),layer.options.palette&&this._hotline.palette(layer.options.palette)}}),renderer=function(options){return L.Browser.canvas?new Renderer(options):null},Util={clipSegment:function(a,b,bounds,useLastCode,round){var codeA=useLastCode?this._lastCode:L.LineUtil._getBitCode(a,bounds),codeB=L.LineUtil._getBitCode(b,bounds),codeOut,p,newCode;for(this._lastCode=codeB;;){if(!(codeA|codeB))return[a,b];if(codeA&codeB)return!1;codeOut=codeA||codeB,p=L.LineUtil._getEdgeIntersection(a,b,codeOut,bounds,round),newCode=L.LineUtil._getBitCode(p,bounds),codeOut===codeA?(p.z=a.z,a=p,codeA=newCode):(p.z=b.z,b=p,codeB=newCode)}}};return L.Hotline=L.Polyline.extend({statics:{Renderer:Renderer,renderer:renderer},options:{renderer:renderer(),min:0,max:1,palette:{0:"green",.5:"yellow",1:"red"},weight:5,outlineColor:"black",outlineWidth:1},getRGBForValue:function(value){return this._renderer._hotline.getRGBForValue(value)},_projectLatlngs:function(latlngs,result,projectedBounds){var flat=latlngs[0]instanceof L.LatLng,len=latlngs.length,i,ring;if(flat){for(ring=[],i=0;i<len;i++)ring[i]=this._map.latLngToLayerPoint(latlngs[i]),ring[i].z=latlngs[i].alt,projectedBounds.extend(ring[i]);result.push(ring)}else for(i=0;i<len;i++)this._projectLatlngs(latlngs[i],result,projectedBounds)},_clipPoints:function(){if(this.options.noClip)this._parts=this._rings;else{this._parts=[];var parts=this._parts,bounds=this._renderer._bounds,i,j,k,len,len2,segment,points;for(i=0,k=0,len=this._rings.length;i<len;i++)for(j=0,len2=(points=this._rings[i]).length;j<len2-1;j++)(segment=Util.clipSegment(points[j],points[j+1],bounds,j,!0))&&(parts[k]=parts[k]||[],parts[k].push(segment[0]),segment[1]===points[j+1]&&j!==len2-2||(parts[k].push(segment[1]),k++))}},_clickTolerance:function(){return this.options.weight/2+this.options.outlineWidth+(L.Browser.touch?10:0)}}),L.hotline=function(latlngs,options){return new L.Hotline(latlngs,options)},L}));