最近做了一個項目,要求從數據庫里讀取帶有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代碼:

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