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

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

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

功能描述

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

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

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

引入地圖相關(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)聽地圖點擊事件

 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)聽地圖點擊事件
    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)點點擊
            // && 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">時間: ${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)名稱

// 利用第一個點 創(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)軌跡點和軌跡線

    //point 為數(shù)組對象中每一個點數(shù)據(jù)
    // 點顏色 根據(jù)強(qiáng)度區(qū)分不同點的顏色
    let pointColor = this.setPointFillColor(point.STRENGTH)
    // 添加點
    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為我提前定義到的各種類型的點樣式
      feature.setStyle(this.tfStyle[pointColor.index])
     tflayer.getSource().addFeature(feature)
    }
  // 添加線
  let startPoint = [point.LON, point.LAT] 開始點
  let endPonit = [points[index - 1].LON, points[index - 1].LAT] 結(jié)束點
  let coords = [startPoint, endPonit]
  let lineDash 線段樣式 實線或者虛線
  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 為提前定義好的點和線的樣式,這么做的目的是為了提高性能,減少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ù)判別點類型

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)造點、線及名稱要素對象 添加到臺風(fēng)圖層數(shù)據(jù)源中
  • 添加風(fēng)圈動畫

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

根據(jù)判斷臺風(fēng)類型是否是實時臺風(fēng)還是歷史臺風(fēng)進(jìn)行添加臺風(fēng)風(fēng)圈,在數(shù)據(jù)中獲取到最后一個實時點位數(shù)據(jù),利用Overlay添加一個動態(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)軌跡動起來

加載的時候利用定時器,一個點位一個點位的繪制,這樣看起來就有動畫效果啦

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

結(jié)尾

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

相關(guān)文章

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

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

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

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

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

    vuex中能直接修改state嗎

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

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

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

    超詳細(xì)動手搭建一個VuePress 站點及開啟PWA與自動部署的方法

    這篇文章主要介紹了超詳細(xì)動手搭建一個VuePress 站點及開啟PWA與自動部署的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    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ā)后臺項目,后臺項目需要進(jìn)行后臺根據(jù)瀏覽器窗口進(jìn)行變化,需要使用vue來監(jiān)聽瀏覽器的窗口變化,這篇文章主要給大家介紹了關(guān)于Vue.js如何監(jiān)聽window窗口尺寸變化的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • vue自定義組件實現(xiàn)雙向綁定

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

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

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

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

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

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

最新評論

布尔津县| 斗六市| 达日县| 精河县| 永兴县| 长岭县| 股票| 邵东县| 阿拉善盟| 华蓥市| 沧源| 江山市| 祁阳县| 澜沧| 崇仁县| 深泽县| 无锡市| 江西省| 阳西县| 健康| 象山县| 东平县| 汉寿县| 邻水| 洛南县| 兴海县| 清原| 阜新| 彭阳县| 文水县| 彰武县| 沁水县| 秦皇岛市| 沾化县| 涟源市| 库车县| 喀什市| 改则县| 大埔县| 中江县| 将乐县|