侧边栏壁纸
博主头像
分享你我博主等级

行动起来,活在当下

  • 累计撰写 107 篇文章
  • 累计创建 13 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

VUE3 使用 openlayers v6.6.1 绘制台风路径、台风圈

管理员
2021-08-30 / 0 评论 / 0 点赞 / 3 阅读 / 101963 字

ts代码:

import { Feature, Overlay } from 'ol';
import { Point, Polygon, LineString, Circle as GeomCircle } from 'ol/geom';
import { Vector as LayerVector } from 'ol/layer';
import { Style, Stroke, Circle, Fill } from 'ol/style';
import { Vector } from 'ol/source';
import { WKT } from 'ol/format';
import { fromLonLat } from 'ol/proj';
import d from '../assets/201929';
export default class Typhoon {
  _map: any;
  _speed: Number = 200;
  _forcColorDict: any = {
    中国: '#ec5d72',
    中国香港: '#ec7cfe',
    中国台湾: '#ecaa65',
    日本: '#56f66e',
    美国: '#53dbfe',
    韩国: '#72a4ac',
    欧洲: '#4c54a6',
  };
  _typhoonList: any = [];
  _typhoonData: any = {};
  _nameOverlays: any = {};
  _typhoonPlayFlag: any = {};
  _typhoonPlayIndex: any = {};
  _warnLines: any = null;
  _typhoonLayers: any = {};
  _forecastFeatures: any = {};
  _typhoonCircle: any = [];
  wktformat:any = new WKT();
  constructor(map: any) {
    this._map = map;
  }
  
