wind-layer
Version:
a openlayers ol bmap amap maptalks extension to windjs
2 lines (1 loc) • 11.6 kB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).windLayer=e()}(this,function(){"use strict";function u(l){void 0===l&&(l={}),this.params=l;var p=this;function e(t){t.projection||(t.projection="EPSG:4326"),p.MIN_VELOCITY_INTENSITY=t.minVelocity||0,p.MAX_VELOCITY_INTENSITY=t.maxVelocity||10,p.VELOCITY_SCALE=(t.velocityScale||.005)*(Math.pow(window.devicePixelRatio,1/3)||1),p.MAX_PARTICLE_AGE=t.particleAge||90,p.PARTICLE_LINE_WIDTH=t.lineWidth||1,p.PARTICLE_MULTIPLIER=t.particleMultiplier||1/300,p.PARTICLE_REDUCTION=Math.pow(window.devicePixelRatio,1/3)||1.6,p.FRAME_RATE=t.frameRate||16,p.COLOR_SCALE=t.colorScale||n,p.DEVICEPIXELRATIO=t.devicePixelRatio||1}p.canvas=l.canvas;var n=["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)"];function i(t,e,n,a,i,o){var r=1-t,s=1-e,h=r*s,c=t*s,u=r*e,l=t*e,d=n[0]*h+a[0]*c+i[0]*u+o[0]*l,p=n[1]*h+a[1]*c+i[1]*u+o[1]*l;return[d,p,Math.sqrt(d*d+p*p)]}function h(t){var e=null,n=null;return t.forEach(function(t){switch(t.header.parameterCategory+","+t.header.parameterNumber){case"1,2":case"2,2":e=t;break;case"1,3":case"2,3":n=t}}),function(t,e){var n=t.data,a=e.data;return{header:t.header,data:function(t){return[n[t],a[t]]},interpolate:i}}(e,n)}function o(a,i,t){function o(t,e){var n=a[Math.round(t)];return n&&n[Math.round(e)]||r}o.release=function(){a=[]},o.randomize=function(t){for(var e,n,a=0;null===o(e=Math.round(Math.floor(Math.random()*i.width)+i.x),n=Math.round(Math.floor(Math.random()*i.height)+i.y))[2]&&a++<30;);return t.x=e,t.y=n,t},t(i,o)}function c(t){return t/180*Math.PI}function u(t){return t/(Math.PI/180)}e(l),window.FRAME_TIME=1e3/p.FRAME_RATE;var f,m,d,v,g,w,y,M,E,A,r=[NaN,NaN,null],s=p.params.data,_=function(t,e){if(!m)return null;var n,a=C(t-v,360)/w,i=(g-e)/y,o=Math.floor(a),r=o+1,s=Math.floor(i),h=s+1;if(n=m[s]){var c=n[o],u=n[r];if(I(c)&&I(u)&&(n=m[h])){var l=n[o],d=n[r];if(I(l)&&I(d))return f.interpolate(a-o,i-s,c,u,l,d)}}return null},I=function(t){return null!=t},C=function(t,e){return t-e*Math.floor(t/e)},R=function(t,e,n,a,i,o){var r=2*Math.PI,s="EPSG:4326"===p.params.projection?5:Math.pow(10,-5.2),h=e<0?s:-s,c=n<0?s:-s,u=b(n,e+h,o),l=b(n+c,e,o),d=Math.cos(n/360*r);return[(u[0]-a)/h/d,(u[1]-i)/h/d,(l[0]-a)/c,(l[1]-i)/c]};function L(t){return Math.log(Math.tan(t/2+Math.PI/4))}function T(a,s){var e,n,h=(e=p.MIN_VELOCITY_INTENSITY,n=p.MAX_VELOCITY_INTENSITY,p.COLOR_SCALE.indexFor=function(t){return Math.max(0,Math.min(p.COLOR_SCALE.length-1,Math.round((t-e)/(n-e)*(p.COLOR_SCALE.length-1))))},p.COLOR_SCALE),c=h.map(function(){return[]}),t=Math.round(a.width*a.height*p.PARTICLE_MULTIPLIER);/android|blackberry|iemobile|ipad|iphone|ipod|opera mini|webos/i.test(navigator.userAgent)&&(t*=p.PARTICLE_REDUCTION);for(var i=[],o=0;o<t;o++)i.push(s.randomize({age:Math.floor(Math.random()*p.MAX_PARTICLE_AGE)+0}));var r=p.canvas.getContext("2d");r.lineWidth=p.PARTICLE_LINE_WIDTH,r.fillStyle="rgba(0, 0, 0, 0.97)",r.globalAlpha=.6;var u=Date.now();!function t(){x=requestAnimationFrame(t);var e=Date.now(),n=e-u;n>FRAME_TIME&&(u=e-n%FRAME_TIME,c.forEach(function(t){t.length=0}),i.forEach(function(t){t.age>p.MAX_PARTICLE_AGE&&(s.randomize(t).age=0);var e=t.x,n=t.y,a=s(e,n),i=a[2];if(null===i)t.age=p.MAX_PARTICLE_AGE;else{var o=e+a[0],r=n+a[1];null!==s(o,r)[2]?(t.xt=o,t.yt=r,c[h.indexFor(i)].push(t)):(t.x=o,t.y=r)}t.age+=1}),r.globalCompositeOperation="destination-in",r.fillRect(a.x,a.y,p.canvas.width,p.canvas.height),r.globalCompositeOperation="lighter",r.globalAlpha=.9,c.forEach(function(t,e){0<t.length&&(r.beginPath(),r.strokeStyle=h[e],t.forEach(function(t){r.moveTo(t.x*p.DEVICEPIXELRATIO,t.y*p.DEVICEPIXELRATIO),r.lineTo(t.xt*p.DEVICEPIXELRATIO,t.yt*p.DEVICEPIXELRATIO),t.x=t.xt,t.y=t.yt}),r.stroke())}),l.onDraw&&l.onDraw())}()}A="EPSG:4326"===p.params.projection?function(t,e,n){var a=n.east-n.west,i=n.south-n.north,o=u(n.north)+e/n.height*u(i);return[u(n.west)+t/n.width*u(a),o]}:function(t,e,n){var a=n.east-n.west,i=n.width/u(a)*360/(2*Math.PI),o=i/2*Math.log((1+Math.sin(n.south))/(1-Math.sin(n.south))),r=(n.height+o-e)/i,s=180/Math.PI*(2*Math.atan(Math.exp(r))-Math.PI/2);return[u(n.west)+t/n.width*u(a),s]};var x,b=function(t,e,n){var a=L(n.south),i=L(n.north),o=n.width/(n.east-n.west),r=n.height/(i-a),s=L(c(t));return[(c(e)-n.west)*o,s=(i-s)*r]},P=function(e,n,a,t){var i={south:c(t[0][1]),north:c(t[1][1]),east:c(t[1][0]),west:c(t[0][0]),width:n,height:a};F(),function(t,e){var n=(f=h(t)).header;v=n.lo1,g=Math.max(n.la2,n.la1),w=n.dx,y=n.dy,M=n.nx,E=n.ny,(d=new Date(n.refTime)).setHours(d.getHours()+n.forecastTime),m=[];for(var a=0,i=360<=Math.floor(M*w),o=0;o<E;o++){for(var r=[],s=0;s<M;s++,a++)r[s]=f.data(a);i&&r.push(r[0]),m[o]=r}e({date:d,interpolate:_})}(s,function(t){!function(w,y,M,n){var E={},t=(M.south-M.north)*(M.west-M.east),_=p.VELOCITY_SCALE*Math.pow(t,.4),I=[],a=y.x;function i(t){for(var e,n,a,i,o,r,s,h,c,u,l,d=[],p=y.y;p<=y.yMax;p+=2){var f=A(t,p,M);if(f){var m=f[0],v=f[1];if(isFinite(m)){var g=w.interpolate(m,v);g&&(e=E,n=m,a=v,i=t,o=p,r=_,h=M,void 0,c=(s=g)[0]*r,u=s[1]*r,l=R(e,n,a,i,o,h),s[0]=l[0]*c+l[2]*u,s[1]=l[1]*c+l[3]*u,g=s,d[p+1]=d[p]=g)}}}I[t+1]=I[t]=d}!function t(){for(var e=Date.now();a<y.width;)if(i(a),a+=2,1e3<Date.now()-e)return void setTimeout(t,25);o(I,y,n)}()}(t,function(t,e,n){var a=t[0],i=t[1],o=Math.round(a[0]),r=Math.max(Math.floor(a[1],0),0);Math.min(Math.ceil(i[0],e),e-1);return{x:o,y:r,xMax:e,yMax:Math.min(Math.ceil(i[1],n),n-1),width:e,height:n}}(e,n,a),i,function(t,e){S.field=e,T(t,e)})})},F=function(){S.field&&S.field.release(),x&&cancelAnimationFrame(x)},S={params:p.params,start:P,stop:F,update:function(t,e,n,a,i){delete p.params.data,p.params.data=t,i&&P(e,n,a,i)},shift:function(t,e){var n=p.canvas,a=n.width,i=n.height,o=n.getContext("2d");if(t<a&&e<i){var r=function(t,e){return Math.max(0,Math.min(t,e))},s=o.getImageData(r(a,-t),r(i,-e),r(a,a-t),r(i,i-e));o.clearRect(0,0,a,i),o.putImageData(s,r(a,t),r(i,e));for(var h=0,c=particles.length;h<c;h++)particles[h].x+=t,particles[h].y+=e}},createField:o,interpolatePoint:_,setData:function(t){s=t},updateParams:function(t){p.params=t,e(p.params)},getParams:function(){return p.params},buildParams:e};return S}window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/window.FRAME_RATE)},window.cancelAnimationFrame||(window.cancelAnimationFrame=function(t){clearTimeout(t)});function t(t,e){void 0===e&&(e={}),this.options=e,this.canvas=null,this.data=t,this.layer_=null,this._windy=null,e.map&&this.appendTo(e.map),this.init=this.init.bind(this),this.handleResize=this.handleResize.bind(this),this.canvasFunction=this.canvasFunction.bind(this),this._addReFreshHandle=this._addReFreshHandle.bind(this)}var i=function(t){return t/.514},o=function(t){return 3.6*t},r=("undefined"==typeof window?{}:window).AMap||{};return t.prototype.appendTo=function(t){if(!t)throw new Error("not map object");this.init(t)},t.prototype.getData=function(){return this.data},t.prototype.setData=function(t){this.data=t,this.map&&this.canvas&&this.data&&this.render(this.canvas)},t.prototype.init=function(t,e){if(!t)throw new Error("not map object");this.map=t,this.context=this.options.context||"2d",this.getCanvasLayer(),this.map.on("resize",this.handleResize,this)},t.prototype.handleResize=function(){this.canvas&&this.canvasFunction()},t.prototype.render=function(t){if(t){var e=this._getExtent();if(!this.getData()||!e)return this;if(t&&!this._windy){var n=this.options,a=n.minVelocity,i=n.maxVelocity,o=n.velocityScale,r=n.particleAge,s=n.lineWidth,h=n.particleMultiplier,c=n.colorScale;this._windy=new u({canvas:t,data:this.getData(),onDraw:function(){},minVelocity:a,maxVelocity:i,velocityScale:o,particleAge:r,lineWidth:s,particleMultiplier:h,colorScale:c}),this._windy.start(e[0],e[1],e[2],e[3])}else t&&this._windy&&this._windy.start(e[0],e[1],e[2],e[3]);return this._addReFreshHandle(),this}},t.prototype._addReFreshHandle=function(){this.map&&"3d"===this.map.getViewMode_().toLowerCase()&&(this.layer_&&this.layer_.reFresh(),r.Util.requestAnimFrame(this._addReFreshHandle))},t.prototype.getCanvasLayer=function(){if(!this.canvas&&!this.layer_){var t=this.canvasFunction(),e=this._getBounds();this.layer_=new r.CanvasLayer({canvas:t,bounds:this.options.bounds||e,zooms:this.options.zooms||[0,22],zIndex:this.options.zIndex||12,opacity:this.options.opacity||1}),this.map.on("mapmove",this.canvasFunction,this),this.map.on("zoomchange",this.canvasFunction,this),this.layer_.setMap(this.map)}},t.prototype.canvasFunction=function(){var t=[this.map.getSize().width,this.map.getSize().height],e=t[0],n=t[1];if(this.canvas){this.canvas.width=e,this.canvas.height=n;var a=this._getBounds();this.layer_&&this.layer_.setBounds(this.options.bounds||a)}else this.canvas=function(t,e,n){if("undefined"==typeof document)return new n(t,e);var a=document.createElement("canvas");return a.width=t,a.height=e,a}(e,n,null);return this.render(this.canvas),this.canvas},t.prototype._getBounds=function(){var t=this.map.getViewMode_(),e=[],n=e[0],a=e[1],i=this.map.getBounds();if("2d"===t.toLowerCase())a=i.getNorthEast(),n=i.getSouthWest();else{var o=i.bounds.map(function(t){return[t.getLng(),t.getLat()]});n=new(Function.prototype.bind.apply(r.LngLat,[null].concat(o[3]))),a=new(Function.prototype.bind.apply(r.LngLat,[null].concat(o[1])))}return new r.Bounds(n,a)},t.prototype._getExtent=function(){var t=[this.map.getSize().width,this.map.getSize().height],e=t[0],n=t[1],a=this._getBounds(),i=a.getNorthEast(),o=a.getSouthWest(),r=o.lng,s=i.lng<0?360+i.lng:i.lng,h=Math.min(r,s),c=Math.max(r,s);return[[[0,0],[e,n]],e,n,[[h,o.lat],[c,i.lat]]]},t.prototype.removeLayer=function(){this.map&&(this.layer_.setMap(null),this.map.off("resize",this.handleResize,this),this.map.off("mapmove",this.canvasFunction,this),this.map.off("zoomchange",this.canvasFunction,this),delete this.map,delete this.layer_,delete this.canvas)},t.prototype.getContext=function(){return this.canvas.getContext(this.context)},t.prototype.getPointData=function(t){var e=this._windy.interpolatePoint(t[0],t[1]);if(e&&!isNaN(e[0])&&!isNaN(e[1])&&e[2])return{direction:function(t,e,n){n.endsWith("CCW")&&(e=0<e?e=-e:Math.abs(e));var a=Math.sqrt(Math.pow(t,2)+Math.pow(e,2)),i=180*Math.atan2(t/a,e/a)/Math.PI+180;return"bearingCW"!==n&&"meteoCCW"!==n||360<=(i+=180)&&(i-=360),i}(e[0],e[1],this.options.angleConvention||"bearingCCW"),speed:function(t,e,n){var a=Math.sqrt(Math.pow(t,2)+Math.pow(e,2));return"k/h"===n?o(a):"kt"===n?i(a):a}(e[0],e[1],this.options.speedUnit)}},t.prototype.clearWind=function(){this._windy&&this._windy.stop()},t.prototype.updateParams=function(t){if(this.options=Object.assign(this.options,t),this._windy){var e=this.options,n=e.minVelocity,a=e.maxVelocity,i=e.velocityScale,o=e.particleAge,r=e.lineWidth,s=e.particleMultiplier,h=e.colorScale;this._windy&&(this._windy.updateParams({minVelocity:n,maxVelocity:a,velocityScale:i,particleAge:o,lineWidth:r,particleMultiplier:s,colorScale:h}),this.map&&this.canvas&&this.data&&this.render(this.canvas))}return this},t.prototype.getParams=function(){return this._windy&&this._windy.getParams()},t});