最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

功能描述

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

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

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

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

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)建地圖對(duì)象

都是一些基本活

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')
            // 臺(tái)風(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)備臺(tái)風(fēng)數(shù)據(jù)和圖層

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

[
      {
        CODE: "202122",//臺(tái)風(fēng)編號(hào)
        DB7: null,//七級(jí)東北
        DB10: null,//十級(jí)東北
        DB12: null,//十二級(jí)東北
        DN7: null,//七級(jí)東南
        DN10: null,//十級(jí)東南
        DN12: null,//十二級(jí)東南
        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: "臺(tái)風(fēng)(熱帶風(fēng)暴級(jí))",//強(qiáng)度
        TH: null,
        TIME: "2021-12-13-14",//日期
        WIND: 18,//最大風(fēng)速
        XB7: null,//七級(jí)西北
        XB10: null,//十級(jí)西北
        XB12: null,//十二級(jí)西北
        XN7: null,//七級(jí)西南
        XN10: null,//十級(jí)西南
        XN12: null,//十二級(jí)西南
      },
   ]
  let tfsource = new ol.source.Vector({
      crossOrigin: 'anonymous',
      features: []
    })
    let tflayer = new ol.layer.Vector({
      source: tfsource
    })
   map.addLayer(tflayer)

繪制臺(tái)風(fēng)名稱

// 利用第一個(gè)點(diǎn) 創(chuàng)建名稱Overlay層 顯示臺(tái)風(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)

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

    //point 為數(shù)組對(duì)象中每一個(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 '臺(tái)風(fēng)(熱帶低壓)':
      case '熱帶低壓':
        pointFillColor = '#eed139'
        index = 0
        break
      case '熱帶風(fēng)暴':
      case '熱帶風(fēng)暴級(jí)':
      case '臺(tái)風(fēng)(熱帶風(fēng)暴)':
      case '臺(tái)風(fēng)(熱帶風(fēng)暴級(jí))':
        pointFillColor = '#0000ff'
        index = 1
        break
      case '臺(tái)風(fēng)(強(qiáng)熱帶風(fēng)暴級(jí))':
      case '強(qiáng)熱帶風(fēng)暴級(jí)':
      case '強(qiáng)熱帶風(fēng)暴':
        pointFillColor = '#0f8000'
        index = 2
        break
      case '臺(tái)風(fēng)':
        pointFillColor = '#fe9c45'
        index = 3
        break
      case '強(qiáng)臺(tái)風(fēng)':
      case '臺(tái)風(fēng)(強(qiáng)臺(tái)風(fēng)級(jí))':
      case '臺(tái)風(fēng)(強(qiáng)臺(tái)風(fēng))':
        pointFillColor = '#fe00fe'
        index = 4
        break
      case '超強(qiáng)臺(tái)風(fēng)':
      case '臺(tái)風(fēng)(超強(qiáng)臺(tái)風(fēng)級(jí))':
      case '臺(tái)風(fēng)(超強(qiáng)臺(tái)風(fēng))':
        pointFillColor = '#fe0000'
        index = 5
        break
    }
    return {pointFillColor, index}
  }

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

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

添加臺(tái)風(fēng)風(fēng)圈動(dòng)畫

根據(jù)判斷臺(tái)風(fēng)類型是否是實(shí)時(shí)臺(tái)風(fēng)還是歷史臺(tái)風(fēng)進(jìn)行添加臺(tái)風(fēng)風(fēng)圈,在數(shù)據(jù)中獲取到最后一個(gè)實(shí)時(shí)點(diǎn)位數(shù)據(jù),利用Overlay添加一個(gè)動(dòng)態(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
    }

讓臺(tái)風(fēng)軌跡動(dòng)起來

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

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

結(jié)尾

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

