vue3在高德地图中制作气象扇形雷达图

97 篇文章 2 订阅
88 篇文章 0 订阅

在这里插入图片描述
这是效果图,每隔22.5°就会有一个扇形区域,有三层区域,第一层是距离圆点5km,第二层是10km,第三层是50km。

第一步:高德地图中绘画圆

在这里插入图片描述

      // 构造矢量圆形
      let circle = new AMap.Circle({
        center: position.value, // 圆心位置
        radius: 5000, //半径
        strokeColor: "#94D8F6", //线颜色
        strokeOpacity: 1, //线透明度
        strokeWeight: 1, //线粗细度
        fillColor: "", //填充颜色
        fillOpacity: 0.35, //填充透明度
      });
      let circle01 = new AMap.Circle({
        center: position.value, // 圆心位置
        radius: 10000, //半径
        strokeColor: "#94D8F6", //线颜色
        strokeOpacity: 1, //线透明度
        strokeWeight: 1, //线粗细度
        fillColor: "", //填充颜色
        fillOpacity: 0.35, //填充透明度
      });
      let circle02 = new AMap.Circle({
        center: position.value, // 圆心位置
        radius: 50000, //半径
        strokeColor: "#94D8F6", //线颜色
        strokeOpacity: 1, //线透明度
        strokeWeight: 1, //线粗细度
        fillColor: "", //填充颜色
        fillOpacity: 0.35, //填充透明度
      });
      map.add(circle); // 增加圆圈
      map.add(circle01); // 增加圆圈
      map.add(circle02); // 增加圆圈

第二步:绘制圆点到50km圆的分割线

在这里插入图片描述
就是每隔22.5°增加一条线

思路就是,要得知距离圆点50km某个方位的新点位。我写了一个方法。

  // 已知某个点位,在相同经度下,计算沿纬度方向移动n米,然后旋转N度,获得的新点位:
  calculateNewPoint(lat: number, lng: number, distance: number, angle: number) {
    // lat 起始点纬度  lng起始点经度  distance 两点距离 angle  角度,顺时针为正,逆时针为负
    const R = 6378137; // 地球半径,单位为米
    const dRad = distance / R; // 距离转换为弧度
    const angleRad = angle * Math.PI / 180; // 角度转换为弧度
  
    const newLat = Math.asin(
      Math.sin(lat * Math.PI / 180) * Math.cos(dRad) +
      Math.cos(lat * Math.PI / 180) * Math.sin(dRad) * Math.cos(angleRad)
    ) * 180 / Math.PI;
  
    const newLng = lng + Math.atan2(
      Math.sin(angleRad) * Math.sin(dRad) * Math.cos(lat * Math.PI / 180),
      Math.cos(dRad) - Math.sin(lat * Math.PI / 180) * Math.sin(newLat * Math.PI / 180)
    ) * 180 / Math.PI;
  
    return { lat: newLat, lng: newLng };// return 新点位的经纬度
  }

在这里插入图片描述

然后获取获取点位

  for (let i = 1; i <= 31; i = i + 2) {
    obj.push($tool.calculateNewPoint(position.value[1], position.value[0], n, 11.25 * i));// 获取最外圈的点位,因为第一条线,距离我的纬度是11.25,所以以此循环过后,就得到一周18个点

  }

然后开始画线,将所有的50km获取的新点位,都和圆点进行连线

      for (let index = 0; index < sectorPoints.value.length; index++) {
        let line = new AMap.Polyline({
          path: [
            position.value,
            [sectorPoints.value[index].lng, sectorPoints.value[index].lat],
          ],
          isOutline: true,
          outlineColor: index % 2 == 0 ? "#ff0056" : "#FFF766",
          borderWeight: 0,
          strokeColor: index % 2 == 0 ? "#ff0056" : "#FFF766",
          strokeOpacity: 1,
          strokeWeight: 1,
          // 折线样式还支持 'dashed'
          strokeStyle: "solid",
          // strokeStyle是dashed时有效
          // strokeDasharray: [15, 5],
          lineJoin: "round",
          lineCap: "round",
          zIndex: 150,
        });
        pathline.push(line);
      }
