openlayers 绘制台风风圈(准确版)

闲言: 这个问题的一开始是最近几天的那个啥子台风有登陆湛江,然后我负责的项目刚好处在上线边缘(就是能用跟不能用之间反复跳跃),风圈的实现一开始是跟着LZUGIS 大佬 的 思路写的,当然,我也不知道为啥这么写就行。然后我也发现了一个问题就是说,首先就是绘制的圆弧位置不对,第二个是准确度不够,不过这么一琢磨,人家也说了简单的实现算法,有点问题也属实正常。直到我搜索台风路径,发现嗯,我艹,好精准,秉着好奇的心F12,是用SVG写的,框架用的也不是ol。。。emmm,网上又没有相关的现成的,然后不BB ,现在看到自己这些牢骚有点害臊 -----2021年11月18日)

这篇文章的产出有https://blog.csdn.net/qq947522963/article/details/50773705 作者 xuym-_-的一大份功劳,从这篇文章 了解了一些地图基础。才想到如何渲染到地图上的思路。当然,曲折是有的,断断续续也磨了我3天左右,还好应该算顺利完成了。

前言: 思路主要是通过canvas绘图,然后根据风圈影响的实地距离计算屏幕距离渲染到地图上。

思路介绍

台风风圈 传入 4个方向的影响距离,呈圆弧状, 实际上 就是 4段 以 台风点为中心,半径不同的4个圆弧进行填充。

canvas 部分

let count = 1;
for (let i in configs) {
              // 每次 加 0.5  绘制圆弧
              let ratio = 0.5 * count * Math.PI;
              let distance = configs[i] / state.resolution;
              ctx.arc(x, y, distance, ratio - 0.5 * Math.PI, ratio);
              // 如果绘制到 第二个圆弧了 绘制线段 连接 这两个圆弧
              count++;
            }
            ctx.fillStyle = "rgb(238, 160, 29)";
            ctx.fill();
            ctx.closePath();

将该canvas配合渲染到ol地图上面

这里的逻辑是: 传入点的数据(其实我们只要经纬度),将circle的style中的渲染方法改写,canvas不设置第五个参数 默认逆时针,所以我们把SouthEast东南,这样子的进行命名同时将km转为m,在renderer函数里,调用当前渲染所用的canvas的上下文,将canvas逻辑贴上去。 返回这个feature,加入source中进行渲染。 没有进行封装,如果你需要,直接COPY 传进去 数据 就可以运行,返回一个feature。

/**
     * return feature
     */
    drawSolarExact: function (points) {
      let position = fromLonLat([points.lng, points.lat]);
      let feature = new Feature({
        geometry: new Circle(position),
      });
      // 处理四个方向的数据
      let radiusArr = points.radius7.split("|").map((item) => {
        return parseFloat(item);
      });
      // 全部除以100 右下角开始
      let configs = {
        SE: radiusArr[0] * 1000,
        SW: radiusArr[1] * 1000,
        NW: radiusArr[2] * 1000,
        NE: radiusArr[3] * 1000,
      };
      //       实地距离:  R * P
      // 图上距离:  (P / 72) / 39.3701 = P / (72*39.3701)
      // 比例尺:  S =  P / (72*39.3701)  / R*P   = 1 /  R*72*32.3701
      // 假设屏幕距离为P,分辨率为R,则比例尺S为:
      let count = 1;
      console.log(this.map.getView().getResolution());
      feature.setStyle(
        new Style({
          renderer(coordinates, state) {
            const ctx = state.context;
            let [x, y] = coordinates[0];
            ctx.beginPath();

            for (let i in configs) {
              // 每次 加 0.5  绘制圆弧
              let ratio = 0.5 * count * Math.PI;
              let distance = configs[i] / state.resolution;
              ctx.arc(x, y, distance, ratio - 0.5 * Math.PI, ratio);
              // 如果绘制到 第二个圆弧了 绘制线段 连接 这两个圆弧
              count++;
            }
            ctx.fillStyle = "rgb(238, 160, 29)";
            ctx.fill();
            ctx.closePath();

            count = 1;
          },
        })
      );
      return feature;
    },

测试效果

在这里插入图片描述
这是风圈的值.
在这里插入图片描述
这个线获取的长度是根据官方的文档说明的API 获取的,应该是准确的,除非我的理解出错,嗯,,对于我人为造成的误差就不要计较了。 至于相关的颜色啊,border啊,层级,这个 就自己根据自己的需求去添加修改把,

formatLength: function (line) {
      const length = line.getLength();
      let output;
      if (length > 100) {
        output = Math.round((length / 1000) * 100) / 100 + " " + "km";
      } else {
        output = Math.round(length * 100) / 100 + " " + "m";
      }
      return output;
    },

在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,无法确定具体的问题原因。但是,以下是一些可能导致OpenLayers台风风圈不显示的原因和解决方法: 1. 检查代码中是否正确引用了OpenLayers库文件。如果没有正确引用,可能会导致OpenLayers无法正常工作。 2. 检查代码中是否正确设置了地图的中心点和缩放级别。如果地图的中心点和缩放级别设置不正确,可能会导致台风风圈不显示。 3. 检查代码中是否正确设置了台风风圈的参数。如果参数设置不正确,可能会导致台风风圈不显示。 4. 检查代码中是否正确设置了台风风圈的样式。如果样式设置不正确,可能会导致台风风圈不显示。 以下是一个使用OpenLayers绘制台风风圈的示例代码,供参考: ```javascript // 创建地图 var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.fromLonLat([120.5, 30.0]), zoom: 8 }) }); // 绘制台风风圈 var center = ol.proj.fromLonLat([120.5, 30.0]); var radius = 100000; // 单位:米 var circle = new ol.geom.Circle(center, radius); var feature = new ol.Feature(circle); var vectorSource = new ol.source.Vector({ features: [feature] }); var vectorLayer = new ol.layer.Vector({ source: vectorSource, style: new ol.style.Style({ stroke: new ol.style.Stroke({ color: 'red', width: 2 }), fill: new ol.style.Fill({ color: 'rgba(255, 0, 0, 0.1)' }) }) }); map.addLayer(vectorLayer); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值