相關(guān)文章

  • vue3原始值響應(yīng)方案及響應(yīng)丟失問題解讀

    vue3原始值響應(yīng)方案及響應(yīng)丟失問題解讀

    這篇文章主要介紹了vue3原始值響應(yīng)方案及響應(yīng)丟失問題解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Vue數(shù)字輸入框組件使用方法詳解

    Vue數(shù)字輸入框組件使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了Vue數(shù)字輸入框組件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • vuex中能直接修改state嗎

    vuex中能直接修改state嗎

    當(dāng)我們使用vuex的時(shí)候,時(shí)不時(shí)能看到“更改Vuex中的store中的狀態(tài)唯一辦法就是提交mutations”,但是有沒有試想過,我們不提交mutations其實(shí)也能修改state的值?答案是可以的,下面通過本文介紹下vuex修改state值的方法,感興趣的朋友一起看看吧
    2022-11-11
  • 詳解axios 全攻略之基本介紹與使用(GET 與 POST)

    詳解axios 全攻略之基本介紹與使用(GET 與 POST)

    本篇文章主要介紹了axios 全攻略之基本介紹與使用(GET 與 POST),詳細(xì)的介紹了axios的安裝和使用,還有 GET 與 POST方法,有興趣的可以了解一下
    2017-09-09
  • 超詳細(xì)動(dòng)手搭建一個(gè)VuePress 站點(diǎn)及開啟PWA與自動(dòng)部署的方法

    超詳細(xì)動(dòng)手搭建一個(gè)VuePress 站點(diǎn)及開啟PWA與自動(dòng)部署的方法

    這篇文章主要介紹了超詳細(xì)動(dòng)手搭建一個(gè)VuePress 站點(diǎn)及開啟PWA與自動(dòng)部署的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • Vue3使用transition組件改變DOM屬性的方式小結(jié)

    Vue3使用transition組件改變DOM屬性的方式小結(jié)

    這篇文章主要為大家詳細(xì)介紹了Vue3中使用transition組件改變DOM屬性的常用方式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • Vue.js如何監(jiān)聽window窗口尺寸變化

    Vue.js如何監(jiān)聽window窗口尺寸變化

    使用VUE開發(fā)后臺(tái)項(xiàng)目,后臺(tái)項(xiàng)目需要進(jìn)行后臺(tái)根據(jù)瀏覽器窗口進(jìn)行變化,需要使用vue來監(jiān)聽瀏覽器的窗口變化,這篇文章主要給大家介紹了關(guān)于Vue.js如何監(jiān)聽window窗口尺寸變化的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • vue自定義組件實(shí)現(xiàn)雙向綁定

    vue自定義組件實(shí)現(xiàn)雙向綁定

    這篇文章主要為大家詳細(xì)介紹了vue自定義組件實(shí)現(xiàn)雙向綁定,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • vue實(shí)現(xiàn)打印功能的示例代碼

    vue實(shí)現(xiàn)打印功能的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何通過vue實(shí)現(xiàn)打印功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • vue實(shí)現(xiàn)動(dòng)態(tài)表單動(dòng)態(tài)渲染組件的方式(2)

    vue實(shí)現(xiàn)動(dòng)態(tài)表單動(dòng)態(tài)渲染組件的方式(2)

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)動(dòng)態(tài)表單動(dòng)態(tài)渲染組件的方式第二篇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04

最新評(píng)論

东平县| 县级市| 普安县| 阜南县| 大厂| 巴青县| 类乌齐县| 黔西| 哈尔滨市| 南川市| 楚雄市| 义乌市| 大埔县| 梅州市| 北海市| 碌曲县| 理塘县| 常熟市| 墨竹工卡县| 白水县| 梓潼县| 东港市| 简阳市| 淮南市| 西安市| 东光县| 柳江县| 台北市| 蚌埠市| 齐齐哈尔市| 河池市| 盐津县| 琼结县| 莱芜市| 定远县| 亳州市| 鹿泉市| 南木林县| 寻甸| 惠东县| 台中县|