GPS转百度坐标后按顺序标点和连线
最近做了一个项目,要求从数据库里读取带有GPS数据的人员运行信息,并在百度地图上按顺序标点并按顺序连线,现在把代码分享给大家,希望有需要的朋友能用到。
各个模块的功能在代码后有注释。
先上一张效果图:
html的代码,里面有各个模块的功能注释:
//////////////////////////////////////////////////// 添加图标到地图并连线 /////////////////////////////////////////// // 全局参数 var L=0;//标识是第几个 var Json =[];//接受转换了的百度坐标 var hashMap = { //自定义创建的hasmap 装载转换后的坐标值 Set : function(key,value){this[key] = value}, Get : function(key){return this[key]}, Contains : function(key){return this.Get(key) == null?false:true}, Remove : function(key){delete this[key]} } //入口函数 function SetMarkPoint() { map.clearOverlays(); map.centerAndZoom(point, 17);//为了箭头的太小设置 //例如 设置这样一个字符串并拆分成数组对象 ,里面的是GPS坐标,转换成百度坐标后按顺序显示在地图上并且点之间用带箭头的红线 var data="#测试|116.19045683|29.27100653#测试|116.19045244|29.27100924#测试|116.19045262|29.27100842#测试|116.19044917|29.27101235#测试|116.18752215|29.26957149#测试|116.18436463|29.26704273";//姓名+经纬度 DataRow = data.split("#"); Json =[];//接受转换了的百度坐标 初始化全局变量 var K=DataRow.length;//标示符判断最后K、L是否相等 L=0;//初始化全局变量 for(var J=0;J< DataRow.length;J++) { var dr = DataRow[J].split("|"); //这里把函数放在外面去调用,因为函数里面是一个异步操作,如果写成内联函数或导致循环值出现不可预知的错误。 GPSChanges(dr,J,K);//J为异步获取转换的GPS坐标的标示 } } } function GPSChanges(dr,i,K){ var gpsPoint = new BMap.Point(dr[1], dr[2]); //因为转换GPS坐标是异步的,所以循环转换的时候返回来的时候顺序可能不一致,我们可以修改convertor.js的BMap.Convertor.translate()方法,重载一个带返回标示的参数translate()方法。 // BMap.Convertor.translate(gpsPoint 要转换的GPS坐标,0 为GPS类型的坐标,回调函数,i为返回的标示) BMap.Convertor.translate(gpsPoint, 0, function(gpsLocationPoint,Y) { var myCompOverlay = new ComplexCustomOverlay(gpsLocationPoint, dr[0]); map.addOverlay(myCompOverlay);//添加点 hashMap.Set(Y,gpsLocationPoint);//自定义一个全局的javascript hashmap用来装载返回的百度坐标 L++; if(L==K)//判断所有坐标是否已经转换完成 { for(var N=0;N<K;N++) { Json.push(hashMap.Get(N));//从0开始按顺序获取hashmap的坐标值,装载到Json中 hashMap.Remove(N);//清除已经获取的 } var polyline = new BMap.Polyline(Json, {strokeColor:"red", strokeWeight:1, strokeOpacity:0.9});//在地图上画线 map.addOverlay(polyline);//画线 addArrow(polyline,3,Math.PI/7); //为线段添加箭头 第二个参数为线头的大小,同时也受你打开的地图设置的map.centerAndZoom的影响 } },i); } function addArrow(polyline,length,angleValue){ //绘制箭头的函数 var linePoint=polyline.getPath();//线的坐标串 var arrowCount=linePoint.length; for(var i =1;i<arrowCount;i++){ //在拐点处绘制箭头 var pixelStart=map.pointToPixel(linePoint[i-1]); var pixelEnd=map.pointToPixel(linePoint[i]); var angle=angleValue;//箭头和主线的夹角 var r=length; // r/Math.sin(angle)代表箭头长度 var delta=0; //主线斜率,垂直时无斜率 var param=0; //代码简洁考虑 var pixelTemX,pixelTemY;//临时点坐标 var pixelX,pixelY,pixelX1,pixelY1;//箭头两个点 if(pixelEnd.x-pixelStart.x==0){ //斜率不存在是时 pixelTemX=pixelEnd.x; if(pixelEnd.y>pixelStart.y) { pixelTemY=pixelEnd.y-r; } else { pixelTemY=pixelEnd.y+r; } //已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法 pixelX=pixelTemX-r*Math.tan(angle); pixelX1=pixelTemX+r*Math.tan(angle); pixelY=pixelY1=pixelTemY; } else //斜率存在时 { delta=(pixelEnd.y-pixelStart.y)/(pixelEnd.x-pixelStart.x); param=Math.sqrt(delta*delta+1); if((pixelEnd.x-pixelStart.x)<0) //第二、三象限 { pixelTemX=pixelEnd.x+ r/param; pixelTemY=pixelEnd.y+delta*r/param; } else//第一、四象限 { pixelTemX=pixelEnd.x- r/param; pixelTemY=pixelEnd.y-delta*r/param; } //已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法 pixelX=pixelTemX+ Math.tan(angle)*r*delta/param; pixelY=pixelTemY-Math.tan(angle)*r/param; pixelX1=pixelTemX- Math.tan(angle)*r*delta/param; pixelY1=pixelTemY+Math.tan(angle)*r/param; } var pointArrow=map.pixelToPoint(new BMap.Pixel(pixelX,pixelY)); var pointArrow1=map.pixelToPoint(new BMap.Pixel(pixelX1,pixelY1)); var Arrow = new BMap.Polyline([ pointArrow, linePoint[i], pointArrow1 ], {strokeColor:"blue", strokeWeight:2, strokeOpacity:0.9}); map.addOverlay(Arrow); } } ////////////////////////////////////////////////////////////////// 添加图标到地图并连线 //////////////////////////////////
修改后的convertor.js代码:
convertor.js
1 //2013-03-11 2 (function(){ //闭包 3 function load_script(xyUrl, callback){ 4 var head = document.getElementsByTagName('head')[0]; 5 var script = document.createElement('script'); 6 script.type = 'text/javascript'; 7 script.src = xyUrl; 8 //借鉴了jQuery的script跨域方法 9 script.onload = script.onreadystatechange = function(){ 10 if((!this.readyState || this.readyState === "loaded" || this.readyState === "complete")){ 11 callback && callback(); 12 // Handle memory leak in IE 13 script.onload = script.onreadystatechange = null; 14 if ( head && script.parentNode ) { 15 head.removeChild( script ); 16 } 17 } 18 }; 19 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 20 head.insertBefore( script, head.firstChild ); 21 } 22 function translate(point,type,callback,X){ 23 var callbackName = 'cbk_' + Math.round(Math.random() * 10000); //随机函数名 24 var xyUrl = "http://api.map.baidu.com/ag/coord/convert?from="+ type + "&to=4&x=" + point.lng + "&y=" + point.lat + "&callback=BMap.Convertor." + callbackName; 25 //动态创建script标签 26 load_script(xyUrl); 27 BMap.Convertor[callbackName] = function(xyResult){ 28 delete BMap.Convertor[callbackName]; //调用完需要删除改函数 29 var point = new BMap.Point(xyResult.x, xyResult.y); 30 callback && callback(point,X);//修改返回参数,添加一个参数X 31 } 32 } 33 34 window.BMap = window.BMap || {}; 35 BMap.Convertor = {}; 36 BMap.Convertor.translate = translate; 37 })();