欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue?openlayers實(shí)現(xiàn)臺風(fēng)軌跡示例詳解

 更新時(shí)間:2022年11月18日 09:44:22   作者:冬日暖陽一片云  
這篇文章主要為大家介紹了vue?openlayers實(shí)現(xiàn)臺風(fēng)軌跡示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

功能描述

  • 臺風(fēng)軌跡點(diǎn)實(shí)時(shí)繪制,根據(jù)不同點(diǎn)的類型繪制不同的軌跡點(diǎn)顏色
  • 軌跡線繪制,涉及實(shí)時(shí)軌跡線段與預(yù)報(bào)軌跡線,根據(jù)臺風(fēng)類型繪制成不同顏色
  • 當(dāng)前正在發(fā)生的臺風(fēng)還需增加當(dāng)前臺風(fēng)所風(fēng)圈位置
  • 臺風(fēng)軌跡點(diǎn)點(diǎn)擊彈框顯示軌跡點(diǎn)信息

openlayers(簡稱ol)這里不做介紹,剛開始寫此類文章,直接上代碼

創(chuàng)建一個(gè)地圖容器

引入地圖相關(guān)對象

import Map from 'ol/Map';
import View from 'ol/View';
import XYZ from 'ol/source/XYZ';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';

創(chuàng)建地圖對象

都是一些基本活

const center = [-5639523.95, -3501274.52];
const map = new Map({
  target: document.getElementById('map'),
  view: new View({
    center: center,
    zoom: 10,
    minZoom: 2,
    maxZoom: 19,
  }),
  layers: [ ],
});
this.addEventMapClick()

監(jiān)聽地圖點(diǎn)擊事件

 addEventMapClick () {
    const nameDom = document.createElement('div')
    nameDom.setAttribute('class', 'typhoon-popup')
    const nameOverlay = new ol.Overlay({
      element: nameDom,
      position: [0, 0],
      positioning: 'right-center',
      stopEvent: false,
      insertFirst: false,
      autoPanAnimation: {
        duration: 250
      }
    })
    this.viewer.addOverlay(nameOverlay)
    this._popup = nameOverlay
    // 監(jiān)聽地圖點(diǎn)擊事件
    this.viewer.on('singleclick', e => {
      this._popup.getElement().parentElement.style.display = 'none'
      this.viewer.forEachFeatureAtPixel(
        e.pixel,
        (result) => {
          if (result) {
            let Properties = result.get('properties')
            let layerType = result.get('layerType')
            // 臺風(fēng)點(diǎn)點(diǎn)擊
            // && layerType === 'typhoonpoint'
            if (layerType === 'typhoonLyer') {
              let html = `<div class="typhoonLyer"><div class="con">名稱: ${Properties.CODE || ''} ${Properties.NAME_CN || ''} ${Properties.NAME_EN || ''}</div>
              <div class="con">風(fēng)速: ${Properties.MOVE_SPEED || '--'} km/h</div>
              <div class="con">中心氣壓: ${Properties.PRESS || '--'}</div>
              <div class="con">時(shí)間: ${Properties.time || '--'}</div>
              <div class="con">中心位置: ${Properties.LON}/${Properties.LAT}</div></div>`
              this._popup.getElement().innerHTML = html
              this._popup.setPosition([Properties.LON, Properties.LAT])
              // this._popup.setOffset([25, 0])
              this._popup.getElement().parentElement.style.display = 'block'
            } else {
              this._popup.getElement().parentElement.style.display = 'none'
            }
          }
        }
      )
    })
  }

開始繪制

準(zhǔn)備臺風(fēng)數(shù)據(jù)和圖層

臺風(fēng)數(shù)據(jù)我是用的JSON。這里就簡單描述一下數(shù)據(jù)中只要用到的字段信息

