• 风场可视化学习笔记:openlayers


    最近在弄地图控件方面的东西,这里分享一个我找到的一个添加风场的教程和demo,需要对大家有所帮助(以下为转载内容)载于https://blog.csdn.net/u010065726/article/details/106338194/

    windLayer api使用示例

    这里主要为windlayer关于在openlayers3-4版本内使用的相关接口及参数说明

    在加载时,主要读取的数据来源格式为json,而我们一般获取到的数据主要为netCDF或Grib等格式的数据,这里还涉及相关的数据转换操作

    1.openlayers-wind 参数说明

    TIP

    对应于 openlayers 3-4 相关参数

    图层参数

    其他参数遵循 ol 基础图层参数。

    windOptions

    colorScale

    关于颜色配置,在以往的配置中传入的是颜色数组会根据以下函数和格点数据的数据范围去计算匹配的颜色值,

    const indexFor = function (m) {  // map velocity speed to a style
        return Math.max(0, Math.min((that.COLOR_SCALE.length - 1),
          Math.round((m - min) / (max - min) * (that.COLOR_SCALE.length - 1))));
        
    }

    这样实现只能按照风速值范围等间隔渲染,无法做到精确匹配对应值的颜色。

    在最新的版本中新增了此参数的类型,可以通过回调函数精确对应颜色值(但是会有一定的性能损失)

    颜色配置支持三种方式:

    String:固定颜色值

    Function: 通过回调函数的风速值设定颜色(但是会有一定的性能损失)

    String[]: 按照风速值范围等间隔渲染,无法做到精确匹配对应值的颜色。

    2.数据来源
    风场数据来源主要为气象的数据文件,可以详见另一篇文章 windy网站数据分析 。文章中提到的windy基本涵盖了大部分的气象数据来源,大家可以参考一下。

    在使用wind-layer需要了解相关的数据转换,大家可以多下下功夫,有什么内容也可以分享出来,大家互相学习下。

    3.图层初始化并格网分析数据源
    调用相关的API接口,添加相应的图层对象

    demo代码如下:

    <!DOCTYPE html>
    <html>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>
        风向demo
    </title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dat.gui@0.7.6/build/dat.gui.css">
    <script src="https://cdn.jsdelivr.net/npm/openlayers/dist/ol.js">
    </script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/openlayers/dist/ol.css">
    <script src="https://cdn.jsdelivr.net/npm/openlayers-wind/dist/ol-wind.js">
    </script>
    <style type="text/css">
        html, body { margin: 0; height: 100%;  100% }
        .container {  100%; height: 100% }
    </style>
    <body>
    <div id="map" class="container">
    </div>
    <script>
      const map = new ol.Map({
        target: 'map',
        view: new ol.View({
          center: [113.53450137499999, 34.44104525],
          // center: ol.proj.fromLonLat([113.53450137499999, 34.44104525]),
          zoom: 5,
          projection: 'EPSG:4326',
        }),
        layers: [new ol.layer.Tile({
          source: new ol.source.OSM({
            url: 'https://{a-d}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
          })
        })],
      });
    
      let layer;
    
      // https://sakitam-fdd.github.io/wind-layer/data/wind.json
      fetch('https://sakitam-fdd.github.io/wind-layer/data/wind.json').then(res => res.json()).then(res =>{
        const windLayer = new OlWind.WindLayer(res, {
          windOptions: {
            colorScale: ["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)"],
            velocityScale: 1 / 100,
            paths: 1000,
          },
          map: map,
        });
    
        analysisWindyData(res);
        console.log(map, windLayer);
    
        layer = windLayer;
    
        // layer.appendTo(map);
        map.addLayer(windLayer);
        map.on('singleclick', e =>{
          var details = getWindyDetail(e.coordinate);
          console.log(details);
          alert(' 风向:' + details.direction + '
     风级:' + details.level + '
     风速:' + details.speed);
        });
      });
    
      var allgrid = [];
      function analysisWindyData(windydata) {
        var p = 0;0.
        var east, north;
        if (windydata[0].header.parameterNumberName == "eastward_wind") {
          east = windydata[0];
          north = windydata[1];
        } else {
          east = windydata[1];
          north = windydata[0];
        }
        for (var j = 0; j < north.header.ny; j++) {
          var row = [];
          for (var i = 0; i < north.header.nx; i++, p++) {
            row[i] = [east.data[p], north.data[p]];
          }
          allgrid[j] = row;
        }
      }
      function getWindyDetail(coord) {
        var lng = coord[0];
        var lat = coord[1];
        // 与格网序列的数据转换
        if (lng >= 0) {
          lng = Math.floor(lng);
        } else {
          lng = 360 + Math.floor(lng)
        }
        lat = 90 - Math.floor(lat);
        // 获取对应的格网序列
        var xlength = lng;
        var ylength = lat;
        var xdata, ydata;
        xdata = allgrid[Math.abs(ylength)][Math.abs(xlength)][0];
        ydata = allgrid[Math.abs(ylength)][Math.abs(xlength)][1];
        console.log(xdata);
        console.log(ydata);
        if (typeof xdata != "number" || typeof ydata != "number") {
          console.error("暂无该区域风向数据!");
          return;
        }
        var v = Math.sqrt(Math.pow(xdata, 2) + Math.pow(ydata, 2));
        var angle = getWindyAngle(xdata, ydata);
        var result = {
          "direction": getWindyDirection(angle),
          "level": getWindyLevel(v),
          "speed": v.toFixed(2)
        };
        return result;
      }
    
      function getWindyDirection(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 "东北风";
        }
      }
    
      function getWindyAngle(u, v) {
        var fx = 0;
        if (u > 0 & v > 0) {
          fx = 270 - 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 = 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 = 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;
      }
    
      function getWindyLevel(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;
        }
    
      }
    </script>
    </body>

    如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

     

  • 相关阅读:
    POI导出word文档里的符号,亲测有效
    java使用POI导出word文档,包含图片,表格,文本
    linux下关闭tomcat8009端口
    导入包报错The import org.springframework cannot be resolved
    create connection error, url: jdbc:mysql://**ip**:3306/*?errorCode 1045, state 28000
    云服务器是怎么做到安装多个系统的?
    java基础概念整理综合 及补充(jdk1.8)
    oracle数据库,表被锁,如何解锁?
    Java框架:spring框架整合hibernate框架的xml配置(使用注解的方式)
    form表单多文件上传
  • 原文地址:https://www.cnblogs.com/smileZAZ/p/15529528.html
Copyright © 2020-2023  润新知