轨迹回放有几个方案:
方案一、调用arcgis自己的api,设置定时器,一段时间清空当前点,绘制下一个点。
缺点:点的移动不是连续的,一闪一闪的,而且速度不均匀
方案二、利用HTML5的canvas,原理和上面一样
缺点:同上
方案三、利用SVG制作动画
没有缺点,非常完美
通过比较,最后使用SVG进行制作轨迹回放。
这里有几个难点:
1、屏幕坐标和经纬度的同步
2、SVG动画层会遮盖地图层的事件
3、由于是连续动画,移动到某时刻并不一定在路径数组的点上,暂停和漫游需要知道回放到的路基数组的具体区间
实现的思路:
1、启动的时候,动态把SVG的路径解析出来
2、设置定时器,频率要比播放速度快,尽量快就好了。
定时器里面做两个事情:a、判断是否到达下一个点,把数组偏移量记录下来。b、判断是否碰到屏幕边界,屏幕边界需要漫游。
当然,这个定时器只有在播放的时候触发逻辑。
3、zoomin和zoomout,漫游的时候删除原来SVG动画,通过第二步的数组偏移量,把后续的路径按照新的屏幕坐标解析出来。当前轨迹点也同理重新绘制
4、屏幕坐标和经纬度的同步可以通过arcgis api里面的方法进行
5、事件被遮盖的问题,SVG提供了一种方式,通过embed 的wmode="opaque"设置可以解决。但是我这里的SVG如果潜入到embed中,则不方便动态获取DOM,也就不好实现SVG的重绘。因此排除掉此方法。
考虑到被遮盖的事件只有鼠标点击和滚轮的zoomin和zoomout,鼠标拖动的漫游。而且希望在播放状态的漫游中会自动适配到轨迹,暂停和停止不做限制,因此考虑自己来实现arcgis的以上事件。
6、鼠标点击和滚轮的zoomin和zoomout的事件通过SVG的鼠标点击事件,事件中直接调用arcgis的api即可。由于SVG没有鼠标拖拽事件,则需要独立实现,把移动的方向获取,然后调用arcgis的api即可。
下面看一下关键代码
核心对象:
//track用来存储轨迹状态,动态获得播放当前状态
var track={
//轨迹的初始经纬度,一旦获得则不能被改变
originalLon:[],
originalLat:[],
//未播放的路径经纬度
lon:[],
lat:[],
//屏幕坐标
x:[],
y:[],
//当前播放点的经纬度
now:[],
//当前播放点的屏幕坐标
nowXY:[],
//轨迹长度
length:0,
//当前数组偏移量
i:0,
//屏幕边界点坐标
limitXY:[],
//设置当前数组偏移量和判断是否碰壁,碰壁则漫游
nowTimer:setInterval(function(){
if(!document)
return;
//设置当前数组偏移量
if(track.lon[track.i]-track.now()<0.0001 && track.lat[track.i]-track.now[1]<0.0001){
if(processManager.isStart)
track.i++;
//判断是否碰壁,碰壁则漫游
if(track.nowXY[0]>=track.limitXY[0] || track.nowXY[1]>=track.limitXY[1] ||
track.nowXY[0]<=0 || track.nowXY