[
      {
        CODE: "202122",//臺風(fēng)編號
        DB7: null,//七級東北
        DB10: null,//十級東北
        DB12: null,//十二級東北
        DN7: null,//七級東南
        DN10: null,//十級東南
        DN12: null,//十二級東南
        LAT: 5.5,//維度
        LON: 140.9,//經(jīng)度
        MOVE_DIR: null,//風(fēng)向
        MOVE_SPEED: null,//風(fēng)向速度
        OBJECTID: 27848,//id
        PRESS: 998,//中心氣壓
        SHIJIAN: null,
        STRENGTH: "臺風(fēng)(熱帶風(fēng)暴級)",//強(qiáng)度
        TH: null,
        TIME: "2021-12-13-14",//日期
        WIND: 18,//最大風(fēng)速
        XB7: null,//七級西北
        XB10: null,//十級西北
        XB12: null,//十二級西北
        XN7: null,//七級西南
        XN10: null,//十級西南
        XN12: null,//十二級西南
      },
   ]
  let tfsource = new ol.source.Vector({
      crossOrigin: 'anonymous',
      features: []
    })
    let tflayer = new ol.layer.Vector({
      source: tfsource
    })
   map.addLayer(tflayer)

繪制臺風(fēng)名稱

// 利用第一個(gè)點(diǎn) 創(chuàng)建名稱Overlay層 顯示臺風(fēng)名稱
 const nameDom = document.createElement('div')
    nameDom.setAttribute('class', 'typhoon-name-panel')
    nameDom.classList.add(lx)
    nameDom.innerHTML = label
    const position = [point.LON, point.LAT]
    const nameOverlay = new ol.Overlay({
      element: nameDom,
      position: position,
      wz: position,
      positioning: 'center-left',
      offset: [15, 0]
    })
    map.addOverlay(nameOverlay)
    map.getView().setCenter(position)

繪制臺風(fēng)軌跡點(diǎn)和軌跡線

    //point 為數(shù)組對象中每一個(gè)點(diǎn)數(shù)據(jù)
    // 點(diǎn)顏色 根據(jù)強(qiáng)度區(qū)分不同點(diǎn)的顏色
    let pointColor = this.setPointFillColor(point.STRENGTH)
    // 添加點(diǎn)
    if (point.LON &amp;&amp; point.LAT) {
      const feature = new ol.Feature({
        geometry: new ol.geom.Point([point.LON, point.LAT]),
        layerType: 'typhoonLyer',
        properties: point
      })
      // this.tfStyle為我提前定義到的各種類型的點(diǎn)樣式
      feature.setStyle(this.tfStyle[pointColor.index])
     tflayer.getSource().addFeature(feature)
    }
  // 添加線
  let startPoint = [point.LON, point.LAT] 開始點(diǎn)
  let endPonit = [points[index - 1].LON, points[index - 1].LAT] 結(jié)束點(diǎn)
  let coords = [startPoint, endPonit]
  let lineDash 線段樣式 實(shí)線或者虛線
  if (lx !== 'ss') {
    lineDash = [0]
  } else {
    lineDash = (!point.predict &amp;&amp; !points[index - 1].predict) ? [0] : [10]
  }
// this.tfLinStyle 為提前定義好的線段樣式
  let lineStyle = lineDash[0] === 0 ? this.tfLinStyle[pointColor.index] : this.tfLinStyle[6]
  let feature = new ol.Feature({
    geometry: new ol.geom.LineString(coords),
    layerType: 'typhoonLyer',
    properties: point
  })
  feature.setStyle(lineStyle)
  tflayer.getSource().addFeature(feature)

代碼解析 文中提到的this.tfLinStyle 和 this.tfStyle 為提前定義好的點(diǎn)和線的樣式,這么做的目的是為了提高性能,減少oplayer中new 一堆重復(fù)性的樣式堆棧,消耗內(nèi)存