map.add(pathline);// 增加线段

然后我们就得到了这样的图案
在这里插入图片描述

第三步:寻找5km、10km、50的点,用来后期去分割区域

因为高德没有扇形的绘画功能,所以只能在扇形的两个点之间寻找很多个点,用来分割扇形,然后再画多边形
在这里插入图片描述
找点的代码

let setSector = (n: number, obj: any[]) => {
  // 绘制扇形线条
  // position.value 中心点
  for (let i = 1; i <= 31; i = i + 2) {
    obj.push($tool.calculateNewPoint(position.value[1], position.value[0], n, 11.25 * i));
    let _path = [];
    for (let j = 11.25 * (i - 2); j <= 11.25 * i; j = j + 0.5) {
      let _one = $tool.calculateNewPoint(position.value[1], position.value[0], n, j);
      _path.push([_one.lng, _one.lat]);
      // [sectorPoints.value[index].lng, sectorPoints.value[index].lat]
    }

    if (n == 5000) {
      // _path.push(position.value);
      sector5kmLine.value.push({
        path: _path,
      });
    } else if (n == 10000) {
      sector10kmLine.value.push({
        path: _path,
      });
    } else if (n == 50000) {
      sector50kmLine.value.push({
        path: _path,
      });
    }
  }
};
setSector(50000, sectorPoints.value);// 存点
setSector(5000, sectorPoints5km.value);
setSector(10000, sectorPoints10km.value);

然后存储多边形的数据,都存到sectorArea中

for (let i = 0; i < sector5kmLine.value.length; i++) {
  let _path01: any[] = [];
  let _path02: any[] = [];
  let _path03: any[] = [];
  _path01 = JSON.parse(JSON.stringify(sector5kmLine.value[i].path));
  _path01.push(position.value);

  _path02 = JSON.parse(
    JSON.stringify(
      sector5kmLine.value[i].path.concat(
        JSON.parse(JSON.stringify(sector10kmLine.value[i].path)).reverse()
      )
    )
  );

  _path03 = JSON.parse(
    JSON.stringify(
      sector50kmLine.value[i].path.concat(
        JSON.parse(JSON.stringify(sector10kmLine.value[i].path)).reverse()
      )
    )
  );
  sectorArea.value.push({
    // 5km 扇形区域
    id: "5km" + i,// 预留每个区域id
    status: 0, // 0 正常 1 撤离 2  隐蔽 3避迁 4 禁用食物
    show: false,
    path: _path01,
    fillcolor: "#ee91fc",
    polygon: "", // 多边形
  });
  sectorArea.value.push({
    // 5km~10km 扇形区域
    id: "5km10km" + i,// 预留每个区域id
    status: 0, // 0 正常 1 撤离 2  隐蔽 3避迁 4 禁用食物
    show: false,
    path: _path02,
    fillcolor: "#179188",
    polygon: "", // 多边形
  });
  sectorArea.value.push({
    // 50km~10km 扇形区域
    id: "10km50km" + i,// 预留每个区域id
    status: 0, // 0 正常 1 撤离 2  隐蔽 3避迁 4 禁用食物
    show: false,
    path: _path03,
    fillcolor: "#17fffc",
    polygon: "", // 多边形
  });
}

正式画多边形

      sectorArea.value.forEach((item: { path: any; fillcolor: any;id:string }) => {
        let _polygon = new AMap.Polygon({
          path: item.path,
          strokeColor: "green",
          strokeWeight: 6,
          strokeOpacity: 0.2,
          fillOpacity: 0.4,
          fillColor: item.fillcolor,
          zIndex: 150,
          bubble: true,
          extData:{
            id:item.id// 区域标记
          }
        });
        _polygon.on("mouseover", () => {
          _polygon.setOptions({
            //修改多边形属性的方法
            fillColor: "#F47378",
          });
        });
        _polygon.on("mouseout", () => {
          _polygon.setOptions({
            //修改多边形属性的方法
            fillColor: item.fillcolor,
          });
        });
        polygons.value.push(_polygon);
      });

将画的多边形添加进地图中

map.add(polygons.value);

最终效果就是这样
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

第7个前端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值