  init = () => {
    // 添加警戒线
    this.addWarnLine();
    // 添加地图事件
    this.addMapEvent();
    this.showTyphoon(d.data[0]);
    // 获取台风数据
    // $.get('../../data/201929.json', (res) => {
    //   _typhoonList = res;
    //   showTyphoon(_typhoonList[0]);
    // });
  };
  addWarnLine = () => {
    const warnLineData = [
      {
        color: 'blue',
        weight: 1,
        opacity: 0.8,
        dashArray: [0, 0],
        points: [
          [105, 0],
          [113, 4.5],
          [119, 11],
          [119, 18],
          [127, 22],
          [127, 34],
        ],
      },
      {
        color: 'green',
        weight: 1,
        opacity: 0.8,
        dashArray: [10, 5],
        points: [
          [105, 0],
          [120, 0],
          [132, 15],
          [132, 34],
        ],
      },
    ];
    const features = [];
    for (var i = 0; i < warnLineData.length; i++) {
      const d = warnLineData[i];
      const geometry = new LineString(d.points);
      geometry.transform('EPSG:4326', this._map.getView().getProjection());
      const feature = new Feature({
        geometry: geometry,
        attr: d,
      });
      features.push(feature);
    }
    const source = new Vector({
      features: features,
    });
    this._warnLines = new LayerVector({
      source: source,
      style: this.warnLineStyle,
      opacity: 0.8,
    });
    this._map.addLayer(this._warnLines);
  };
  // 警戒线样式设置
  warnLineStyle = (feat: any) => {
    const attr = feat.get('attr');
    return new Style({
      stroke: new Stroke({
        color: attr.color,
        width: attr.weight,
        lineDash: attr.dashArray,
      }),
    });
  };
  // 添加地图事件
  addMapEvent = () => {
    // 鼠标移动事件
    this._map.on('pointermove', (evt: any) => {
      const pixel = evt.pixel;
      const dom = this._map.getTargetElement();
      if (this._map.hasFeatureAtPixel(pixel)) {
        dom.style.cursor = 'pointer';
        const features = this._map.getFeaturesAtPixel(pixel);
        const feature = features[0];
        // console.log(feature.get('attr'));
      } else {
        dom.style.cursor = 'default';
      }
    });
    this._map.on('click', (evt: any) => {
      const pixel = evt.pixel;
      if (this._map.hasFeatureAtPixel(pixel)) {
        const features = this._map.getFeaturesAtPixel(pixel);
        const feature = features[0];
        const attr = feature.get('attr');
        this._typhoonPlayIndex[attr.tfbh] = attr.index;
        this.showForecast(attr.tfbh, attr);
      }
    });
  };
  // 展示台风
  showTyphoon = (typhoonData: any) => {
    const tfbh = typhoonData.tfbh;
    this._typhoonData[tfbh] = typhoonData;
    // 1. 添加台风名称
    this.addNameOverlay(typhoonData);
    // 2. 创建展示图层
    this.addTyphoonLayer(tfbh);
    // 3.开始播放
    this.playTyphoon(tfbh);
  };
  // 移除台风
  removeTyphoon = (tfbh: any) => {
    // 删除台风名称
    this._map.removeOverlay(this._nameOverlays[tfbh]);
    // 删除展示图层
    this._map.removeLayer(this._typhoonLayers[tfbh].layer);
    // 消除定时器
    clearInterval(this._typhoonPlayFlag[tfbh]);
  };
  // 添加台风名称
  addNameOverlay = (typhoonData: any) => {
    const nameDom = document.createElement('div');
    nameDom.setAttribute('class', 'typhoon-name');
    nameDom.innerHTML = typhoonData.name;
    const pointStart = typhoonData.points[0];
    // const position = fromLonLat([
    //   pointStart.longitude,
    //   pointStart.latitude,
    // ]);
    const nameOverlay = new Overlay({
      element: nameDom,
      position: [pointStart.longitude, pointStart.latitude],
      positioning: 'center-left',
      offset: [15, 0],
    });
    this._map.addOverlay(nameOverlay);
    this._nameOverlays[typhoonData.tfbh] = nameOverlay;
    this._typhoonCircle[typhoonData.tfbh]=this.drawTyphoonCircle(pointStart.longitude, pointStart.latitude);//台风圈
    
  };
  /**
   * 绘制台风圈
   */
  drawTyphoonCircle = (x: any, y: any) => {
    
    /** 台风配置 */
    var Configs = {
      // CIRCLE_CENTER_X:104.21390114106414,
      // CIRCLE_CENTER_Y:35.847595169932646,
      CIRCLE_CENTER_X: x,
      CIRCLE_CENTER_Y: y,
      CIRCLE_R: {
        "SE": 0.5,
        "NE": 0.3,
        "NW": 0.2,
        "SW": 0.5
      }
    };
    /** 台风算法 */
    var wkt = "POLYGON((";
    var wkt0 = "", _interval = 6;
    for (var i = 0; i < 360 / _interval; i++) {
      var _r = 0;
      var _ang = i * _interval;
      if (_ang > 0 && _ang <= 90) {
        _r = Configs.CIRCLE_R.NE;
      }
      else if (_ang > 90 && _ang <= 180) {
        _r = Configs.CIRCLE_R.NW;
      }
      else if (_ang > 180 && _ang <= 270) {
        _r = Configs.CIRCLE_R.SW;
      }
      else {
        _r = Configs.CIRCLE_R.SE;
      }
    
      var x = Configs.CIRCLE_CENTER_X + _r * Math.cos(_ang * 3.14 / 180);
      var y = Configs.CIRCLE_CENTER_Y + _r * Math.sin(_ang * 3.14 / 180);
    
      wkt = wkt + "" + x + " " + y + ", ";
      if (i === 0) {
        wkt0 = "" + x + " " + y + "";
      }
    }
    wkt = wkt + wkt0 + "))";
    var features = new Array();
    features.push(this.wktformat.readFeature(wkt));
    features.push(this.wktformat.readFeature("POINT(" + Configs.CIRCLE_CENTER_X + " " + Configs.CIRCLE_CENTER_Y + ")"));
    
    var styleFunc = (feature: any, resolution: any) => {
      return new Style({
        fill: new Fill({
          color: 'rgba(255, 0, 0, 0.2)'
        }),
        stroke: new Stroke({
          color: '#ffcc33',
          width: 2
        }),
        image: new Circle({
          radius: 4,
          fill: new Fill({
            color: '#ff0000'
          })
        })
      });
    };
    var layerVector = new LayerVector({
      source: new Vector({
        features: features,
      }),
      style: styleFunc
    });
    this._map.addLayer(layerVector);
    return layerVector;
  };
  /**
   * 删除台风圈
   * @param tfbh 分组名称
   */
  removeTyphoonCircle = (tfbh: any)=>{
    // const source = this._typhoonCircle[tfbh].getSource();
    // source.removeFeature(this._typhoonCircle[tfbh]);
    this._typhoonCircle[tfbh].getSource().clear();
    this._map.removeLayer(this._typhoonCircle[tfbh]);
  }
  // 根据编号添加台风图层
  addTyphoonLayer = (tfbh: any) => {
    const source = new Vector({
      features: [],
    });
    const layer = new LayerVector({
      source: source,
      style: this.typhoonStyle,
    });
    this._map.addLayer(layer);
    this._typhoonLayers[tfbh] = {
      source: source,
      layer: layer,
    };
    this._forecastFeatures[tfbh] = [];
  };
  // 播放台风
  playTyphoon = (tfbh: any) => {
    let index = 0;
    const typhoonData = this._typhoonData[tfbh];
    this.play(index, tfbh);
    this._typhoonPlayFlag[tfbh] = setInterval(() => {
      index++;
      if (index === typhoonData.points.length) {
        clearInterval(this._typhoonPlayFlag[tfbh]);
      } else {
        this.play(index, tfbh);
      }
    }, 200);
  };
  // 播放单个点
  play = (index: any, tfbh: any) => {
    // 删除预报
    this.removeForecast(tfbh);
    this.removeTyphoonCircle(tfbh);
    this._map.removeLayer(this._typhoonCircle[tfbh]);
    this._typhoonPlayIndex[tfbh] = index;
    const points = this._typhoonData[tfbh].points;
    const point = points[index];
    point.type = 'live';
    point.index = index;
    point.tfbh = tfbh;
    if (index > 0) {
      const prePoint = points[index - 1];
      point.start = [prePoint.longitude, prePoint.latitude];
    }
    point.end = [point.longitude, point.latitude];
    //const position = fromLonLat(point.end);
    const position = point.end;
    //点的数据设置
    const feature = new Feature({
      geometry: new Point(position),
      attr: point,
    });
    this._typhoonLayers[tfbh].source.addFeature(feature);
    this._typhoonCircle[tfbh]=this.drawTyphoonCircle(point.longitude, point.latitude);//台风圈
    // console.log("输出数据", this._typhoonCircle[tfbh].getSource().getFeatures()[0].getGeometry());
    
    // this._typhoonCircle[tfbh].getSource().getFeatures()[0].getGeometry().setCoordinates(feature);
    // debugger;
    console.log("分类保存的台风圈");
    // 最后一个实况点,展示预报路径
    if (index === this._typhoonData[tfbh].points.length - 1) {
      this.showForecast(tfbh, point);
    }
  };
  // 删除预报数据
  removeForecast = (tfbh: any) => {
    const source = this._typhoonLayers[tfbh].source;
    for (var i = 0; i < this._forecastFeatures[tfbh].length; i++) {
      const f = this._forecastFeatures[tfbh][i];
      source.removeFeature(f);
    }
    this._forecastFeatures[tfbh] = [];
  };
  // 展示预报数据
  showForecast = (tfbh: any, livePoint: any) => {
    const source = this._typhoonLayers[tfbh].source;
    // 1. 删除预报数据
    this.removeForecast(tfbh);
    // 2. 添加预报
    const forecast = livePoint.forecast;
    const features = [];
    for (var i = 0; i < forecast.length; i++) {
      const f = forecast[i];
      for (var j = 0; j < f.points.length; j++) {
        const point = f.points[j];
        const prePoint = f.points[j - 1];
        point.sets = f.sets;
        point.type = 'forc';
        point.index = j;
        point.start =
          j === 0
            ? [livePoint.longitude, livePoint.latitude]
            : [prePoint.longitude, prePoint.latitude];
        point.end = [point.longitude, point.latitude];
        //const coords = fromLonLat(point.end);
        const coords = point.end;
        const feature = new Feature({
          geometry: new Point(coords),
          attr: point,
        });
        features.push(feature);
      }
    }
    source.addFeatures(features);
    this._forecastFeatures[tfbh] = features;
  };
  // 根据风速获取点的颜色
  getPointColor = (speed: any) => {
    let _color = '';
    if (speed >= 10.8 && speed < 17.2) {
      _color = 'rgba(153, 255, 153, .9)';
    } else if (speed >= 17.2 && speed < 24.5) {
      _color = 'rgba(102, 204, 255, .9)';
    } else if (speed >= 24.5 && speed < 32.7) {
      _color = 'rgba(255, 255, 102, .9)';
    } else if (speed >= 32.7 && speed < 41.5) {
      _color = 'rgba(253, 139, 0, .9)';
    } else if (speed >= 41.5 && speed < 50.1) {
      _color = 'rgba(255, 51, 0, .9)';
    } else {
      _color = 'rgba(255, 0, 255, .9)';
    }
    return _color;
  };
  // 台风展示样式
  typhoonStyle = (feat: any) => {
    const attr = feat.get('attr');
    const speed = 12; //attr.speed;
    const type = attr.type;
    const index = attr.index;
    const color = this.getPointColor(speed);
    let styles = [];
    // 点的样式
    const radius = type === 'live' ? 4 : 3;
    const pointStyle = new Style({
      image: new Circle({
        radius: radius,
        fill: new Fill({
          color: color,
        }),
        stroke: new Stroke({
          color: 'rgba(0, 0, 0, 0.6)',
          width: 1,
        }),
      }),
    });
    styles.push(pointStyle);
    if (type === 'live' && index === this._typhoonPlayIndex[attr.tfbh]) {
      const center = feat.get('geometry').getCoordinates();
      const fillStyle = new Fill({
        color: 'rgba(0, 0, 0, 0.2)',
      });
      // 7级风圈的样式
      if (attr.radius7 > 0) {
        const geometry: any = this.getCircleGeometry(center, attr.radius7_quad);
        const style = new Style({
          geometry: geometry,
          stroke: new Stroke({
            color: '#00bab2',
            width: 1,
          }),
          fill: fillStyle,
        });
        styles.push(style);
      }
      // 10级风圈的样式
      if (attr.radius10 > 0) {
        const geometry: any = this.getCircleGeometry(
          center,
          attr.radius10_quad
        );
        const style = new Style({
          geometry: geometry,
          stroke: new Stroke({
            color: '#ffff00',
            width: 1,
          }),
          fill: fillStyle,
        });
        styles.push(style);
      }
      // 12级风圈的样式
      if (attr.radius12 > 0) {
        const geometry: any = this.getCircleGeometry(
          center,
          attr.radius12_quad
        );
        const style = new Style({
          geometry: geometry,
          stroke: new Stroke({
            color: '#da7341',
            width: 1,
          }),
          fill: fillStyle,
        });
        styles.push(style);
      }
    }
    // 线的样式
    const start = attr.start;
    const end = attr.end;
    const lineColor = this.getLineColor(type, attr.sets);
    const lineDash = type === 'live' ? [0] : [8];
    const lineWidth = type === 'live' ? 2 : 1;
    if (start && start.length > 0) {
      const coords = [start, end];
      const geometry = new LineString(coords);
      geometry.transform('EPSG:4326', this._map.getView().getProjection());
      const lineStyle = new Style({
        geometry: geometry,
        stroke: new Stroke({
          color: lineColor,
          width: lineWidth,
          lineDash: lineDash,
        }),
      });
      styles.push(lineStyle);
    }
    return styles;
  };
  // 获取线的颜色
  getLineColor = (type: any, sets: any) => {
    if (type === 'live') {
      return 'rgba(0, 0, 0, .6)';
    } else {
      let color = this._forcColorDict[sets];
      if (!color) color = 'rgba(0, 0, 0, .3)';
      return color;
    }
  };
  getCircleGeometry = (center: any, radiusData: any) => {
    if (typeof radiusData === 'number') {
      return new GeomCircle(center, radiusData * 1000);
    } else {
      if (radiusData['ne']) {
        let _coords = [];
        let _angInterval = 6;
        let _pointNums = 360 / (_angInterval * 4);
        let quadrant: any = {
          // 逆时针算角度
          '0': 'ne',
          '1': 'nw',
          '2': 'sw',
          '3': 'se',
        };
        for (let i = 0; i < 4; i++) {
          let _r = parseFloat(radiusData[quadrant[i]]) * 1000; // 单位是km
          if (!_r) _r = 0;
          for (let j = i * _pointNums; j <= (i + 1) * _pointNums; j++) {
            let _ang = _angInterval * j;
            let x = center[0] + _r * Math.cos((_ang * Math.PI) / 180);
            let y = center[1] + _r * Math.sin((_ang * Math.PI) / 180);
            _coords.push([x, y]);
          }
        }
        return new Polygon([_coords]);
      } else {
        return null;
      }
    }
  };
}