this.tfStyle = [
      new ol.style.Style({
        image: new ol.style.Circle({
          radius: 6,
          fill: new ol.style.Fill({
            color: '#eed139'
          }),
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.6)',
            width: 1
          })
        })
      }),
      new ol.style.Style({
        image: new ol.style.Circle({
          radius: 6,
          fill: new ol.style.Fill({
            color: '#0000ff'
          }),
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.6)',
            width: 1
          })
        })
      }),
      new ol.style.Style({
        image: new ol.style.Circle({
          radius: 6,
          fill: new ol.style.Fill({
            color: '#0f8000'
          }),
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.6)',
            width: 1
          })
        })
      }),
      new ol.style.Style({
        image: new ol.style.Circle({
          radius: 6,
          fill: new ol.style.Fill({
            color: '#fe9c45'
          }),
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.6)',
            width: 1
          })
        })
      }),
      new ol.style.Style({
        image: new ol.style.Circle({
          radius: 6,
          fill: new ol.style.Fill({
            color: '#fe00fe'
          }),
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.6)',
            width: 1
          })
        })
      }),
      new ol.style.Style({
        image: new ol.style.Circle({
          radius: 6,
          fill: new ol.style.Fill({
            color: '#fe0000'
          }),
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.6)',
            width: 1
          })
        })
      })
    ]
    this.tfLinStyle = [
      new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: '#eed139',
          width: 2,
          lineDash: [0]
        })
      }),
      new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: '#0000ff',
          width: 2,
          lineDash: [0]
        })
      }),
      new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: '#0f8000',
          width: 2,
          lineDash: [0]
        })
      }),
      new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: '#fe9c45',
          width: 2,
          lineDash: [0]
        })
      }),
      new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: '#fe00fe',
          width: 2,
          lineDash: [0]
        })
      }),
      new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: '#fe0000',
          width: 2,
          lineDash: [0]
        })
      }),
      new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: '#fe0000',
          width: 2,
          lineDash: [10]
        })
      })]

setPointFillColor函數(shù)判別點(diǎn)類型

setPointFillColor (type) {
    let pointFillColor = '#eed139'
    let index = 0
    switch (type) {
      case '臺風(fēng)(熱帶低壓)':
      case '熱帶低壓':
        pointFillColor = '#eed139'
        index = 0
        break
      case '熱帶風(fēng)暴':
      case '熱帶風(fēng)暴級':
      case '臺風(fēng)(熱帶風(fēng)暴)':
      case '臺風(fēng)(熱帶風(fēng)暴級)':
        pointFillColor = '#0000ff'
        index = 1
        break
      case '臺風(fēng)(強(qiáng)熱帶風(fēng)暴級)':
      case '強(qiáng)熱帶風(fēng)暴級':
      case '強(qiáng)熱帶風(fēng)暴':
        pointFillColor = '#0f8000'
        index = 2
        break
      case '臺風(fēng)':
        pointFillColor = '#fe9c45'
        index = 3
        break
      case '強(qiáng)臺風(fēng)':
      case '臺風(fēng)(強(qiáng)臺風(fēng)級)':
      case '臺風(fēng)(強(qiáng)臺風(fēng))':
        pointFillColor = '#fe00fe'
        index = 4
        break
      case '超強(qiáng)臺風(fēng)':
      case '臺風(fēng)(超強(qiáng)臺風(fēng)級)':
      case '臺風(fēng)(超強(qiáng)臺風(fēng))':
        pointFillColor = '#fe0000'
        index = 5
        break
    }
    return {pointFillColor, index}
  }

以上代碼很完整,我加了注釋,整體思路總結(jié)如下:

  • 先獲取臺風(fēng)數(shù)據(jù)
  • 構(gòu)造臺風(fēng)軌跡圖層并添加到地圖容器
  • 循環(huán)構(gòu)造點(diǎn)、線及名稱要素對象 添加到臺風(fēng)圖層數(shù)據(jù)源中
  • 添加風(fēng)圈動畫

添加臺風(fēng)風(fēng)圈動畫

根據(jù)判斷臺風(fēng)類型是否是實(shí)時(shí)臺風(fēng)還是歷史臺風(fēng)進(jìn)行添加臺風(fēng)風(fēng)圈,在數(shù)據(jù)中獲取到最后一個(gè)實(shí)時(shí)點(diǎn)位數(shù)據(jù),利用Overlay添加一個(gè)動態(tài)圖標(biāo),我是利用的gif圖片

    let key = LX + '-' + tfbh
    const points = this._typhoonData[key].point
    let fqindex = points.findIndex(item => !item.predict)
    // 添加風(fēng)圈
    if (fqindex) {
      const nameDom = document.createElement('div')
      nameDom.setAttribute('class', 'typhoon-area')
      let nameOverlay = new ol.Overlay({
        position: [points[fqindex].LON, points[fqindex].LAT],
        positioning: 'center-bottom',
        element: nameDom, // 綁定上面添加的元素
        stopEvent: false,
        offset: [-15, -15]// 圖片偏移量
      })
      this.viewer.addOverlay(nameOverlay)
      this._tfenterCollection[key]['areaoverlay'] = nameOverlay
    }

