使用的数据还是来自echarts,模拟了全国各地到湖南重点景区的客流情况。

分析
要实现动态迁徙图的效果,主要需解决两个问题
    曲线的绘制。因为给出的数据只有起点和终点两个点位,所以想要绘制曲线可以参考turf中的bezier曲线生成API。
    点迹的动画播放。仍然要依靠render机制,这里我还是使用比较熟悉的postrender事件回调函数。
实现
首先利用turf做一个利用两个点就可以生成弧线要素的函数,其实这里面调用的是turf的bezierSpline,写死了一个定比例取到的点位,参数列表为要素的自定义属性留了位置。同时在函数里计算出曲线的长度待用。

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;}

然后重点分析一下点位动画的实现:

先写出监听postrender事件回调函数的基本框架,并取得VectorContex对象的句柄:

tileLayer.on('postrender', (evt) => {  let veContext = getVectorContext(evt);  })

再写出遍历所有曲线的forEach结构及回调函数,回调函数内先将本次迭代的曲线绘制到地图上:

tileLayer.on('postrender', (evt) => {  let veContext = getVectorContext(evt);   arcLinesFeature.forEach((item,index) => {    veContext.drawFeature(item, arcStyle);   })  })

然后通过frameState获取当前帧的时间戳,计算得到当前帧运动点位的位置百分比,如果百分比超过100%还要进行归零处理

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;    }      }) })

最后根据位置百分比,使用getCoordinateAt求得点位的坐标,并且使用VectorContex对象绘制到canvas上,然后显示调用render()函数,请求渲染下一帧。

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开发者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】实现简单的地图显示

【OpenLayers】地图控件之缩放控件

【OpenLayers】归属控件与全屏控件

【OpenLayers】地图控件之坐标拾取控件和鹰眼控件

【OpenLayers】地图控件之旋转控件与比例尺控件

【OpenLayers】实现图层切换控件

【OpenLayers】多源数据加载之数据组织

【OpenLayers】多源数据加载之瓦片地图原理一

【OpenLayers】多源数据加载之瓦片地图原理二

【OpenLayers】多源数据加载之用最简单的方式加载瓦片地图

【OpenLayers】多源数据加载之使用XYZ的方式加载瓦片地图

【OpenLayers】多源数据加载之详解OpenLayers的瓦片坐标系

【OpenLayers】多源数据加载之离线瓦片地图

【OpenLayers】多源数据加载之矢量地图

【OpenLayers】多源数据加载之WMS(一)

【OpenLayers】多源数据加载之WMS(二)

【OpenLayers】多源数据加载之矢量切片

【OpenLayers】多源数据加载之WMTS

【OpenLayers】图形绘制之设置图形的样式

【OpenLayers】图形绘制之编辑图形

【OpenLayers】使用GeoJSON数据渲染热力图

【OpenLayers】实现“上一视图”、“下一视图”的视图切换功能

【OpenLayers】图文标注

【OpenLayers】聚合标注

【OpenLayers】图层卷帘(Layer Swipe)

【OpenLayers】Drag-and-Drop Image Vector

【OpenLayer 实战】实现克里金插值渲染图-Kriging

【OpenLayer 实战】请求Geoserver带Filter的WFS查询

【OpenLayer 实战】使用GeoJSON进行行政区划剪裁(clip, not mask or filter)

END

请:右下点在看,右上点【···】分享

关注我

发现更多精彩

