arcgis总结——结合SVG制作轨迹回放
来源:互联网 发布:知堂回想录 pdf 编辑:程序博客网 时间:2024/06/05 17:11
轨迹回放有几个方案:
方案一、调用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[1]<=0){ if(processManager.isStart){ var point=new esri.geometry.Point({ x:track.now[0], y:track.now[1] }); map.centerAt(point); } } },50))};//processManager对象用来存储播放状态var processManager={isStart:false};//SVGEvent类用来实现SVG的扩展事件var SVGEvent=function(){ ...}//用静态方法来实现事件绑定SVGEvent.bindEvent=function(element,eventName,fn){ if(!element || element=="svg") element=window; //鼠标滚动事件 if(eventName=="mousewheel"){ window.onmousewheel=document.onmousewheel=fn; } //鼠标拖动事件 if(eventName=="mouseDrag"){ var state=false,original_x,original_y; element.onmousedown=function(event){ original_x=e.clientX; original_y=e.clientY; state=true; }; element.onmousemove=function(event){ if(state){ var e=event ? event : window.event; } }; element.onmouseup=function(event){ if(state){ state=false; var diffX=parseInt(event.clientX-original_x); var diffY=parseInt(event.clientY-original_y); var dx="center"; var dy="center"; var d="center"; if(Math.abs(diffX)>80) dx=diffX>0 ? "right" : "left"; if(Math.abs(diffY)>80) dy=diffY>0 ? "down" : "up"; if(dx!="center" && dy!="center") d=dx+dy; if(dx!="center" && dy=="center") d=dx; if(dx=="center" && dy!="center") d=dy; fn.call(element,event,dx,dy,d,[event,clientX,event.clientY],[original_x,original_y]); original_x=0; original_y=0; original_left=0; original_top=0; } } }}
初始化处理的关键代码:
function init(){ //地图的初始化省略 ... //zoomin、zoomout后重新同步坐标,并且重绘动画 dojo.connect(map,'onZoomEnd',function(){ zoomSVG(); }); //鼠标滚动 SVGEvent.bindEvent("svg","mousewheel",wheel); //鼠标拖动 SVGEvent.bindEvent("svg","mouseDrag",drag); //初始化边界坐标 track.limitXY=[document.body.clientWidth,docment.body.clientHeight]; //初始化屏幕坐标 initScreenXY(); //初始化svg initSVG(track); //加载轨迹线 addTrack(track);}function initScreenXY(){ track.x=[]; track.y=[]; for(var i=0;i<track.length;i++){ var geometry=new esri.geometry.Point(track.originalLon[i],track.originalLat[j]); var screenPoint=map.toScreen(geometry); track.x.push(screenPoint.x); track.y.push(screenPoint.y); }}function initSVG(track){ //绘制起始点 var circle=document.createElementNS("http://www.w3.org/2000/svg","circle"); circle.setAttribute("id","circle"); circle.setAttribute("cx",track.x[0]); circle.setAttribute("cy",track.y[0]); circle.setAttribute("r",8); document.getElementById("svg").appendChild(circle); //绘制轨迹 var motionPath=document.createElementNS("http://www.w3.org/2000/svg","path"); motionPath.setAttribute("id","motionPath"); motionPath.setAttribute("fill","none"); var pathParams="M0 0"; for(var i=0;i<track.length;i++){ pathParams="L"+parseInt(track.x[i]-track.x[0])+" "+parseInt(track.y[i]-track.y[0]); } motionPath.setAttribute("d",pathParams); document.getElementById("svg").appendChild(motionPath);}function addTrack(track){ //通过arcgis绘制轨迹线,这样在zoomin,zoomout和漫游后不需要重绘 var path=[]; for(var i=0;i<track.length;i++){ var pos=[]; pos.push(track.lon[i]); pos.push(track.lat[i]); path.push(pos); } var polyLine=new esri.geometry.Polyline([path]); var simpleLineSymbol=new esri.symbol.SimpleLineSymbol(); var graphic=new esri.Graphic(polyLine,simpleLineSymbol); map.graphics.add(graphic);}
动画控制的核心代码如下:
function play(){ if(!processManager.isStart){ document.getElementById("animateMotion").beginElement(); processManager.isStart=true; }else{ document.getElementById("svg").unpauseAnimations(); } }}function pause(){ document.getElementById("svg").pauseAnimations(); processManager.isStart=false;}function stop(){ track.i=0; processManager.isStart=false; pause(); clearSVG(); initScreenXY(); initSVG(track);}function clearSVG(){ var circle=document.getElementById("circle"); circle.parentNode.removeChild(circle); var motionPath=document.getElementById("motionPath"); motionPath.parentNode.removeChild(motionPath);}
zoomin,zoomout,漫游后的处理核心代码如下:
function zoomSVG(){ document.getElementById("svg").pausseAnimations(); clearSVG(); reDrawSVG(); if(processManager.isStart) play();}function panSVG(){ document.getElementById("svg").pausseAnimations(); clearSVG(); reDrawSVG(); if(processManager.isStart) play();<span style="font-family: Arial, Helvetica, sans-serif;">}function reDrawSVG(){ //初始化剩余路线的坐标信息 var lon=[]; var lat=[]; var x=[]; var y=[]; //是否播放到最后一段,最后一段特殊处理 if(track.i<track.length){ for(var i=track.i;i<track.length;i++){ if(!track.originalLon[i]) break; lon.push(track.originalLon[i]); lat.push(track.originalLat[i]); var geometry=new esri.geometry.Point(track.originalLon[i],track.originalLat[i]); var screenPoint=map.toScreen(geometry); x.push(screenPoint.x); y.push(screenPoint.y); } } else{ lon.push(track.originalLon[track.i-1]); lat.push(track.originalLat[track.i-1]); var geometry=new esri.geometry.Point(track.originalLon[track.i-1],track.originalLat(track.i-1)); var screenPoint=map.toScreen(geometry); x.push(screenPoint.x); y.push(screenPoint.y); } //绘制当前点 var circle=document.createElementNS("http://www.w3.org/2000/svg","circle"); circle.setAttribute("id","circle"); circle.setAttribute("cx",x[0]); circle.setAttribute("cy",y[0]); circle.setAttribute("r",8); document.getElementBuId("svg").appendChild(circle); //绘制SVG轨迹 var motionPath=document.createElementNS("http://www.w3.org/2000/svg","path"); motionPath.setAttribute("id","motionPath"); motionPath.setAttribute("fill",none); var pathParams="M0 0"; //是否播放到最后一段,最后一段特殊处理 if(track.i<track.length){ for(var i=0;i<x.length;i++){ pathParams+="L"+parseInt(x[i]-x[0])+" "+parseInt(y[i]-y[0]); } } else{ pathParams+="L"+parseInt(x[x.length-1]-x[0])+" "+parseInt(y[y.length-1]-y[0]); } motionPath.setAttribute("d",pathParams); document.getElementById("svg").appendChild(motionPath);}
获得当前点的经纬度,屏幕坐标核心代码如下:
function now(){ var circle=document.getElementById("circle"); if(circle){ //当前的屏幕坐标 var ctm=circle.getCTM(); var x=circle.getAttribute("cx"); var y=circle.getAttribute("cy"); track.nowXY[0]=x*ctm.a+y*ctm.c+ctm.e; track.nowXY[1]=x*ctm.b+y*ctm.d+ctm.f; //当前的经纬度坐标 var screenPoint=new esri.geometry.ScreenPoint({ x:track.nowXY[0], y:track.nowXY[1] }); var point=map.toMap(screenPoint); track.now[0]=point.x; track.now[1]=point.y; }}
实现鼠标点击,滚轮的zoomin,zoomout和鼠标拖动漫游的核心代码如下:
//事件的绑定在init中,这里是绑定的functionfunction wheel(evt){ if(evt.deltaY>0){ zoomIn(); } else{ zoomOut(); }}function zoomIn(){ var extent=map.extent; map.setExtent(extent.expand(0.5));}function zoomOut(){ var extent=map.extent; map.setExtent(extent.expand(2));}function drag(event,dx,dy,d,point,originalPoint){ if(d=="right") map.panLeft(); if(d=="left") map.panRight(); if(d=="up") map.panDown(); if(d=="down") map.panUp(); if(d=="leftup") map.panLowerRight(); if(d=="leftdown") map.panUpperRight(); if(d=="rightup") map.panLowerLeft(); if(d=="rightdown") map.panUpperLeft();<span style="background-color: rgb(240, 240, 240);">}
- arcgis总结——结合SVG制作轨迹回放
- ArcGIS API for Silverlight 实现轨迹回放
- ArcGIS API for Silverlight 实现轨迹回放
- ArcGIS API for Silverlight 实现轨迹回放
- 基于ArcGIS for javascript API 轨迹回放
- ArcGIS API for Silverlight 实现轨迹回放
- arcgis for silverlight 实现轨迹回放
- 基于ArcGIS for javascript API 轨迹回放
- 百度地图——显示小车轨迹动画回放
- 历史轨迹回放源代码
- 历史轨迹回放
- MapXtreme轨迹回放
- 轨迹回放 百度地图
- 百度地图 - 轨迹回放
- OpenLayers3的轨迹回放
- ArcGIS中制作GPS点位轨迹线及多边形
- GPS/轨迹追踪、轨迹回放、围栏控制
- svg 画轨迹图
- 【猿题库】软工机试
- Android抽象布局(include、merge 、ViewStub)的简介
- SQLSever2008 创建视图
- 客户关系管理系统之动态搜索栏
- html中展示json数据结构
- arcgis总结——结合SVG制作轨迹回放
- 欢迎使用CSDN-markdown编辑器
- mysql 5.7传统复制到gtid复制的在线切换
- 什么是面向过程?什么是面向对象?
- jsonp跨域
- 新技术让SAP HANA向“通用”平台迈进
- python中文分词---jieba
- 进程和线程的区别与联系
- POJ2823-Sliding Window