之前有接触过一个项目,大致要求是有一系列GPS坐标(有时间顺序),要求在百度地图上标记出这些点,画出轨迹图。
首先有一点要明确,百度地图上的GPS坐标(百度坐标)是对原始GPS坐标经过一些计算后得到的,所以我们如果想要在百度地图上正确描绘我们所需要的点,我们必须先将手上的GPS坐标转换成百度地图的坐标,再通过new BMap.Point(lng,lat)去添加标记点。转换成百度坐标需要用到BMap.Convertor.translate(gpsPoint,0,translateCallback)函数,需要引用。
由于坐标转换translate函数执行是一个异步的过程,我们无法控制它的执行顺序,所以在对一系列坐标同时进行处理时,无法按照我们想要的顺序在回调函数中对数据进行处理,这里必须对translate函数做一些改进,其实一个标志位就足够了。下面贴出改进后的convertor.js代码。
(function(){ //闭包
function load_script(xyUrl, callback){
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = xyUrl;
//借鉴了jQuery的script跨域方法
script.onload = script.onreadystatechange = function(){
if((!this.readyState || this.readyState === "loaded" || this.readyState === "complete")){
callback && callback();
// Handle memory leak in IE
script.onload = script.onreadystatechange = null;
if ( head && script.parentNode ) {
head.removeChild( script );
}
}
};
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
head.insertBefore( script, head.firstChild );
}
function translate(point,type,callback,X){
var callbackName = 'cbk_' + Math.round(Math.random() * 10000); //随机函数名
var xyUrl = "http://api.map.baidu.com/ag/coord/convert?from="+ type + "&to=4&x=" + point.lng + "&y=" + point.lat + "&callback=BMap.Convertor." + callbackName;
//动态创建script标签
load_script(xyUrl);
BMap.Convertor[callbackName] = function(xyResult){
delete BMap.Convertor[callbackName]; //调用完需要删除改函数
var point = new BMap.Point(xyResult.x, xyResult.y);
callback && callback(point,X);
}
}
window.BMap = window.BMap || {};
BMap.Convertor = {};
BMap.Convertor.translate = translate;
})();
简单来说,就是将translate方法的参数由3个改成4个,新加的参数即是顺序标志位。
下面附上自定义的js文件代码:
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(data) {
map.clearOverlays();
//例如 设置这样一个字符串并拆分成数组对象 ,里面的是GPS坐标,转换成百度坐标后按顺序显示在地图上并且点之间用带箭头的红线
var K=data.length;//标示符判断最后K、L是否相等
for(var i=0;ipixelStart.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:5, strokeOpacity:0.9});
map.addOverlay(Arrow);
}
}
首先依次将标记点添加到地图,不分顺序,并将标记点存进自定义的hashmap对象(key值为顺序标志位)。然后在转换坐标的回调函数中,根据我们新添加的顺序标志位来判断,如果是第一个坐标点,则地图定位到此点;如果是最后一个点,则根据key值按顺序循环hashmap的对象,将标记点存进Json数组,这样就得到了有序的点集数组。根据有序数组依次画出每条直线,并利用addArrow()函数画出箭头(通过计算后得到的2条直线)即可。
最后附上简易的效果图(直线的颜色及大小都可调整):