在这里插入图片描述
实现台风效果

 <img id="tfImg" src="../../public/editor-0.8s-47px.gif" />
    <!-- 台风hover信息 -->
    <div id="tfHoverInfo">
      <!-- {{tf2HoverInfo}} -->
      <div>强度:{{ tf2HoverInfo.vti }}</div>
      <div>东经:{{ tf2HoverInfo.clongitude }}</div>
      <div>北纬:{{ tf2HoverInfo.clatitude }}</div>

      <div>风力:{{ tf2HoverInfo.foreWd }}</div>
      <div>风速:{{ tf2HoverInfo.foreWs }}</div>
      <div>移动速度:{{ tf2HoverInfo.cws }}</div>
    </div>
    <!-- 台风过警戒线提示 -->
    <div id="tf2AlterInfo">
      {{ tf2AlterInfo }}
    </div>
    <div class="ol-legend" title="图例" @click="showLenged"></div>
    <transition name="lenged-fade">
      <div class="legend-container" v-show="lengedFlag">
        <img :src="this.tlpng" />
      </div>
    </transition>
#tfImg {
  position: absolute;
  top: -100px;
  left: -100px;
  z-index: 999999;
}
#tf2AlterInfo {
  display: none;
  position: absolute;
  width: 120px;
  height: 60px;
  line-height: 60px;
  padding: 10px;
  text-align: center;
  border-radius: 8px;
  border: 1px solid gray;
  color: red;
  background-color: yellow;
  font-size: 18px;
  font-weight: bold;
}
#tfHoverInfo {
  position: absolute;
  z-index: 9999999;
  border-radius: 6px;
  background-color: whitesmoke;

  padding: 15px;
  display: none;
  overflow: auto;
}
.ol-legend {
  position: absolute;
  bottom: 10px;
  right: 280px;
  z-index: 99999;
  height: 22px;
  width: 23px;
  background-image: url("../../public/images/tl.png");
  background-repeat: no-repeat;
  background-size: 100% 100%;
  cursor: pointer;
}
.legend-container {
  position: absolute;
  bottom: 40px;
  right: 320px;
}
data(){
return {
      //台风
      alertLine24Turf: null,
      alertLine48Turf: null,

      //警戒线图层
      warningLineLayer: null,
      //绘制台风图层和source
      tf2VecLayer: null,
      tf2VecSource: null,
      tf2HoverFlag: 0,
      tf2HoverInfo: {
        vti: "1",
        clatitude: "2",
        clongitude: "3",
        cws: "4",
        cpress: "5",
        // pressure: "6",
        // movespeed: "7"
      },
      oldTf2Feature: null,
      tf2AlterInfo: "",
      lengedFlag: false, //图例
      }
}
mounted****
 //初始化绘制台风相关变量
    this.tf2VecSource = new VectorSource();
    this.tf2VecLayer = new VectorLayer({
      source: this.tf2VecSource,
    });
    this.map.addLayer(this.tf2VecLayer);
    console.log("台风矢量添加完成");

    //地图鼠标事件****
    this.map.on("pointermove", (ev) => {
      //台风事件
      // this.tf2HoverFlag = 100;
      if (this.tf2HoverFlag == 1) {
        let pixel = ev.pixel;
        let feature = this.map.forEachFeatureAtPixel(pixel, function (feature) {
          return feature;
        });
        console.log(feature, "台风");
        if (feature != undefined && feature.values_._self) {
          this.oldTf2Feature = feature;
          // console.log(feature.getStyle(), '台风');
          // console.log(this.tfHoverInfo,"??");
          this.tf2HoverInfo.vti = feature.values_._self.vti;
          this.tf2HoverInfo.clongitude = feature.values_._self.clongitude;
          this.tf2HoverInfo.clatitude = feature.values_._self.clatitude;
          this.tf2HoverInfo.cws = feature.values_._self.cws;
          let dom = document.querySelector("#tfHoverInfo");
          let pixel = this.lonlat2pixel({
            lon: parseFloat(feature.values_._self.clongitude),
            lat: parseFloat(feature.values_._self.clatitude),
          });
          dom.style.display = "block";
          dom.style.top = pixel[1] - 200 + "px";
          dom.style.left = pixel[0] - 110 + "px";
          let style = feature.getStyle();

          //接下来圈变大
          feature.setStyle(
            new Style({
              image: new CircleStyle({
                fill: new Fill({
                  color: style.image_.fill_.color_, //'#ff0000',
                }),
                radius: 12,
              }),
            })
          );
        } else {
          document.querySelector("#tfHoverInfo").style.display = "none";
          if (this.oldTf2Feature) {
            //恢复
            let style = this.oldTf2Feature.getStyle();
            this.oldTf2Feature.setStyle(
              new Style({
                image: new CircleStyle({
                  fill: new Fill({
                    color: style.image_.fill_.color_, //'#ff0000',
                  }),
                  radius: 4,
                }),
              })
            );
          }
        }
      }
    });
    this.map.setView(
      new View({
        center: fromLonLat([130, 15]),
        zoom: 5,
      })
    );
