一、风场类编写
/*** * 风场类 * date:2022-03-14 * author:zdh * @type {CanvasWindy} */ import {Cartesian3,EllipsoidalOccluder,SceneTransforms,Ellipsoid,Cartesian2,Math as CMath} from 'cesium/Cesium' export let CanvasWindy = function (json,params) { //风场json数据 this.windData = json; //可配置参数 this.viewer = params.viewer; this.canvas = params.canvas; this.extent = params.extent || [];//风场绘制时的地图范围,范围不应该大于风场数据的范围,顺序:west/east/south/north,有正负区分,如:[110,120,30,36] this.canvasContext = params.canvas.getContext("2d");//canvas上下文 this.canvasWidth = params.canvasWidth || 300;//画板宽度 this.canvasHeight = params.canvasHeight || 180;//画板高度 this.speedRate = params.speedRate || 100;//风前进速率,意思是将当前风场横向纵向分成100份,再乘以风速就能得到移动位置,无论地图缩放到哪一级别都是一样的速度,可以用该数值控制线流动的快慢,值越大,越慢, this.particlesNumber = params.particlesNumber || 20000;//初始粒子总数,根据实际需要进行调节 this.maxAge = params.maxAge || 120;//每个粒子的最大生存周期 this.frameTime = 1000/(params.frameRate || 10);//每秒刷新次数,因为requestAnimationFrame固定每秒60次的渲染,所以如果不想这么快,就把该数值调小一些 this.color = params.color || '#ffffff';//线颜色,提供几个示例颜色['#14208e','#3ac32b','#e0761a'] this.lineWidth = params.lineWidth || 1;//线宽度 //内置参数 this.initExtent = [];//风场初始范围 this.calc_speedRate = [0,0];//根据speedRate参数计算经纬度步进长度 this.windField = null; this.particles = []; this.animateFrame = null;//requestAnimationFrame事件句柄,用来清除操作 this.isdistory = false;//是否销毁,进行删除操作 this._init(); }; CanvasWindy.prototype = { constructor: CanvasWindy, _init: function () { let self = this; // 创建风场网格 this.windField = this.createField(); this.initExtent = [this.windField.west,this.windField.east,this.windField.south,this.windField.north]; //如果风场创建时,传入的参数有extent,就根据给定的extent,让随机生成的粒子落在extent范围内 if(this.extent.length!=0){ this.extent = [ Math.max(this.initExtent[0],this.extent[0]), Math.min(this.initExtent[1],this.extent[1]), Math.max(this.initExtent[2],this.extent[2]), Math.min(this.initExtent[3],this.extent[3]) ]; } // console.log(this.extent); this._calcStep(); // 创建风场粒子 for (let i = 0; i < this.particlesNumber; i++) { this.particles.push(this.randomParticle(new CanvasParticle())); } this.canvasContext.fillStyle = "rgba(0, 0, 0, 0.97)"; this.canvasContext.globalAlpha = 0.6; this.animate(); let then = Date.now(); (function frame() { if(!self.isdistory){ self.animateFrame = requestAnimationFrame(frame); let now = Date.now(); let delta = now - then; if (delta > self.frameTime) { then = now - delta % self.frameTime; self.animate(); } }else{ self.removeLines(); } })(); }, //计算经纬度步进长度 _calcStep:function(){ let isextent = (this.extent.length!=0); let calcExtent = isextent?this.extent:this.initExtent; let calcSpeed = this.speedRate; this.calc_speedRate = [(calcExtent[1]-calcExtent[0])/calcSpeed,(calcExtent[3]-calcExtent[2])/calcSpeed]; }, //根据现有参数重新生成风场 redraw:function(){ window.cancelAnimationFrame(this.animateFrame); this.particles = []; this._init(); }, createField: function () { let data = this._parseWindJson(); return new CanvasWindField(data); }, animate: function () { let self = this, field = self.windField; let nextLng = null, nextLat = null, uv = null; self.particles.forEach(function (particle) { if (particle.age == null || particle.age <= 0) { self.randomParticle(particle); } if (particle.age > 0) { let x = particle.x, y = particle.y, tlng = particle.tlng, tlat = particle.tlat; let gridpos = self._togrid(tlng,tlat); let tx = gridpos[0]; let ty = gridpos[1]; if (!self.isInExtent(tlng,tlat)) { particle.age = 0; } else { uv = field.getIn(tx, ty); nextLng = tlng + self.calc_speedRate[0] * uv[0]; nextLat = tlat + self.calc_speedRate[1] * uv[1]; particle.lng = tlng; particle.lat = tlat; particle.x = tx; particle.y = ty; particle.tlng = nextLng; particle.tlat = nextLat; particle.age--; } } }); if (self.particles.length <= 0) this.removeLines(); self._drawLines(); }, //粒子是否在地图范围内 isInExtent:function(lng,lat){ let calcExtent = this.initExtent; if((lng>=calcExtent[0] && lng<=calcExtent[1]) && (lat>=calcExtent[2] && lat<=calcExtent[3])) return true; return false; }, _resize:function(width,height){ this.canvasWidth = width; this.canvasHeight = height; }, _parseWindJson: function () { let uComponent = null, vComponent = null, header = null; this.windData.forEach(function (record) { let type = record.header.parameterCategory + "," + record.header.parameterNumber; switch (type) { case "2,2": uComponent = record['data']; header = record['header']; break; case "2,3": vComponent = record['data']; break; default: break; } }); return { header: header, uComponent: uComponent, vComponent: vComponent }; }, removeLines: function () { window.cancelAnimationFrame(this.animateFrame); this.isdistory = true; this.canvas.width = 1; document.getElementById('content').removeChild(this.canvas); }, //根据粒子当前所处的位置(棋盘网格位置),计算经纬度,在根据经纬度返回屏幕坐标 _tomap: function (lng,lat,particle) { let ct3 = Cartesian3.fromDegrees(lng,lat,0); // 判断当前点是否在地球可见端 let isVisible = new EllipsoidalOccluder(Ellipsoid.WGS84, this.viewer.camera.position).isPointVisible(ct3); let pos = SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, ct3); if(!isVisible){ particle.age = 0; } // console.log(pos); return pos?[pos.x,pos.y]:null; }, //根据经纬度,算出棋盘格位置 _togrid: function (lng,lat) { let field = this.windField; let x = (lng-this.initExtent[0])/(this.initExtent[1]-this.initExtent[0])*(field.cols-1); let y = (this.initExtent[3]-lat)/(this.initExtent[3]-this.initExtent[2])*(field.rows-1); return [x,y]; }, _drawLines: function () { let self = this; let particles = this.particles; this.canvasContext.lineWidth = self.lineWidth; //后绘制的图形和前绘制的图形如果发生遮挡的话,只显示后绘制的图形跟前一个绘制的图形重合的前绘制的图形部分,示例:https://www.w3school.com.cn/tiy/t.asp?f=html5_canvas_globalcompop_all this.canvasContext.globalCompositeOperation = "destination-in"; this.canvasContext.fillRect(0,0,this.canvasWidth,this.canvasHeight); this.canvasContext.globalCompositeOperation = "lighter";//重叠部分的颜色会被重新计算 this.canvasContext.globalAlpha = 0.9; this.canvasContext.beginPath(); this.canvasContext.strokeStyle = this.color; particles.forEach(function (particle) { let movetopos = self._tomap(particle.lng, particle.lat,particle); let linetopos = self._tomap(particle.tlng, particle.tlat,particle); // console.log(movetopos,linetopos); if(movetopos!=null && linetopos!=null){ self.canvasContext.moveTo(movetopos[0],movetopos[1]); self.canvasContext.lineTo(linetopos[0],linetopos[1]); } }); this.canvasContext.stroke(); }, //随机数生成器(小数) fRandomByfloat:function(under, over){ return under+Math.random()*(over-under); }, //随机数生成器(整数) fRandomBy:function(under, over){ switch(arguments.length){ case 1: return parseInt(Math.random()*under+1); case 2: return parseInt(Math.random()*(over-under+1) + under); default: return 0; } }, //根据当前风场extent随机生成粒子 randomParticle: function (particle) { let safe = 30,x=-1, y=-1,lng=null,lat=null; let hasextent = this.extent.length!=0; let calc_extent = hasextent?this.extent:this.initExtent; try{ do { try{ if(hasextent){ let pos_x = this.fRandomBy(0,this.canvasWidth); let pos_y = this.fRandomBy(0,this.canvasHeight); let cartesian = this.viewer.camera.pickEllipsoid(new Cartesian2(pos_x, pos_y), this.viewer.scene.globe.ellipsoid); let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian); if(cartographic){ //将弧度转为度的十进制度表示 lng = CMath.toDegrees(cartographic.longitude); lat = CMath.toDegrees(cartographic.latitude); } }else{ lng = this.fRandomByfloat(calc_extent[0],calc_extent[1]); lat = this.fRandomByfloat(calc_extent[2],calc_extent[3]); } }catch(e){ } if(lng){ let gridpos = this._togrid(lng,lat); x = gridpos[0]; y = gridpos[1]; } } while (this.windField.getIn(x, y)[2] <= 0 && safe++ < 30); }catch (e) { } try{ let field = this.windField; let uv = field.getIn(x, y); particle.speed = uv[2]; particle.lng = lng; particle.lat = lat; particle.x = x; particle.y = y; let nextLng = lng + this.calc_speedRate[0] * uv[0]; let nextLat = lat + this.calc_speedRate[1] * uv[1]; particle.tlng = nextLng; particle.tlat = nextLat; particle.age = Math.round(Math.random() * this.maxAge);//每一次生成都不一样 } catch (e) { } return particle; } }; /**** *棋盘类 *根据风场数据生产风场棋盘网格 ****/ let CanvasWindField = function (obj) { this.west = null; this.east = null; this.south = null; this.north = null; this.rows = null; this.cols = null; this.dx = null; this.dy = null; this.unit = null; this.date = null; this.grid = null; this._init(obj); }; CanvasWindField.prototype = { constructor: CanvasWindField, _init: function (obj) { let header = obj.header, uComponent = obj['uComponent'], vComponent = obj['vComponent']; this.west = +header['lo1']; this.east = +header['lo2']; this.south = +header['la2']; this.north = +header['la1']; this.rows = +header['ny']; this.cols = +header['nx']; this.dx = +header['dx']; this.dy = +header['dy']; this.unit = header['parameterUnit']; this.date = header['refTime']; this.grid = []; let k = 0, rows = null, uv = null; for (let j = 0; j < this.rows; j++) { rows = []; for (let i = 0; i < this.cols; i++, k++) { uv = this._calcUV(uComponent[k], vComponent[k]); rows.push(uv); } this.grid.push(rows); } }, _calcUV: function (u, v) { return [+u, +v, Math.sqrt(u * u + v * v)]; }, //二分差值算法计算给定节点的速度 _bilinearInterpolation: function (x, y, g00, g10, g01, g11) { let rx = (1 - x); let ry = (1 - y); let a = rx * ry, b = x * ry, c = rx * y, d = x * y; let u = g00[0] * a + g10[0] * b + g01[0] * c + g11[0] * d; let v = g00[1] * a + g10[1] * b + g01[1] * c + g11[1] * d; return this._calcUV(u, v); }, getIn: function (x, y) { if(x<0 || x>=359 || y>=180){ return [0,0,0]; } let x0 = Math.floor(x), y0 = Math.floor(y), x1, y1; if (x0 === x && y0 === y) return this.grid[y][x]; x1 = x0 + 1; y1 = y0 + 1; let g00 = this.getIn(x0, y0), g10 = this.getIn(x1, y0), g01 = this.getIn(x0, y1), g11 = this.getIn(x1, y1); let result = null; try{ result = this._bilinearInterpolation(x - x0, y - y0, g00, g10, g01, g11); }catch(e){ // console.log(x,y); } return result; }, isInBound: function (x, y) { if ((x >= 0 && x < this.cols-1) && (y >= 0 && y < this.rows-1)) return true; return false; } }; /**** *粒子对象 ****/ let CanvasParticle = function () { this.lng = null;//粒子初始经度 this.lat = null;//粒子初始纬度 this.x = null;//粒子初始x位置(相对于棋盘网格,比如x方向有360个格,x取值就是0-360,这个是初始化时随机生成的) this.y = null;//粒子初始y位置(同上) this.tlng = null;//粒子下一步将要移动的经度,这个需要计算得来 this.tlat = null;//粒子下一步将要移动的y纬度,这个需要计算得来 this.age = null;//粒子生命周期计时器,每次-1 this.speed = null;//粒子移动速度,可以根据速度渲染不同颜色 };
二、风场工具类编写
/*** * 风场通用工具 * date:2022-03-14 * author:zdh * @type {windyUtil} */ import $ from 'jquery' import {CanvasWindy} from "./CanvasWindy"; import {Cartesian2,ScreenSpaceEventType,ScreenSpaceEventHandler} from 'cesium/Cesium' // export let wa={} let windyUtil = (function () { function windyUtil (zdhCesium,layerId) { this.zdhCesium = zdhCesium this.globalExtent = [] this.canvasId = layerId this.postRender = null this.handler = null this.allgrid = null this.windData = null this.windy = null this.windycanvas = null this.WindInformation = { block_show:false, //模块化显示 Wind_speed:0, //风速 wind_direction:"无", //风向 wind_field:[] //差值后的向量 } this.windyVisible = true } windyUtil.prototype.showWindy = function(){ this.windyVisible = true $('#' + this.canvasId).show() this.windy.extent = this.globalExtent; this.windy.redraw(); } windyUtil.prototype.hideWindy = function(){ this.windyVisible = false $('#' + this.canvasId).hide() } windyUtil.prototype.getCesiumExtent = function(){ let canvaswidth = window.innerWidth, canvasheight = window.innerHeight*0.5-50; let left_top_pt = new Cartesian2(0,0) let left_bottom_pt = new Cartesian2(0,canvasheight) let right_top_pt = new Cartesian2(canvaswidth,0) let right_bottom_pt = new Cartesian2(canvaswidth,canvasheight) let pick1= this.zdhCesium.viewer.scene.globe.pick(this.zdhCesium.viewer.camera.getPickRay(left_top_pt), this.zdhCesium.viewer.scene) let pick2= this.zdhCesium.viewer.scene.globe.pick(this.zdhCesium.viewer.camera.getPickRay(left_bottom_pt), this.zdhCesium.viewer.scene) let pick3= this.zdhCesium.viewer.scene.globe.pick(this.zdhCesium.viewer.camera.getPickRay(right_top_pt), this.zdhCesium.viewer.scene) let pick4= this.zdhCesium.viewer.scene.globe.pick(this.zdhCesium.viewer.camera.getPickRay(right_bottom_pt), this.zdhCesium.viewer.scene) if(pick1 && pick2 && pick3 && pick4){ //将三维坐标转成地理坐标---只需计算左下右上的坐标即可 let geoPt1= this.zdhCesium.viewer.scene.globe.ellipsoid.cartesianToCartographic(pick2) let geoPt2= this.zdhCesium.viewer.scene.globe.ellipsoid.cartesianToCartographic(pick3) //地理坐标转换为经纬度坐标 let point1=[geoPt1.longitude / Math.PI * 180,geoPt1.latitude / Math.PI * 180] let point2=[geoPt2.longitude / Math.PI * 180,geoPt2.latitude / Math.PI * 180] // console.log(point1,point2); //此时说明extent需要分为东西半球 if(point1[0]>point2[0]){ this.globalExtent = [point1[0],180,point1[1],point2[1],-180,point2[0],point1[1],point2[1]]; }else{ this.globalExtent = [point1[0],point2[0],point1[1],point2[1]]; } }else{ this.globalExtent = [] } } windyUtil.prototype.resizeCanvas = function(){ if(this.windycanvas==null){ return; } this.windycanvas.width=window.innerWidth; this.windycanvas.height=window.innerHeight; // console.log(windycanvas.width,windycanvas.height); if(this.windy){ this.windy._resize(this.windycanvas.width,this.windycanvas.height); } } windyUtil.prototype.createWindLayer = function (windData) { if (this.windycanvas != null){ return } let _this = this // 开启监听器--无论对当前地球做的任何操作都会监听到 this.postRender = this.zdhCesium.viewer.scene.postRender.addEventListener(() => { _this.getCesiumExtent(); }); this.addWindHandle() if (this.windycanvas == null){ this.windycanvas = document.createElement('canvas'); this.windycanvas.setAttribute("id", this.canvasId); this.windycanvas.style.position='absolute' this.windycanvas.style["pointer-events"]="none"; this.windycanvas.style["z-index"]=10; this.windycanvas.style["top"]=0; this.windycanvas.style["right"]=0; document.getElementById('cesiumContainer1').appendChild(this.windycanvas); } this.resizeCanvas(); window.οnresize=this.resizeCanvas; //风场的参数配置,除了canvas/viewer是必传项,其他可以不传,参数含义见windy.js let params = { viewer:this.zdhCesium.viewer, canvas:this.windycanvas, canvasWidth:window.innerWidth, canvasHeight:window.innerHeight, speedRate:5000, particlesNumber:5000, maxAge:120, frameRate:10, color:'#ffffff', lineWidth:1, }; this.windData = windData this.analysisWindyData(this.windData) this.windy = new CanvasWindy(this.windData, params); } windyUtil.prototype.addWindHandle = function () { let _this = this let refreshTimer = -1; let mouse_down = false; let mouse_move = false; this.handler = new ScreenSpaceEventHandler(this.zdhCesium.viewer.scene.canvas); //鼠标滚动、旋转后是否需要重新生成风场---如果需要,打开以下注释--旋转或者移动到北半球的时候计算会有问题 this.handler.setInputAction(function(e) { if(_this.windyVisible === true){ clearTimeout(refreshTimer); $('#' + _this.canvasId).hide() // _this.hideWindy(); setTimeout(function(){ _this.windy.extent = _this.globalExtent; _this.windy.redraw(); $('#' + _this.canvasId).show() // _this.showWindy(); },200); } },ScreenSpaceEventType.WHEEL); //鼠标左键、右键按下 this.handler.setInputAction(function(e) { mouse_down = true; },ScreenSpaceEventType.LEFT_DOWN); this.handler.setInputAction(function(e) { mouse_down = true; },ScreenSpaceEventType.RIGHT_DOWN); //鼠标移动 this.handler.setInputAction(function(e) { if(_this.windyVisible === true){ if(mouse_down){ $('#' + _this.canvasId).hide() // _this.hideWindy(); mouse_move = true; } } },ScreenSpaceEventType.MOUSE_MOVE); //鼠标左键、右键抬起 this.handler.setInputAction(function(e) { if(_this.windyVisible === true){ if(mouse_down && mouse_move){ _this.windy.extent = _this.globalExtent; _this.windy.redraw(); } $('#' + _this.canvasId).show() // _this.showWindy(); mouse_down = false; mouse_move = false; } },ScreenSpaceEventType.LEFT_UP); this.handler.setInputAction(function(e) { if(_this.windyVisible === true){ if(mouse_down && mouse_move){ _this.windy.extent = _this.globalExtent; _this.windy.redraw(); } $('#' + _this.canvasId).show() // _this.showWindy(); mouse_down = false; mouse_move = false; } },ScreenSpaceEventType.RIGHT_UP); } //根据光标推算风场数据函数 windyUtil.prototype.GetWindInformation = function (x, y, width, height) { let Wind_speed = 0 let wind_direction = "无" let mycolumns = this.WindInformation.wind_field if (mycolumns.length !== 0) { let columns_x = mycolumns.length let columns_y = mycolumns[0].length // console.log(x+","+y+"") let i = Math.floor(x / (width / columns_x)) let j = Math.floor(y / (height / columns_y)) let myfield = mycolumns[i][j] if (myfield.length == 3) { Wind_speed = myfield[2].toFixed(2) } else if (myfield.length == 2) { Wind_speed = Math.sqrt(myfield[0] * myfield[0] + myfield[1] * myfield[1]).toFixed(2) } wind_direction = direction_calculation(myfield[0], myfield[1]) this.WindInformation.Wind_speed = Wind_speed this.WindInformation.wind_direction = wind_direction } else { this.WindInformation.Wind_speed = 0 this.WindInformation.wind_direction = "无" } function direction_calculation(u, v) { let fx = 0 // let v = v2 * (-1) let text = "无" if (u == 0) { if (v > 0) { text = "南风" } else if (v < 0) { text = "北风" } } else if (v == 0) { if (u > 0) { text = "西风" } else if (u < 0) { text = "东风" } } else { if (u > 0 & v > 0) {//第一象限 // fx = Math.atan(v / u) * 180 / Math.PI fx = 270 - Math.atan(v / u) * 180 / Math.PI if (fx <= 191.25) { text = "南风" } else if (fx > 191.25 && fx < 258.76) { text = "西南风" } else { text = "西风" } // if (fx <= 11.25) { // text = "南风" // } else if (fx > 11.25 && fx < 78.76) { // text = "西南风" // } else { // text = "西风" // } } else if (u > 0 & v < 0) {//第二象限 // fx = 180 + Math.atan(v / u) * 180 / Math.PI fx = 270 - Math.atan(v / u) * 180 / Math.PI if (fx <= 281.25) { text = "西风" } else if (fx > 281.25 && fx < 348.76) { text = "西北风" } else { text = "北风" } // if (fx <= 101.25) { // text = "西风" // } else if (fx > 101.25 && fx < 168.76) { // text = "西北风" // } else { // text = "北风" // } } else if (u < 0 & v < 0) {//第三象限 // fx = 180 + Math.atan(v / u) * 180 / Math.PI fx = 90 - Math.atan(v / u) * 180 / Math.PI if (fx <= 11.25) { text = "北风" } else if (fx > 11.25 && fx < 78.76) { text = "东北风" } else { text = "东风" } // if (fx <= 191.25) { // text = "东风" // } else if (fx > 191.25 && fx < 258.76) { // text = "东北风" // } else { // text = "北风" // } } else if (u < 0 & v > 0) {//第四象限 // fx = 360 + Math.atan(v / u) * 180 / Math.PI fx = 90 - Math.atan(v / u) * 180 / Math.PI if (fx <= 101.25) { text = "东风" } else if (fx > 101.25 && fx < 168.76) { text = "东南风" } else { text = "南风" } } } return text } } windyUtil.prototype.analysisWindyData = function(windydata) { this.allgrid = [] let p = 0 let east, north if (windydata[0].header.parameterNumberName == "eastward_wind") { east = windydata[0] north = windydata[1] } else { east = windydata[1] north = windydata[0] } for (let j = 0; j < north.header.ny; j++) { let row = [] for (let i = 0; i < north.header.nx; i++, p++) { row[i] = [east.data[p], north.data[p]] } this.allgrid[j] = row } } windyUtil.prototype.getWindyDetail = function(coord) { let lng = coord[0] let lat = coord[1] // 与格网序列的数据转换 // if (lng >= 0) { // lng = Math.floor(lng) // } else { // lng = 360 + Math.floor(lng) // } // lat = 90 - Math.floor(lat) // 获取对应的格网序列(此示例为中国区域0.25度规格) let xlength = Math.floor((coord[0]-70) / 0.25) let ylength = Math.floor((55-coord[1]) / 0.25) let xdata, ydata xdata = parseFloat(this.allgrid[Math.abs(ylength)][Math.abs(xlength)][0]) ydata = parseFloat(this.allgrid[Math.abs(ylength)][Math.abs(xlength)][1]) debugger let feng=this.direction_calculation(xdata,ydata) if (typeof xdata != "number" || typeof ydata != "number") { console.error("暂无该区域风向数据!") return } let v = Math.sqrt(Math.pow(xdata, 2) + Math.pow(ydata, 2)) let angle = this.getWindyAngle(xdata, ydata) let result = { "direction": feng, "level": this.getWindyLevel(v), "speed": v.toFixed(2) } return result } windyUtil.prototype.direction_calculation = function (u, v) { let fx = 0 // let v = v2 * (-1) let text = "无" if (u == 0) { if (v > 0) { text = "南风" } else if (v < 0) { text = "北风" } } else if (v == 0) { if (u > 0) { text = "西风" } else if (u < 0) { text = "东风" } } else { if (u > 0 & v > 0) {//第一象限 // fx = Math.atan(v / u) * 180 / Math.PI fx = 270 - Math.atan(v / u) * 180 / Math.PI if (fx <= 191.25) { text = "南风" } else if (fx > 191.25 && fx < 258.76) { text = "西南风" } else { text = "西风" } // if (fx <= 11.25) { // text = "南风" // } else if (fx > 11.25 && fx < 78.76) { // text = "西南风" // } else { // text = "西风" // } } else if (u > 0 & v < 0) {//第二象限 // fx = 180 + Math.atan(v / u) * 180 / Math.PI fx = 270 - Math.atan(v / u) * 180 / Math.PI if (fx <= 281.25) { text = "西风" } else if (fx > 281.25 && fx < 348.76) { text = "西北风" } else { text = "北风" } // if (fx <= 101.25) { // text = "西风" // } else if (fx > 101.25 && fx < 168.76) { // text = "西北风" // } else { // text = "北风" // } } else if (u < 0 & v < 0) {//第三象限 // fx = 180 + Math.atan(v / u) * 180 / Math.PI fx = 90 - Math.atan(v / u) * 180 / Math.PI if (fx <= 11.25) { text = "北风" } else if (fx > 11.25 && fx < 78.76) { text = "东北风" } else { text = "东风" } // if (fx <= 191.25) { // text = "东风" // } else if (fx > 191.25 && fx < 258.76) { // text = "东北风" // } else { // text = "北风" // } } else if (u < 0 & v > 0) {//第四象限 // fx = 360 + Math.atan(v / u) * 180 / Math.PI fx = 90 - Math.atan(v / u) * 180 / Math.PI if (fx <= 101.25) { text = "东风" } else if (fx > 101.25 && fx < 168.76) { text = "东南风" } else { text = "南风" } } } return text } windyUtil.prototype.getWindyDirection = function(angle) { if ((angle >= 0 && angle <= 22.5) || (angle <= 360 && angle > 337.5)) { return "东风" } if (angle <= 337.5 && angle > 292.5) { return "西北风" } if (angle <= 292.5 && angle > 247.5) { return "北风" } if (angle <= 247.5 && angle > 202.5) { return "西南风" } if (angle <= 202.5 && angle > 157.5) { return "东风" } if (angle <= 157.5 && angle > 112.5) { return "东南风" } if (angle <= 112.5 && angle > 67.5) { return "南风" } if (angle <= 67.5 && angle > 22.5) { return "西南风" } } windyUtil.prototype.getWindyAngle = function(u, v) { let fx = 0 if (u > 0 & v > 0) { fx = 90 - Math.atan(v / u) * 180 / Math.PI } else if (u < 0 & v > 0) { fx = 90 - Math.atan(v / u) * 180 / Math.PI } else if (u < 0 & v < 0) { fx = 270 - Math.atan(v / u) * 180 / Math.PI } else if (u > 0 & v < 0) { fx = 270 - Math.atan(v / u) * 180 / Math.PI } else if (u == 0 & v > 0) { fx = 180 } else if (u == 0 & v < 0) { fx = 0 } else if (u > 0 & v == 0) { fx = 270 } else if (u < 0 & v == 0) { fx = 90 } else if (u == 0 & v == 0) { fx = 999.9 } return fx } windyUtil.prototype.getWindyLevel = function(v) { if (v < 0.3) { return 0 } if (v >= 0.3 && v < 1.6) { return 1 } if (v >= 1.6 && v < 3.4) { return 2 } if (v >= 3.4 && v < 5.5) { return 3 } if (v >= 5.5 && v < 8.0) { return 4 } if (v >= 8.0 && v < 10.8) { return 5 } if (v >= 10.8 && v < 13.9) { return 6 } if (v >= 13.9 && v < 17.2) { return 7 } if (v >= 17.2 && v < 20.8) { return 8 } if (v >= 20.8 && v < 24.5) { return 9 } if (v >= 24.5 && v < 28.5) { return 10 } if (v >= 28.5 && v < 32.7) { return 11 } if (v >= 32.7 && v < 37.0) { return 12 } if (v >= 37.0 && v < 41.5) { return 13 } if (v >= 41.5 && v < 46.2) { return 14 } if (v >= 46.2 && v < 51.0) { return 15 } if (v >= 51.0 && v < 56.1) { return 16 } if (v >= 56.1 && v < 61.2) { return 17 } if (v >= 61.2) { return 18 } } return windyUtil }()) export {windyUtil}
三、调用代码编写
let windyUtil1 = new windyUtil(zdhCesium,layerId) windyUtil1.createWindLayer(res) if(layersInfo[layerId].options.isShow == false){ windyUtil1.hideWindy() } layersInfo[layerId].entities.push(windyUtil1)
四、成果展示
如果对您有帮助
技术合作交流qq:2401315930