echarts symbol 回调函数_【OpenLayer 实战】实现仿Echarts风格的动态迁徙图/航班图相关推荐

  1. echarts symbol 回调函数_凹函数和凸函数到底什么样?傻傻分不清楚

    函数的凹(concave)凸(convex)性是比较重要的概念.你有没有在读书时,突然发现自己脑海中认定的凹函数被书上说成是凸的,然后自我怀疑,哪里错了呢? 其实不一定是你的错,因为不同书的术语不太一 ...

  2. ajax调用外域接口不进回调函数_网易实战分享云信IM SDK接口设计实践

    文|陈吉力 网易智慧企业高级Android开发工程师 对外接口的设计准则 SDK对外提供接口设计的基本原则是易用,易懂,易扩展,易监控.展开来可归纳为以下几个特性: 1. API按照业务功能分类,但所 ...

  3. 回调函数_实用程序类与函数式编程无关

    回调函数 最近,我被指控反对函数式编程,因为我将实用程序类称为反模式. 绝对是错的! 好吧,我确实认为它们是一种糟糕的反模式,但是它们与函数式编程无关. 我相信有两个基本原因. 首先,函数式编程是声明 ...

  4. python mount回调函数_为python回调函数设置argtype

    我对Python很在行,所以希望我能正确地表达这个问题.在 整个问题涉及从Python调用C例程.我可以通过把一些相关的问题/答案凑在一起来接近,但我似乎不能把事情安排得很好.有两个方面:第一个是用指 ...

  5. java中钩子函数回调函数_钩子函数 和回调函数

    标签: http://blog.csdn.net/lipeionline/article/details/6369657  转自 也可以这样,更容易理解:回调函数就好像是一个中断处理函数,系统在符合你 ...

  6. python ctypes 回调函数_如何用Python中的ctypes创建回调函数?

    我为海盗工具引擎SDK编写了一个包装器,但是有一个函数我还没有包装好.它是一个接受回调函数的异步函数,但我似乎不知道如何给它这个回调函数.在 函数如下所示:bool CorsairSetLedsCol ...

  7. java socket 回调函数_请问Java网络编程如何在不使用多线程的情况下实现异步返回?...

    我指的是在不使用多线程的情况下进行并发处理 具体的情况是,在不使用多线程的情况下,服务器侦听某个端口,在有连接进来的时候会调用某个函数对此连接进行处理,但是由于处理的过程可能会比较长,为了不让后面连接 ...

  8. java socket 异步回调函数_浅谈socket同步和异步、阻塞和非阻塞、I/O模型

    原标题:浅谈socket同步和异步.阻塞和非阻塞.I/O模型 在进行网络编程时,常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式 同步/异步主要针 ...

  9. bootstraptable 加载完成回调函数_牛皮了!头一次见有大佬把「JavaScript中的回调函数」详解得如此清晰明了...

    前言 callback,大家都知道是回调函数的意思.但是你对这个概念应该是模模糊糊.比如Ajax,你只知道去调用返回函数,如果对callback没有理解清楚,估计你在学习Node.js后会崩溃,因为c ...

最新文章

  1. 【NLP】业界总结 | BERT的花式玩法
  2. leader选举的源码分析-Messenger
  3. 中英文对照 —— 机械
  4. 亚马逊开源模型设计神器:AutoGluon,三行代码自动生成SOTA模型!
  5. 如何理解什么是放射?
  6. C++开发工程师的薪资和未来发展
  7. C语言标准io函数,《C语言深度解析》第9章——位操作 与 c标准IO库
  8. fences卸载_fences是什么意思?WIN10专业版彻底删除fences的技巧
  9. Mysql查询当天,本周,本月所有数据记录
  10. linux下列出绝对路径的最快捷的方法lls
  11. 操作系统进程线程区别、并发和并行、内存和外存
  12. dell720服务器支持的显卡,Dell Poweredge 服务器显卡选择
  13. Learning Pose Grammar to Encode Human Body Configuration for 3D Pose Estimation论文阅读笔记
  14. 谈我们的团队文化建设
  15. Java中如何通过经纬度坐标获取两个点之间的直线距离
  16. 【方法】树莓派开机使用教程(看这个就够了)
  17. Python数据爬取之中国人口数据【附整理好的分省数据下载链接】
  18. Python:快速去除PDF水印
  19. (实用篇)php常用字符串函数实例总结【转换,替换,计算,截取,加密】
  20. Qt5生成Word格式报告

热门文章

  1. VMWARE双机安装说明
  2. String s = new String(123) 究竟创建了几个对象
  3. Failed to load or instantiate TagLibraryValidator class: org.apache.taglibs.standard.tlv.JstlFmtTLV
  4. php curl 模拟多线程,php利用curl 多线程 模拟 并发的详解
  5. html网页 table布局实例,HTML用Table表格对网页布局
  6. python单词反转_python文本 字符串逐字符反转以及逐单词反转
  7. html语言闪烁特效代码,css3 文字闪烁特效代码
  8. 请写出3个Android布局,一起撸一波干货集中营练练手Android(三)布局+实现篇
  9. L1-056 猜数字 C语言,PAT L1-032 Left-pad
  10. php定义object数据类型,PHP数据类型(4):对象object