讓臺風(fēng)軌跡動起來

加載的時(shí)候利用定時(shí)器,一個(gè)點(diǎn)位一個(gè)點(diǎn)位的繪制,這樣看起來就有動畫效果啦

 this._typhoonPlayFlag[key] = setInterval(() => {
      去干些事請
    }, 50)

結(jié)尾

這里我只是大致的描述了我繪制臺風(fēng)軌跡的一些思路和大致方法,具體項(xiàng)目中,我把整個(gè)過場都封裝成一個(gè)class 類,畢竟臺風(fēng)可能是有多條的,而且還需要做一些顯示隱藏等的一些操作,我這里不做過多描述,僅做為一些思路分享,更多關(guān)于vue openlayers臺風(fēng)軌跡的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue3+vite項(xiàng)目H5配置適配步驟詳解

    vue3+vite項(xiàng)目H5配置適配步驟詳解

    這篇文章主要為大家介紹了vue3+vite項(xiàng)目H5配置適配步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Vue組件文檔生成工具庫的方法

    Vue組件文檔生成工具庫的方法

    本文主要介紹了Vue組件文檔生成工具庫的方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • vue實(shí)現(xiàn)引入本地json的方法分析

    vue實(shí)現(xiàn)引入本地json的方法分析

    這篇文章主要介紹了vue實(shí)現(xiàn)引入本地json的方法,結(jié)合實(shí)例形式分析了vue.js加載本地json文件及解析json數(shù)據(jù)相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • vue刷新后瞬間閃爍,無法解析的問題

    vue刷新后瞬間閃爍,無法解析的問題

    這篇文章主要介紹了vue刷新后瞬間閃爍,無法解析的問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 記一次微信小程序與webviewH5通信的踩坑記錄

    記一次微信小程序與webviewH5通信的踩坑記錄

    uniapp開發(fā)小程序的過程中主、分包有大小限制,隨著業(yè)務(wù)的增加,使用web-view加載H5的方式,往往純加載并不能滿足業(yè)務(wù)需求,這個(gè)時(shí)候就得了解小程序與H5的交互,這篇文章主要給大家介紹了關(guān)于微信小程序與webviewH5通信的踩坑記錄,需要的朋友可以參考下
    2024-07-07
  • vue3組件銷毀的具體實(shí)現(xiàn)

    vue3組件銷毀的具體實(shí)現(xiàn)

    組件的銷毀意味著從 DOM 中移除該組件,并清除與之相關(guān)的所有事件監(jiān)聽器和子組件,本文主要介紹了vue3組件銷毀的具體實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-08-08
  • 詳解vue-router基本使用

    詳解vue-router基本使用

    本篇文章主要介紹了詳解vue-router基本使用,詳細(xì)的介紹了vue-router的概念和用法,有興趣的可以了解一下。
    2017-04-04
  • vue3?中v-model語法糖示例詳解

    vue3?中v-model語法糖示例詳解

    vue3中的v-model相當(dāng)于vue2中的v-model和v-bind.sync 修飾符組合在一起的產(chǎn)物(擇優(yōu)整合)v-bind.sync 在 vue3 中被移除了可以在組件標(biāo)簽上使用多個(gè) v-model 綁定屬性,使用參數(shù)區(qū)分,這篇文章主要介紹了vue3?中v-model語法糖,需要的朋友可以參考下
    2024-06-06
  • Vue3+Element+Ts實(shí)現(xiàn)表單的基礎(chǔ)搜索重置等功能

    Vue3+Element+Ts實(shí)現(xiàn)表單的基礎(chǔ)搜索重置等功能

    本文主要介紹了Vue3+Element+Ts實(shí)現(xiàn)表單的基礎(chǔ)搜索重置等功能,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 源碼分析Vue.js的監(jiān)聽實(shí)現(xiàn)教程

    源碼分析Vue.js的監(jiān)聽實(shí)現(xiàn)教程

    這篇文章主要通過源碼分析介紹了Vue.js的監(jiān)聽實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),相信對大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-04-04

最新評論