methods***
 //台风大圈画法
    generalCurveFeature(olon, olat, r, startAng, endAng, interval) {
      let mianArr = [];
      for (let i = startAng; i < endAng; ) {
        i += interval;
        let clon = r * Math.sin((i * Math.PI) / 180);
        let clat = r * Math.cos((i * Math.PI) / 180);
        let ec = 6356755.0 + ((6378136.49 - 6356755.0) * (90 - olat)) / 90;
        let ed = ec * Math.cos((olat * Math.PI) / 180);
        let jlon = ((clon / ed + (olon * Math.PI) / 180) * 180) / Math.PI;
        let jlat = ((clat / ec + (olat * Math.PI) / 180) * 180) / Math.PI;
        let a11 = fromLonLat([jlon, jlat]);
        mianArr.push(a11);
      }
      mianArr.push(fromLonLat([olon, olat]));
      let featuremian = new Feature({
        geometry: new Polygon([mianArr]),
      });
      return featuremian;
    },

    //经纬度坐标转屏幕坐标
    lonlat2pixel(opt) {
      console.log(opt, "数据数据");
      let pmzb = this.map.getPixelFromCoordinate(
        fromLonLat([opt.lon, opt.lat])
      );

      return pmzb;
    },
    // 根据 约定的 类型的索引 判别 底图 与 注记图 需要渲染的layer类型
    JudgeBaseAndNoteByType(index) {
      let map = [
        ["vec", "cva"],
        ["ter", "cta"],
        ["img", "cia"],
      ];

      return map[index];
    },
    /*创建标注样式
     *@param{object}  feature  标注要素
     *@return {object} 返回创建的标注样式对象
     */
    createLabelStyle(feature) {
      //返回一个样式
      return new Style({
        //文本样式
        text: new Text({
          textAlign: "center", //对齐方式
          textBaseline: "middle", //文本基线
          font: "normal 18px 微软雅黑", //字体样式
          text: feature.get("name"), //文本内容
          offsetY: 15, // Y轴偏置
          fill: new Fill({
            //填充样式
            color: "#ffffff",
          }),
          backgroundFill: new Fill({
            // 填充背景
            color: [0, 0, 0, 0.6],
          }),
          padding: [2, 5, 2, 5],
        }),
        // 设置层级
        zIndex: 199,
      });
    },
     //台风绘制2*****
    compassesTf() {
      this.tf2HoverFlag = 1;
      // console.log(this.typeFun);
      const dataNum = this.typeFun;   //模拟json
 
      let pointsArr = dataNum;
      let featureArr = [];
      let lonlatArr = [];
      let lonlatArr1 = [];
    
      for (let i = 0; i < pointsArr.length; i++) {
       
        let ponsition = [pointsArr[i].clongitude, pointsArr[i].clatitude];
        lonlatArr.push(
          fromLonLat([pointsArr[i].clongitude, pointsArr[i].clatitude])
        );
        lonlatArr1.push([pointsArr[i].clongitude, pointsArr[i].clatitude]);
   
        //创建feature
        let featurepoint = new Feature({
          geometry: new Point(fromLonLat(ponsition)),
          _self: pointsArr[i],
        });
        //设置feature的样式
      

        featurepoint.setStyle(
          new Style({
            image: new CircleStyle({
              fill: new Fill({
                color: this.generalColorByTfLevel(pointsArr[i].strong), //'#ff0000',
              }),
              radius: 4,
             
            }),
          })
        );
      
        featureArr.push(featurepoint);
      }

      //连线
      let tf2line = new Feature({
        geometry: new LineString(lonlatArr),
      });
      tf2line.setStyle(
        new Style({
          stroke: new Stroke({
            color: "#FF0000",
            width: 2,
          }),
        })
      );

      //风圈
      let windCircleFeature = new Feature({
        geometry: new Point(lonlatArr[0]),
      });
      let markerStyle = new Style({
        // 设置icon大小
        image: new Icon({
          scale: 0.8,
          src: this.imgUrl4, //'editor-0.8s-47px.gif' //'/typhoon.png'
       
      windCircleFeature.setStyle(markerStyle);

      this.tf2VecSource.addFeatures(featureArr); //添加点
      this.tf2VecSource.addFeature(tf2line); //添加线
      this.tf2VecSource.addFeature(windCircleFeature); //添加台风
  
      // console.log(toLonLat(lonlatArr[0]), 'lonlatArr[0]lonlatArr[0]lonlatArr[0]');
      //绘制台风 风圈大画法
      let center = toLonLat(lonlatArr[0]);
      let f = this.generalCurveFeature(center[0], center[1], 150000, 0, 90, 0.5);
      let f1 = this.generalCurveFeature(center[0], center[1], 100000, 70, 190, 0.5);
      let f2 = this.generalCurveFeature(center[0], center[1],60000 , 170, 290, 0.5);
       let f3 = this.generalCurveFeature(center[0], center[1],90000 , 250, 370, 0.5);
      let mianSource = new VectorSource({ wrapX: false });
      let mianLayer = new VectorLayer({
          source: mianSource,
      });
      // 创建显示样式
      var stylemian = new Style({
          fill: new Fill({
              color: "rgba(27, 181, 56)",
          }),
      });
       var stylemian2 = new Style({
          fill: new Fill({
              color: "rgba(168,12,1)",
          }),
      });
        var stylemian3 = new Style({
          fill: new Fill({
              color: "rgba(24,36,128)",
          }),

      });
       var stylemian4 = new Style({
          fill: new Fill({
              color: "rgba(66,22,14)",
          }),
      });
      f.setStyle(stylemian);
      f1.setStyle(stylemian);
      f2.setStyle(stylemian);
       f3.setStyle(stylemian);
      mianSource.addFeature(f);
      mianSource.addFeature(f1);
      mianSource.addFeature(f2);
      mianSource.addFeature(f3);

      this.map.addLayer(mianLayer);





      //计时器
      let flagIndex = 0;
      let tfImgDom = document.querySelector("#tfImg");
      let rot = 0;
      let tempInterval = setInterval(() => {
        flagIndex++;
      
        if (flagIndex == lonlatArr.length) {
          clearInterval(tempInterval);
        }
        rot += 60;
        if (rot >= 360) {
          rot = 0;
        }
        markerStyle = new Style({
          // 设置icon大小
          image: new Icon({
            scale: 0.8,
            src: this.imgUrl4, //'/typhoon.png', //'editor-0.8s-47px.gif' //'/typhoon.png'
            rotation: (Math.PI / 180) * rot,
          }),
        });
        // markerStyle.setRotation(Math.PI/180*rot);
        windCircleFeature.setStyle(markerStyle); //添加风圈样式
        //更新风圈坐标
        let newGeometry = new Point(lonlatArr[flagIndex]);
        windCircleFeature.setGeometry(newGeometry);
        //  console.log(lonlatArr1[flagIndex], 'ccccccccccc');

        //警戒线提示
        let tfPoint = this.$turf.point([
          parseFloat(lonlatArr1[flagIndex][0]),
          parseFloat(lonlatArr1[flagIndex][1]),
        ]);
        // console.log(tfPoint, "tfPoint");
        console.log("this.alertLine24Turf", this.alertLine24Turf);
        let isAlert24 = this.$turf.booleanPointOnLine(
          tfPoint,
          this.alertLine24Turf,
          { ignoreEndVertices: false, epsilon: 3 }
        );
        if (isAlert24) {
          console.log("已过24警戒线");
          //经纬度坐标转屏幕坐标 tf2AlterInfo
          let pixel = this.lonlat2pixel({
            lon: lonlatArr1[flagIndex][0],
            lat: lonlatArr1[flagIndex][1],
          });
          let dom = document.querySelector("#tf2AlterInfo");
          dom.style.display = "block";
          dom.style.top = pixel[1] + "px";
          dom.style.left = pixel[0] + "px";
          this.tf2AlterInfo = "已过24警戒线";
        } else {
          // document.querySelector("#tf2AlterInfo").style.display = 'none';
        }
        let isAlert48 = this.$turf.booleanPointOnLine(
          tfPoint,
          this.alertLine48Turf,
          { ignoreEndVertices: false, epsilon: 6 }
        );
        if (isAlert48) {
          //  console.log("过了48警戒线");
          let pixel = this.lonlat2pixel({
            lon: lonlatArr1[flagIndex][0],
            lat: lonlatArr1[flagIndex][1],
          });
          let dom = document.querySelector("#tf2AlterInfo");
          dom.style.display = "block";
          dom.style.top = pixel[1] + "px";
          dom.style.left = pixel[0] + "px";
          this.tf2AlterInfo = "已过48警戒线";
        }
      }, 500);
      //  this.map.removeLayer(newGeometry);
      //警戒线方法
      this.cordonFun();
    },
    /*
     *@description: 根据台风等级类型定义锚点的颜色
     */
    getTypeColor(type) {
      if (type == "TD") return "#02ff02";
      else if (type == "TS") return "#0264ff";
      else if (type == "STS") return "#fffb05";
      else if (type == "TY") return "#ffac05";
      else if (type == "STY") return "#f171f9";
      else if (type == "Super TY") return "#fe0202";
      else return "#02ff02";
    },
    //根据不同的台风强度设置不同的颜色
    generalColorByTfLevel(name) {
      let color = "#ff0000";
      switch (name) {
        case "热带风暴":
          color = "blue";
          break;
        case "热带低压":
          color = "green";
          break;
        case "强热带风暴":
          color = "yellow";
          break;
        case "台风":
          color = "orange";
          break;
        case "强台风":
          color = "pink";
          break;
        case "超强台风":
          color = "salmon";
          break;
      }
      // console.log(color, "color");
      return color;
    },

    /*
     *@description: 添加警戒线
     */
    cordonFun() {
      // 警戒线图层
      this.warningLineLayer = new VectorLayer({
        source: new VectorSource(),
        name: "警戒线",
      });
      this.map.addLayer(this.warningLineLayer);
      console.log(1);
      // 台风48小时警戒线
      const line48 = new Feature({
        geometry: new LineString([
          fromLonLat([132, 34]),
          fromLonLat([132, 15]),
          fromLonLat([120, 0]),
          fromLonLat([105, 0]),
        ]),
      });
      line48.setStyle(this.getLineStyle("#face55", true));
      this.setTextLabel(
        fromLonLat([132, 28]),
        "48\n\n\n\n\n线",
        "#face55"
      );
      this.warningLineLayer.getSource().addFeature(line48);
      // 台风24小时警戒线
      const line24 = new Feature({
        geometry: new LineString([
          fromLonLat([127, 34]),
          fromLonLat([127, 22]),
          fromLonLat([119, 18]),
          fromLonLat([119, 11]),
          fromLonLat([113, 4.5]),
          fromLonLat([105, 0]),
        ]),
      });
      line24.setStyle(this.getLineStyle("#e44f26", false));
      this.setTextLabel(
        fromLonLat([127, 28]),
        "24\n\n\n\n\n线",
        "#e44f26"
      );
      this.warningLineLayer.getSource().addFeature(line24);
    },
    /*
     *@description: 设置警戒线要素
     *@author: zhangyangyang
     *@date: 2022-02-20 18:14:05
     */
    getLineStyle(color, lineDash) {
      return new Style({
        stroke: new Stroke({
          color: color,
          width: 1,
          lineDash: lineDash ? [3, 3] : undefined,
        }),
      });
    },
    /*
     *@description: 设置警戒线文字标注
     */
    setTextLabel(coordinate, text, color) {
      let feature = new Feature({
        geometry: new Point(coordinate),
      });
      feature.setStyle(
        new Style({
          text: new TextStyle({
            text: text,
            font: "normal 12px 宋体",
            offsetX: 10,
            textAlign: "center",
            textBaseline: "middle",
            fill: new Fill({ color: color }),
          }),
        })
      );
      this.warningLineLayer.getSource().addFeature(feature);
    },
Logo

前往低代码交流专区

更多推荐