wind-js-leaflet
Version:
Leaflet plugin to add WindJS data visualisation overlay
1 lines • 13.1 kB
JavaScript
"use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};L.DomUtil.setTransform=L.DomUtil.setTransform||function(t,n,e){var o=n||new L.Point(0,0);t.style[L.DomUtil.TRANSFORM]=(L.Browser.ie3d?"translate("+o.x+"px,"+o.y+"px)":"translate3d("+o.x+"px,"+o.y+"px,0)")+(e?" scale("+e+")":"")},L.CanvasLayer=(L.Layer?L.Layer:L.Class).extend({initialize:function(t){this._map=null,this._canvas=null,this._frame=null,this._delegate=null,L.setOptions(this,t)},delegate:function(t){return this._delegate=t,this},needRedraw:function(){return this._frame||(this._frame=L.Util.requestAnimFrame(this.drawLayer,this)),this},_onLayerDidResize:function(t){this._canvas.width=t.newSize.x,this._canvas.height=t.newSize.y},_onLayerDidMove:function(){var t=this._map.containerPointToLayerPoint([0,0]);L.DomUtil.setPosition(this._canvas,t),this.drawLayer()},getEvents:function(){var t={resize:this._onLayerDidResize,moveend:this._onLayerDidMove};return this._map.options.zoomAnimation&&L.Browser.any3d&&(t.zoomanim=this._animateZoom),t},onAdd:function(t){this._map=t,this._canvas=L.DomUtil.create("canvas","leaflet-layer"),this.tiles={};var n=this._map.getSize();this._canvas.width=n.x,this._canvas.height=n.y;var e=this._map.options.zoomAnimation&&L.Browser.any3d;L.DomUtil.addClass(this._canvas,"leaflet-zoom-"+(e?"animated":"hide")),t._panes.overlayPane.appendChild(this._canvas),t.on(this.getEvents(),this);var o=this._delegate||this;o.onLayerDidMount&&o.onLayerDidMount(),this.needRedraw()},onRemove:function(t){var n=this._delegate||this;n.onLayerWillUnmount&&n.onLayerWillUnmount(),t.getPanes().overlayPane.removeChild(this._canvas),t.off(this.getEvents(),this),this._canvas=null},addTo:function(t){return t.addLayer(this),this},LatLonToMercator:function(t){return{x:6378137*t.lng*Math.PI/180,y:6378137*Math.log(Math.tan((90+t.lat)*Math.PI/360))}},drawLayer:function(){var t=this._map.getSize(),n=this._map.getBounds(),e=this._map.getZoom(),o=this.LatLonToMercator(this._map.getCenter()),a=this.LatLonToMercator(this._map.containerPointToLatLng(this._map.getSize())),i=this._delegate||this;i.onDrawLayer&&i.onDrawLayer({layer:this,canvas:this._canvas,bounds:n,size:t,zoom:e,center:o,corner:a}),this._frame=null},_setTransform:function(t,n,e){var o=n||new L.Point(0,0);t.style[L.DomUtil.TRANSFORM]=(L.Browser.ie3d?"translate("+o.x+"px,"+o.y+"px)":"translate3d("+o.x+"px,"+o.y+"px,0)")+(e?" scale("+e+")":"")},_animateZoom:function(t){var n=this._map.getZoomScale(t.zoom),e=L.Layer?this._map._latLngToNewLayerPoint(this._map.getBounds().getNorthWest(),t.zoom,t.center):this._map._getCenterOffset(t.center)._multiplyBy(-n).subtract(this._map._getMapPanePos());L.DomUtil.setTransform(this._canvas,e,n)}}),L.canvasLayer=function(){return new L.CanvasLayer};var Windy=function(t){var n,e,o,a,i,r,s,l,h,u,c,d=.005*(Math.pow(window.devicePixelRatio,1/3)||1),f=261.15,m=317.15,_=90,p=1,v=.005,y=Math.pow(window.devicePixelRatio,1/3)||1.6,g=15,w=1e3/g,L=[NaN,NaN,null],M=function(t,n,e,o,a,i){var r=1-t,s=1-n,l=r*s,h=t*s,u=r*n,c=t*n,d=e[0]*l+o[0]*h+a[0]*u+i[0]*c,f=e[1]*l+o[1]*h+a[1]*u+i[1]*c,m=e[2]*l+o[2]*h+a[2]*u+i[2]*c;return[d,f,m]},x=function(t,n,e){var o=t.data,a=n.data;return{header:t.header,data:function(t){return[o[t],a[t],e.data[t]]},interpolate:M}},b=function(t){var n=null,e=null,o=null,a=null;return t.forEach(function(t){switch(t.header.parameterCategory+","+t.header.parameterNumber){case"2,2":n=t;break;case"2,3":e=t;break;case"0,0":o=t;break;default:a=t}}),x(n,e,o)},P=function(t,u){n=b(t);var c=n.header;a=c.lo1,i=c.la1,r=c.dx,s=c.dy,l=c.nx,h=c.ny,o=new Date(c.refTime),o.setHours(o.getHours()+c.forecastTime),e=[];for(var d=0,f=Math.floor(l*r)>=360,m=0;m<h;m++){for(var _=[],p=0;p<l;p++,d++)_[p]=n.data(d);f&&_.push(_[0]),e[m]=_}u({date:o,interpolate:D})},D=function(t,o){if(!e)return null;var l,h=C(t-a,360)/r,u=(i-o)/s,c=Math.floor(h),d=c+1,f=Math.floor(u),m=f+1;if(l=e[f]){var _=l[c],p=l[d];if(T(_)&&T(p)&&(l=e[m])){var v=l[c],y=l[d];if(T(v)&&T(y))return n.interpolate(h-c,u-f,_,p,v,y)}}return null},T=function(t){return null!==t&&void 0!==t},C=function(t,n){return t-n*Math.floor(t/n)},S=function(){return/android|blackberry|iemobile|ipad|iphone|ipod|opera mini|webos/i.test(navigator.userAgent)},W=function(t,n,e,o,a,i,r,s){var l=r[0]*i,h=r[1]*i,u=z(t,n,e,o,a,s);return r[0]=u[0]*l+u[2]*h,r[1]=u[1]*l+u[3]*h,r},z=function(t,n,e,o,a,i){var r=2*Math.PI,s=Math.pow(10,-5.2),l=n<0?s:-s,h=e<0?s:-s,u=E(e,n+l,i),c=E(e+h,n,i),d=Math.cos(e/360*r);return[(u[0]-o)/l/d,(u[1]-a)/l/d,(c[0]-o)/h,(c[1]-a)/h]},R=function(t,n,e){function o(n,e){if(!t)return[NaN,NaN,null];var o=t[Math.round(n)];return o&&o[Math.round(e)]||L}o.release=function(){t=[]},o.randomize=function(t){var e,a,i=0;do e=Math.round(Math.floor(Math.random()*n.width)+n.x),a=Math.round(Math.floor(Math.random()*n.height)+n.y);while(null===o(e,a)[2]&&i++<30);return t.x=e,t.y=a,t},e(n,o)},A=function(t,n,e){var o=t[0],a=t[1],i=Math.round(o[0]),r=Math.max(Math.floor(o[1],0),0),s=(Math.min(Math.ceil(a[0],n),n-1),Math.min(Math.ceil(a[1],e),e-1));return{x:i,y:r,xMax:n,yMax:s,width:n,height:e}},F=function(t){return t/180*Math.PI},N=function(t){return t/(Math.PI/180)},U=function(t,n,e){var o=e.east-e.west,a=e.width/N(o)*360/(2*Math.PI),i=a/2*Math.log((1+Math.sin(e.south))/(1-Math.sin(e.south))),r=e.height+i,s=(r-n)/a,l=180/Math.PI*(2*Math.atan(Math.exp(s))-Math.PI/2),h=N(e.west)+t/e.width*N(o);return[h,l]},I=function(t){return Math.log(Math.tan(t/2+Math.PI/4))},E=function(t,n,e){var o=I(e.south),a=I(e.north),i=e.width/(e.east-e.west),r=e.height/(a-o),s=I(F(t)),l=(F(n)-e.west)*i,s=(a-s)*r;return[l,s]},k=function(t,n,e,o){function a(o){for(var a=[],r=n.y;r<=n.yMax;r+=2){var h=U(o,r,e);if(h){var u=h[0],c=h[1];if(isFinite(u)){var d=t.interpolate(u,c);d&&(d=W(i,u,c,o,r,s,d,e),a[r+1]=a[r]=d)}}}l[o+1]=l[o]=a}for(var i={},r=(e.south-e.north)*(e.west-e.east),s=d*Math.pow(r,.3),l=[],h=n.x;h<n.width;h+=2)a(h);R(l,n,o)},q=function(n,e,o){function a(t,n){var e=["rgb(36,104, 180)","rgb(60,157, 194)","rgb(128,205,193 )","rgb(151,218,168 )","rgb(198,231,181)","rgb(238,247,217)","rgb(255,238,159)","rgb(252,217,125)","rgb(255,182,100)","rgb(252,150,75)","rgb(250,112,52)","rgb(245,64,32)","rgb(237,45,28)","rgb(220,24,32)","rgb(180,0,35)"];return e.indexFor=function(o){return Math.max(0,Math.min(e.length-1,Math.round((o-t)/(n-t)*(e.length-1))))},e}function i(){l.forEach(function(t){t.length=0}),u.forEach(function(t){t.age>_&&(e.randomize(t).age=~~(Math.random()*_/2));var n=t.x,o=t.y,a=e(n,o),i=a[2];if(null===i)t.age=_;else{var r=n+a[0],h=o+a[1];null!==e(r,h)[0]?(t.xt=r,t.yt=h,l[s.indexFor(i)].push(t)):(t.x=r,t.y=h)}t.age+=1})}function r(){L.save(),L.globalAlpha=.16,L.globalCompositeOperation="destination-out",L.fillStyle="#000",L.fillRect(n.x,n.y,n.width,n.height),L.restore(),l.forEach(function(t,n){t.length>0&&(L.beginPath(),L.strokeStyle=s[n],t.forEach(function(t){L.moveTo(t.x,t.y),L.lineTo(t.xt,t.yt),t.x=t.xt,t.y=t.yt}),L.stroke())})}var s=a(f,m),l=s.map(function(){return[]}),h=(o.south-o.north)*(o.west-o.east),d=Math.round(n.width*n.height*v*Math.pow(h,.24));S()&&(d/=y),u=u||[],u.length>d&&(u=u.slice(0,d));for(var g=u.length;g<d;g++)u.push(e.randomize({age:~~(Math.random()*_)+0}));var L=t.canvas.getContext("2d");L.lineWidth=p;var M=Date.now();!function x(){c=requestAnimationFrame(x);var t=Date.now(),n=t-M;n>w&&(M=t-n%w,i(),r())}()},O=function(n,e,o,a,i){delete t.data,t.data=n,i&&B(e,o,a,i)},B=function(n,e,o,a){var i={south:F(a[0][1]),north:F(a[1][1]),east:F(a[1][0]),west:F(a[0][0]),width:e,height:o};H(),P(t.data,function(t){k(t,A(n,e,o),i,function(t,n){$.field=n,q(t,n,i)})})},H=function(){$.field&&$.field.release(),c&&cancelAnimationFrame(c)},j=function(n,e){var o=t.canvas,a=o.width,i=o.height,r=o.getContext("2d");if(a>n&&i>e){var s=function(t,n){return Math.max(0,Math.min(t,n))},l=r.getImageData(s(a,-n),s(i,-e),s(a,a-n),s(i,i-e));r.clearRect(0,0,a,i),r.putImageData(l,s(a,n),s(i,e));for(var h=0,c=u.length;h<c;h++)u[h].x+=n,u[h].y+=e}},$={params:t,start:B,stop:H,update:O,shift:j,createField:R,interpolatePoint:D};return $};window.requestAnimationFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/FRAME_RATE)}}(),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(t){clearTimeout(t)}),L.Control.WindPosition=L.Control.extend({options:{position:"bottomleft",emptyString:"Unavailable"},onAdd:function(t){return this._container=L.DomUtil.create("div","leaflet-control-wind-position"),L.DomEvent.disableClickPropagation(this._container),t.on("mousemove",this._onMouseMove,this),this._container.innerHTML=this.options.emptyString,this._container},onRemove:function(t){t.off("mousemove",this._onMouseMove,this)},vectorToSpeed:function(t,n){var e=Math.sqrt(Math.pow(t,2)+Math.pow(n,2));return e},vectorToDegrees:function(t,n){var e=Math.sqrt(Math.pow(t,2)+Math.pow(n,2)),o=Math.atan2(t/e,n/e),a=180*o/Math.PI,i=a+180;return i.toFixed(3)},_onMouseMove:function(t){var n=this,e=this.options.WindJSLeaflet._map.containerPointToLatLng(L.point(t.containerPoint.x,t.containerPoint.y)),o=this.options.WindJSLeaflet._windy.interpolatePoint(e.lng,e.lat),a="";if(o&&!isNaN(o[0])&&!isNaN(o[1])&&o[2]){var i=o[1];i=i>0?i-=2*i:Math.abs(i),a="<strong>Wind Direction: </strong>"+n.vectorToDegrees(o[0],i)+"°, <strong>Wind Speed: </strong>"+n.vectorToSpeed(o[0],i).toFixed(1)+"m/s, <strong>Temp: </strong>"+(o[2]-273.15).toFixed(1)+"°C"}else a="no wind data";n._container.innerHTML=a,0==$(".leaflet-control-wind-position").index()&&$(".leaflet-control-wind-position").insertAfter(".leaflet-control-mouseposition")}}),L.Map.mergeOptions({positionControl:!1}),L.Map.addInitHook(function(){this.options.positionControl&&(this.positionControl=new L.Control.MousePosition,this.addControl(this.positionControl))}),L.control.windPosition=function(t){return new L.Control.WindPosition(t)},function(t,n){"object"===("undefined"==typeof exports?"undefined":_typeof(exports))?module.exports=n(require("wind-js-leaflet")):"function"==typeof define&&define.amd?define(["wind-js-leaflet"],function(e){return t.returnExportsGlobal=n(window)}):window.WindJSLeaflet=n(window)}(void 0,function(t){var n={_map:null,_data:null,_options:null,_canvasLayer:null,_windy:null,_context:null,_timer:0,_mouseControl:null,init:function(t){n._checkWind(t).then(function(){n._map=t.map,n._options=t,n._canvasLayer=L.canvasLayer().delegate(n),n._options.layerControl.addOverlay(n._canvasLayer,t.overlayName||"wind"),n._map.on("overlayremove",function(t){t.layer==n._canvasLayer&&n._destroyWind()})})["catch"](function(t){console.log("err"),n._options.errorCallback(t)})},setTime:function(t){n._options.timeISO=t},_checkWind:function(t){return new Promise(function(n,e){t.localMode&&n(!0),$.ajax({type:"GET",url:t.pingUrl,error:function(t){e(t)},success:function(t){n(t)}})})},_getRequestUrl:function(){if(!this._options.useNearest)return this._options.latestUrl;var t={timeIso:this._options.timeISO||(new Date).toISOString(),searchLimit:this._options.nearestDaysLimit||7};return this._options.nearestUrl+"?"+$.param(t)},_loadLocalData:function(){console.log("using local data.."),$.getJSON("demo.json",function(t){n._data=t,n._initWindy(t)})},_loadWindData:function(){if(this._options.localMode)return void this._loadLocalData();var t=this._getRequestUrl();console.log(t),$.ajax({type:"GET",url:t,error:function(t){console.log("error loading data"),n._options.errorCallback(t)||console.log(t),n._loadLocalData()},success:function(t){n._data=t,n._initWindy(t)}})},onDrawLayer:function(t,e){return n._windy?(this._timer&&clearTimeout(n._timer),void(this._timer=setTimeout(function(){var t=n._map.getBounds(),e=n._map.getSize();n._windy.start([[0,0],[e.x,e.y]],e.x,e.y,[[t._southWest.lng,t._southWest.lat],[t._northEast.lng,t._northEast.lat]])},750))):void n._loadWindData()},_initWindy:function(t){this._windy=new Windy({canvas:n._canvasLayer._canvas,data:t}),this._context=this._canvasLayer._canvas.getContext("2d"),this._canvasLayer._canvas.classList.add("wind-overlay"),this.onDrawLayer(),this._map.on("dragstart",n._windy.stop),this._map.on("zoomstart",n._clearWind),this._map.on("resize",n._clearWind),this._initMouseHandler()},_initMouseHandler:function(){if(!this._mouseControl&&this._options.displayValues){var t=this._options.displayOptions||{};t.WindJSLeaflet=n,this._mouseControl=L.control.windPosition(t).addTo(this._map)}},_clearWind:function(){this._windy&&this._windy.stop(),this._context&&this._context.clearRect(0,0,3e3,3e3)},_destroyWind:function(){this._timer&&clearTimeout(this._timer),this._windy&&this._windy.stop(),this._context&&this._context.clearRect(0,0,3e3,3e3),this._mouseControl&&this._map.removeControl(this._mouseControl),this._mouseControl=null,this._windy=null,this._map.removeLayer(this._canvasLayer)}};return n});