echarts symbol 回调函数_【OpenLayer 实战】实现仿Echarts风格的动态迁徙图/航班图
使用的數(shù)據(jù)還是來自echarts,模擬了全國各地到湖南重點景區(qū)的客流情況。
分析
要實現(xiàn)動態(tài)遷徙圖的效果,主要需解決兩個問題
??? 曲線的繪制。因為給出的數(shù)據(jù)只有起點和終點兩個點位,所以想要繪制曲線可以參考turf中的bezier曲線生成API。
??? 點跡的動畫播放。仍然要依靠render機制,這里我還是使用比較熟悉的postrender事件回調(diào)函數(shù)。
實現(xiàn)
首先利用turf做一個利用兩個點就可以生成弧線要素的函數(shù),其實這里面調(diào)用的是turf的bezierSpline,寫死了一個定比例取到的點位,參數(shù)列表為要素的自定義屬性留了位置。同時在函數(shù)里計算出曲線的長度待用。?
然后重點分析一下點位動畫的實現(xiàn):
先寫出監(jiān)聽postrender事件回調(diào)函數(shù)的基本框架,并取得VectorContex對象的句柄:
tileLayer.on('postrender', (evt) => { let veContext = getVectorContext(evt); })再寫出遍歷所有曲線的forEach結(jié)構(gòu)及回調(diào)函數(shù),回調(diào)函數(shù)內(nèi)先將本次迭代的曲線繪制到地圖上:
tileLayer.on('postrender', (evt) => { let veContext = getVectorContext(evt); arcLinesFeature.forEach((item,index) => { veContext.drawFeature(item, arcStyle); }) })然后通過frameState獲取當(dāng)前幀的時間戳,計算得到當(dāng)前幀運動點位的位置百分比,如果百分比超過100%還要進(jìn)行歸零處理
tileLayer.on('postrender', (evt) => { let veContext = getVectorContext(evt); arcLinesFeature.forEach((item,index) => { veContext.drawFeature(item, arcStyle); let time = (evt.frameState.time - item.get('start')) / 1000; let frac = time / 5-index/arcLinesFeature.length; if (!item.get('start')) item.set('start', new Date().getTime()); if (frac>=1) { item.set('start', new Date().getTime()); frac=0; } }) })最后根據(jù)位置百分比,使用getCoordinateAt求得點位的坐標(biāo),并且使用VectorContex對象繪制到canvas上,然后顯示調(diào)用render()函數(shù),請求渲染下一幀。
tileLayer.on('postrender', (evt) => { let veContext = getVectorContext(evt); arcLinesFeature.forEach((item,index) => { veContext.drawFeature(item, arcStyle); let time = (evt.frameState.time - item.get('start')) / 1000; let frac = time / 5-index/arcLinesFeature.length; if (!item.get('start')) item.set('start', new Date().getTime()); if (frac>=1) { item.set('start', new Date().getTime()); frac=0; } let along = item.getGeometry().getCoordinateAt(frac); let pF=new Feature(new Point(along)); veContext.drawFeature(pF, dotStyle); }) map.render()})完整代碼
(刪掉了我自己的Google開發(fā)者Key,黑色主題地圖還請自己動手做一個)
import { Map, View } from 'ol';import TileLayer from 'ol/layer/Tile';import XYZ from 'ol/source/XYZ';import Point from 'ol/geom/Point';import VectorSource from 'ol/source/Vector';import VectorLayer from 'ol/layer/Vector';import Feature from 'ol/Feature';import * as turf from '@turf/turf'import GeoJSON from 'ol/format/GeoJSON'import { getVectorContext } from 'ol/render';import Style from 'ol/style/Style';import Stroke from 'ol/style/Stroke';import Fill from 'ol/style/Fill';import CircleStyle from 'ol/style/Circle';import data from './data/t.json' let tileLayer = new TileLayer({ source: new XYZ({ url: 'http://www.google.cn/maps/vt?pb=!1m5!1m4!1i{z}!2i{x}!3i{y}!4i256!2m3!1e0!2sm!3i451159038!3m14!2szh-CN!3sUS!5e18!12m1!1e68!12m3!1e37!2m1!1ssmartmaps!12m4!1e26!2m2!1sstyles!2zcC5oOiNmZjFhMDB8cC5pbDp0cnVlfHAuczotMTAwfHAubDozM3xwLmc6MC41LHMudDo2fHMuZTpnfHAuYzojZmYyRDMzM0M!4e0&key=&token=126219' })})let map = new Map({ target: 'map', layers: [ tileLayer ], view: new View({ center: [11936406.337013, 3786384.633134], zoom: 5 })}); var flightSource = new VectorSource()var flightLayer = new VectorLayer( { source: flightSource })var turfFormat = new GeoJSON(); function getTurfArcFeature(start, end, opt) { var line = turf.lineString([ start, [start[0] + (end[0] - start[0]) * 0.5, start[1] + (end[1] - start[1]) * 0.65], end ]); var curved = turf.bezierSpline(line); let length = turf.length(curved, { units: 'meters' }); var bF = turfFormat.readFeature(curved); bF.getGeometry().transform('EPSG:4326', 'EPSG:3857'); bF.setProperties(opt); bF.set("length", length); return bF;} map.addLayer(flightLayer) var arcStyle = new Style({ stroke: new Stroke({ color: [0, 122, 122, 0.7], width: 1 })}) var dotStyle = new Style({ image: new CircleStyle({ fill: new Fill({ color: [255, 255, 255,0.7] }), radius: 1 })}) var arcLinesFeature = [];data.moveLines.forEach((item, index) => { let tempF = getTurfArcFeature(item.coords[0], item.coords[1], { 'from': item.fromName, 'to': item.toName }); arcLinesFeature.push(tempF);}) tileLayer.on('postrender', (evt) => { let veContext = getVectorContext(evt); arcLinesFeature.forEach((item,index) => { veContext.drawFeature(item, arcStyle); let time = (evt.frameState.time - item.get('start')) / 1000; let frac = time / 5-index/arcLinesFeature.length; if (!item.get('start')) item.set('start', new Date().getTime()); if (frac>=1) { item.set('start', new Date().getTime()); frac=0; } let along = item.getGeometry().getCoordinateAt(frac); let pF=new Feature(new Point(along)); veContext.drawFeature(pF, dotStyle); }) map.render()})【OpenLayers】OpenLayers概述
【OpenLayers】實現(xiàn)簡單的地圖顯示
【OpenLayers】地圖控件之縮放控件
【OpenLayers】歸屬控件與全屏控件
【OpenLayers】地圖控件之坐標(biāo)拾取控件和鷹眼控件
【OpenLayers】地圖控件之旋轉(zhuǎn)控件與比例尺控件
【OpenLayers】實現(xiàn)圖層切換控件
【OpenLayers】多源數(shù)據(jù)加載之?dāng)?shù)據(jù)組織
【OpenLayers】多源數(shù)據(jù)加載之瓦片地圖原理一
【OpenLayers】多源數(shù)據(jù)加載之瓦片地圖原理二
【OpenLayers】多源數(shù)據(jù)加載之用最簡單的方式加載瓦片地圖
【OpenLayers】多源數(shù)據(jù)加載之使用XYZ的方式加載瓦片地圖
【OpenLayers】多源數(shù)據(jù)加載之詳解OpenLayers的瓦片坐標(biāo)系
【OpenLayers】多源數(shù)據(jù)加載之離線瓦片地圖
【OpenLayers】多源數(shù)據(jù)加載之矢量地圖
【OpenLayers】多源數(shù)據(jù)加載之WMS(一)
【OpenLayers】多源數(shù)據(jù)加載之WMS(二)
【OpenLayers】多源數(shù)據(jù)加載之矢量切片
【OpenLayers】多源數(shù)據(jù)加載之WMTS
【OpenLayers】圖形繪制之設(shè)置圖形的樣式
【OpenLayers】圖形繪制之編輯圖形
【OpenLayers】使用GeoJSON數(shù)據(jù)渲染熱力圖
【OpenLayers】實現(xiàn)“上一視圖”、“下一視圖”的視圖切換功能
【OpenLayers】圖文標(biāo)注
【OpenLayers】聚合標(biāo)注
【OpenLayers】圖層卷簾(Layer Swipe)
【OpenLayers】Drag-and-Drop Image Vector
【OpenLayer 實戰(zhàn)】實現(xiàn)克里金插值渲染圖-Kriging
【OpenLayer 實戰(zhàn)】請求Geoserver帶Filter的WFS查詢
【OpenLayer 實戰(zhàn)】使用GeoJSON進(jìn)行行政區(qū)劃剪裁(clip, not mask or filter)
END
?請:右下點在看,右上點【···】分享
關(guān)注我
發(fā)現(xiàn)更多精彩
總結(jié)
以上是生活随笔為你收集整理的echarts symbol 回调函数_【OpenLayer 实战】实现仿Echarts风格的动态迁徙图/航班图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 炒菜机器人放食材的顺序_珠江新城有了首家
- 下一篇: linux 内核io操作,关于Linux