js代码

"use strict";
exports.__esModule = true;
var ol_1 = require("ol");
var geom_1 = require("ol/geom");
var layer_1 = require("ol/layer");
var style_1 = require("ol/style");
var source_1 = require("ol/source");
var format_1 = require("ol/format");
var _201929_1 = require("../assets/201929");
var Typhoon = /** @class */ (function () {
    function Typhoon(map) {
        var _this = this;
        this._speed = 200;
        this._forcColorDict = {
            中国: '#ec5d72',
            中国香港: '#ec7cfe',
            中国台湾: '#ecaa65',
            日本: '#56f66e',
            美国: '#53dbfe',
            韩国: '#72a4ac',
            欧洲: '#4c54a6'
        };
        this._typhoonList = [];
        this._typhoonData = {};
        this._nameOverlays = {};
        this._typhoonPlayFlag = {};
        this._typhoonPlayIndex = {};
        this._warnLines = null;
        this._typhoonLayers = {};
        this._forecastFeatures = {};
        this._typhoonCircle = [];
        this.wktformat = new format_1.WKT();
        this.init = function () {
            // 添加警戒线
            _this.addWarnLine();
            // 添加地图事件
            _this.addMapEvent();
            _this.showTyphoon(_201929_1["default"].data[0]);
            // 获取台风数据
            // $.get('../../data/201929.json', (res) => {
            //   _typhoonList = res;
            //   showTyphoon(_typhoonList[0]);
            // });
        };
        this.addWarnLine = function () {
            var warnLineData = [
                {
                    color: 'blue',
                    weight: 1,
                    opacity: 0.8,
                    dashArray: [0, 0],
                    points: [
                        [105, 0],
                        [113, 4.5],
                        [119, 11],
                        [119, 18],
                        [127, 22],
                        [127, 34],
                    ]
                },
                {
                    color: 'green',
                    weight: 1,
                    opacity: 0.8,
                    dashArray: [10, 5],
                    points: [
                        [105, 0],
                        [120, 0],
                        [132, 15],
                        [132, 34],
                    ]
                },
            ];
            var features = [];
            for (var i = 0; i < warnLineData.length; i++) {
                var d_1 = warnLineData[i];
                var geometry = new geom_1.LineString(d_1.points);
                geometry.transform('EPSG:4326', _this._map.getView().getProjection());
                var feature = new ol_1.Feature({
                    geometry: geometry,
                    attr: d_1
                });
                features.push(feature);
            }
            var source = new source_1.Vector({
                features: features
            });
            _this._warnLines = new layer_1.Vector({
                source: source,
                style: _this.warnLineStyle,
                opacity: 0.8
            });
            _this._map.addLayer(_this._warnLines);
        };
        // 警戒线样式设置
        this.warnLineStyle = function (feat) {
            var attr = feat.get('attr');
            return new style_1.Style({
                stroke: new style_1.Stroke({
                    color: attr.color,
                    width: attr.weight,
                    lineDash: attr.dashArray
                })
            });
        };
        // 添加地图事件
        this.addMapEvent = function () {
            // 鼠标移动事件
            _this._map.on('pointermove', function (evt) {
                var pixel = evt.pixel;
                var dom = _this._map.getTargetElement();
                if (_this._map.hasFeatureAtPixel(pixel)) {
                    dom.style.cursor = 'pointer';
                    var features = _this._map.getFeaturesAtPixel(pixel);
                    var feature = features[0];
                    // console.log(feature.get('attr'));
                }
                else {
                    dom.style.cursor = 'default';
                }
            });
            _this._map.on('click', function (evt) {
                var pixel = evt.pixel;
                if (_this._map.hasFeatureAtPixel(pixel)) {
                    var features = _this._map.getFeaturesAtPixel(pixel);
                    var feature = features[0];
                    var attr = feature.get('attr');
                    _this._typhoonPlayIndex[attr.tfbh] = attr.index;
                    _this.showForecast(attr.tfbh, attr);
                }
            });
        };
        // 展示台风
        this.showTyphoon = function (typhoonData) {
            var tfbh = typhoonData.tfbh;
            _this._typhoonData[tfbh] = typhoonData;
            // 1. 添加台风名称
            _this.addNameOverlay(typhoonData);
            // 2. 创建展示图层
            _this.addTyphoonLayer(tfbh);
            // 3.开始播放
            _this.playTyphoon(tfbh);
        };
        // 移除台风
        this.removeTyphoon = function (tfbh) {
            // 删除台风名称
            _this._map.removeOverlay(_this._nameOverlays[tfbh]);
            // 删除展示图层
            _this._map.removeLayer(_this._typhoonLayers[tfbh].layer);
            // 消除定时器
            clearInterval(_this._typhoonPlayFlag[tfbh]);
        };
        // 添加台风名称
        this.addNameOverlay = function (typhoonData) {
            var nameDom = document.createElement('div');
            nameDom.setAttribute('class', 'typhoon-name');
            nameDom.innerHTML = typhoonData.name;
            var pointStart = typhoonData.points[0];
            // const position = fromLonLat([
            //   pointStart.longitude,
            //   pointStart.latitude,
            // ]);
            var nameOverlay = new ol_1.Overlay({
                element: nameDom,
                position: [pointStart.longitude, pointStart.latitude],
                positioning: 'center-left',
                offset: [15, 0]
            });
            _this._map.addOverlay(nameOverlay);
            _this._nameOverlays[typhoonData.tfbh] = nameOverlay;
            _this._typhoonCircle[typhoonData.tfbh] = _this.drawTyphoonCircle(pointStart.longitude, pointStart.latitude); //台风圈
        };
        /**
         * 绘制台风圈
         */
        this.drawTyphoonCircle = function (x, y) {
            /** 台风配置 */
            var Configs = {
                // CIRCLE_CENTER_X:104.21390114106414,
                // CIRCLE_CENTER_Y:35.847595169932646,
                CIRCLE_CENTER_X: x,
                CIRCLE_CENTER_Y: y,
                CIRCLE_R: {
                    "SE": 0.5,
                    "NE": 0.3,
                    "NW": 0.2,
                    "SW": 0.5
                }
            };
            /** 台风算法 */
            var wkt = "POLYGON((";
            var wkt0 = "", _interval = 6;
            for (var i = 0; i < 360 / _interval; i++) {
                var _r = 0;
                var _ang = i * _interval;
                if (_ang > 0 && _ang <= 90) {
                    _r = Configs.CIRCLE_R.NE;
                }
                else if (_ang > 90 && _ang <= 180) {
                    _r = Configs.CIRCLE_R.NW;
                }
                else if (_ang > 180 && _ang <= 270) {
                    _r = Configs.CIRCLE_R.SW;
                }
                else {
                    _r = Configs.CIRCLE_R.SE;
                }
                var x = Configs.CIRCLE_CENTER_X + _r * Math.cos(_ang * 3.14 / 180);
                var y = Configs.CIRCLE_CENTER_Y + _r * Math.sin(_ang * 3.14 / 180);
                wkt = wkt + "" + x + " " + y + ", ";
                if (i === 0) {
                    wkt0 = "" + x + " " + y + "";
                }
            }
            wkt = wkt + wkt0 + "))";
            var features = new Array();
            features.push(_this.wktformat.readFeature(wkt));
            features.push(_this.wktformat.readFeature("POINT(" + Configs.CIRCLE_CENTER_X + " " + Configs.CIRCLE_CENTER_Y + ")"));
            var styleFunc = function (feature, resolution) {
                return new style_1.Style({
                    fill: new style_1.Fill({
                        color: 'rgba(255, 0, 0, 0.2)'
                    }),
                    stroke: new style_1.Stroke({
                        color: '#ffcc33',
                        width: 2
                    }),
                    image: new style_1.Circle({
                        radius: 4,
                        fill: new style_1.Fill({
                            color: '#ff0000'
                        })
                    })
                });
            };
            var layerVector = new layer_1.Vector({
                source: new source_1.Vector({
                    features: features
                }),
                style: styleFunc
            });
            _this._map.addLayer(layerVector);
            return layerVector;
        };
        /**
         * 删除台风圈
         * @param tfbh 分组名称
         */
        this.removeTyphoonCircle = function (tfbh) {
            // const source = this._typhoonCircle[tfbh].getSource();
            // source.removeFeature(this._typhoonCircle[tfbh]);
            _this._typhoonCircle[tfbh].getSource().clear();
            _this._map.removeLayer(_this._typhoonCircle[tfbh]);
        };
        // 根据编号添加台风图层
        this.addTyphoonLayer = function (tfbh) {
            var source = new source_1.Vector({
                features: []
            });
            var layer = new layer_1.Vector({
                source: source,
                style: _this.typhoonStyle
            });
            _this._map.addLayer(layer);
            _this._typhoonLayers[tfbh] = {
                source: source,
                layer: layer
            };
            _this._forecastFeatures[tfbh] = [];
        };
        // 播放台风
        this.playTyphoon = function (tfbh) {
            var index = 0;
            var typhoonData = _this._typhoonData[tfbh];
            _this.play(index, tfbh);
            _this._typhoonPlayFlag[tfbh] = setInterval(function () {
                index++;
                if (index === typhoonData.points.length) {
                    clearInterval(_this._typhoonPlayFlag[tfbh]);
                }
                else {
                    _this.play(index, tfbh);
                }
            }, 200);
        };
        // 播放单个点
        this.play = function (index, tfbh) {
            // 删除预报
            _this.removeForecast(tfbh);
            _this.removeTyphoonCircle(tfbh);
            _this._map.removeLayer(_this._typhoonCircle[tfbh]);
            _this._typhoonPlayIndex[tfbh] = index;
            var points = _this._typhoonData[tfbh].points;
            var point = points[index];
            point.type = 'live';
            point.index = index;
            point.tfbh = tfbh;
            if (index > 0) {
                var prePoint = points[index - 1];
                point.start = [prePoint.longitude, prePoint.latitude];
            }
            point.end = [point.longitude, point.latitude];
            //const position = fromLonLat(point.end);
            var position = point.end;
            //点的数据设置
            var feature = new ol_1.Feature({
                geometry: new geom_1.Point(position),
                attr: point
            });
            _this._typhoonLayers[tfbh].source.addFeature(feature);
            _this._typhoonCircle[tfbh] = _this.drawTyphoonCircle(point.longitude, point.latitude); //台风圈
            // console.log("输出数据", this._typhoonCircle[tfbh].getSource().getFeatures()[0].getGeometry());
            // this._typhoonCircle[tfbh].getSource().getFeatures()[0].getGeometry().setCoordinates(feature);
            // debugger;
            console.log("分类保存的台风圈");
            // 最后一个实况点,展示预报路径
            if (index === _this._typhoonData[tfbh].points.length - 1) {
                _this.showForecast(tfbh, point);
            }
        };
        // 删除预报数据
        this.removeForecast = function (tfbh) {
            var source = _this._typhoonLayers[tfbh].source;
            for (var i = 0; i < _this._forecastFeatures[tfbh].length; i++) {
                var f = _this._forecastFeatures[tfbh][i];
                source.removeFeature(f);
            }
            _this._forecastFeatures[tfbh] = [];
        };
        // 展示预报数据
        this.showForecast = function (tfbh, livePoint) {
            var source = _this._typhoonLayers[tfbh].source;
            // 1. 删除预报数据
            _this.removeForecast(tfbh);
            // 2. 添加预报
            var forecast = livePoint.forecast;
            var features = [];
            for (var i = 0; i < forecast.length; i++) {
                var f = forecast[i];
                for (var j = 0; j < f.points.length; j++) {
                    var point = f.points[j];
                    var prePoint = f.points[j - 1];
                    point.sets = f.sets;
                    point.type = 'forc';
                    point.index = j;
                    point.start =
                        j === 0
                            ? [livePoint.longitude, livePoint.latitude]
                            : [prePoint.longitude, prePoint.latitude];
                    point.end = [point.longitude, point.latitude];
                    //const coords = fromLonLat(point.end);
                    var coords = point.end;
                    var feature = new ol_1.Feature({
                        geometry: new geom_1.Point(coords),
                        attr: point
                    });
                    features.push(feature);
                }
            }
            source.addFeatures(features);
            _this._forecastFeatures[tfbh] = features;
        };
        // 根据风速获取点的颜色
        this.getPointColor = function (speed) {
            var _color = '';
            if (speed >= 10.8 && speed < 17.2) {
                _color = 'rgba(153, 255, 153, .9)';
            }
            else if (speed >= 17.2 && speed < 24.5) {
                _color = 'rgba(102, 204, 255, .9)';
            }
            else if (speed >= 24.5 && speed < 32.7) {
                _color = 'rgba(255, 255, 102, .9)';
            }
            else if (speed >= 32.7 && speed < 41.5) {
                _color = 'rgba(253, 139, 0, .9)';
            }
            else if (speed >= 41.5 && speed < 50.1) {
                _color = 'rgba(255, 51, 0, .9)';
            }
            else {
                _color = 'rgba(255, 0, 255, .9)';
            }
            return _color;
        };
        // 台风展示样式
        this.typhoonStyle = function (feat) {
            var attr = feat.get('attr');
            var speed = 12; //attr.speed;
            var type = attr.type;
            var index = attr.index;
            var color = _this.getPointColor(speed);
            var styles = [];
            // 点的样式
            var radius = type === 'live' ? 4 : 3;
            var pointStyle = new style_1.Style({
                image: new style_1.Circle({
                    radius: radius,
                    fill: new style_1.Fill({
                        color: color
                    }),
                    stroke: new style_1.Stroke({
                        color: 'rgba(0, 0, 0, 0.6)',
                        width: 1
                    })
                })
            });
            styles.push(pointStyle);
            if (type === 'live' && index === _this._typhoonPlayIndex[attr.tfbh]) {
                var center = feat.get('geometry').getCoordinates();
                var fillStyle = new style_1.Fill({
                    color: 'rgba(0, 0, 0, 0.2)'
                });
                // 7级风圈的样式
                if (attr.radius7 > 0) {
                    var geometry = _this.getCircleGeometry(center, attr.radius7_quad);
                    var style = new style_1.Style({
                        geometry: geometry,
                        stroke: new style_1.Stroke({
                            color: '#00bab2',
                            width: 1
                        }),
                        fill: fillStyle
                    });
                    styles.push(style);
                }
                // 10级风圈的样式
                if (attr.radius10 > 0) {
                    var geometry = _this.getCircleGeometry(center, attr.radius10_quad);
                    var style = new style_1.Style({
                        geometry: geometry,
                        stroke: new style_1.Stroke({
                            color: '#ffff00',
                            width: 1
                        }),
                        fill: fillStyle
                    });
                    styles.push(style);
                }
                // 12级风圈的样式
                if (attr.radius12 > 0) {
                    var geometry = _this.getCircleGeometry(center, attr.radius12_quad);
                    var style = new style_1.Style({
                        geometry: geometry,
                        stroke: new style_1.Stroke({
                            color: '#da7341',
                            width: 1
                        }),
                        fill: fillStyle
                    });
                    styles.push(style);
                }
            }
            // 线的样式
            var start = attr.start;
            var end = attr.end;
            var lineColor = _this.getLineColor(type, attr.sets);
            var lineDash = type === 'live' ? [0] : [8];
            var lineWidth = type === 'live' ? 2 : 1;
            if (start && start.length > 0) {
                var coords = [start, end];
                var geometry = new geom_1.LineString(coords);
                geometry.transform('EPSG:4326', _this._map.getView().getProjection());
                var lineStyle = new style_1.Style({
                    geometry: geometry,
                    stroke: new style_1.Stroke({
                        color: lineColor,
                        width: lineWidth,
                        lineDash: lineDash
                    })
                });
                styles.push(lineStyle);
            }
            return styles;
        };
        // 获取线的颜色
        this.getLineColor = function (type, sets) {
            if (type === 'live') {
                return 'rgba(0, 0, 0, .6)';
            }
            else {
                var color = _this._forcColorDict[sets];
                if (!color)
                    color = 'rgba(0, 0, 0, .3)';
                return color;
            }
        };
        this.getCircleGeometry = function (center, radiusData) {
            if (typeof radiusData === 'number') {
                return new geom_1.Circle(center, radiusData * 1000);
            }
            else {
                if (radiusData['ne']) {
                    var _coords = [];
                    var _angInterval = 6;
                    var _pointNums = 360 / (_angInterval * 4);
                    var quadrant = {
                        // 逆时针算角度
                        '0': 'ne',
                        '1': 'nw',
                        '2': 'sw',
                        '3': 'se'
                    };
                    for (var i = 0; i < 4; i++) {
                        var _r = parseFloat(radiusData[quadrant[i]]) * 1000; // 单位是km
                        if (!_r)
                            _r = 0;
                        for (var j = i * _pointNums; j <= (i + 1) * _pointNums; j++) {
                            var _ang = _angInterval * j;
                            var x = center[0] + _r * Math.cos((_ang * Math.PI) / 180);
                            var y = center[1] + _r * Math.sin((_ang * Math.PI) / 180);
                            _coords.push([x, y]);
                        }
                    }
                    return new geom_1.Polygon([_coords]);
                }
                else {
                    return null;
                }
            }
        };
        this._map = map;
    }
    return Typhoon;
}());
exports["default"] = Typhoon;

使用:

 const map= new Typhoon(data.map);
        map.init();

效果:

image.png

image.png

0

评论区