WGS84从GPS中获取的坐标系,转换为百度BD-09坐标系
一、使用百度地图的API转换——单个坐标转换
百度官网API示例:https://lbsyun.baidu.com/jsdemo.htm#a5_2
主要代码:
<script type="text/javascript">
//待转化的GPS坐标
var x = 116.32715863448607;
var y = 39.990912172420714;
var ggPoint = new BMap.Point(x,y);
//地图初始化
var bm = new BMap.Map("allmap");
bm.centerAndZoom(ggPoint, 15);
bm.addControl(new BMap.NavigationControl());
//坐标转换完之后的回调函数:在对应位置添加一个标注点
translateCallback = function (data){
if(data.status === 0) {
//data.status===0表示转换结果正常返回
//新建一个标注点
var marker = new BMap.Marker(data.points[0]);
//将标注点添加到地图上
bm.addOverlay(marker);
var label = new BMap.Label("转换后的百度坐标",{offset:new BMap.Size(20,-10)});
//在标注点的旁边添加一个label说明
marker.setLabel(label); //添加百度label
//设置百度地图中心点
bm.setCenter(data.points[0]);
}
}
//坐标转换
setTimeout(function(){
var convertor = new BMap.Convertor();
var pointArr = [];
pointArr.push(ggPoint);
convertor.translate(pointArr, 1, 5, translateCallback)
}, 1000);
/**
* 坐标常量说明:
* COORDINATES_WGS84 = 1, WGS84坐标
* COORDINATES_WGS84_MC = 2, WGS84的平面墨卡托坐标
* COORDINATES_GCJ02 = 3,GCJ02坐标
* COORDINATES_GCJ02_MC = 4, GCJ02的平面墨卡托坐标
* COORDINATES_BD09 = 5, 百度bd09经纬度坐标
* COORDINATES_BD09_MC = 6,百度bd09墨卡托坐标
* COORDINATES_MAPBAR = 7,mapbar地图坐标
* COORDINATES_51 = 8,51地图坐标
*/
</script>
百度地图坐标转换API的请求参数和返回结果、状态码的说明文档:https://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition
二、百度地图还提供了批量坐标转换的工具,API示例地址:
https://lbsyun.baidu.com/jsdemo.htm#Translategroup
但是,使用这个工具,需要注意它的一些局限性:
1.对转换的坐标的数量有限制:最多20个,如果超过限制,返回的data.status==25(上面图片的状态码说明中有)
2.要注意它使用的是setTimeout()方法,它是异步执行的,也就是它所在的程序块儿的主程序执行完之后,才会执行回调函数;这使得它并不是按先进先出的顺序返回结果,所以转换之后的坐标顺序可能是乱的。
解决办法就是,使用for循环+setTimeout闭包(传递一个变量,记录坐标的顺序):
for(var i=0;i<path.length;i++){
//将for循环的变量i传输到setTimeout内部j,记录到转换结果pointArr[j]的顺序就不会乱了
(function(j) {
setTimeout(function(){
var point = [];
//这里的path是待批量转换的WGS84坐标
point.push(new BMapGL.Point(path[j].lon,path[j].lat));
//坐标转换
posTrans(point, translateCallback);
}, 1000 );
//转换完成之后的回调函数
var translateCallback=function(data){
if(data.status === 0) {
//转换后的结果,j代表坐标点在原始队列中的顺序
pointArr[j]=data.points[0];
}
}
})(i);
}
//坐标转换
function posTrans(points,callback){
var convertor = new BMapGL.Convertor();
convertor.translate(points, 1, 5, callback);//百度的坐标转换接口。
}
最初看这些代码是晕的,原因是概念模糊,需要明白的一些概念:自调用函数(又叫自执行函数)、闭包、作用域(局部作用域、全局作用域)、setTimeout延时器的运行机制
理解这些概念,参考的一些文章:
1.关于for循环中使用setTimeout的四种解决方案:https://www.cnblogs.com/wl0804/p/11987833.html
2.自执行函数和闭包:
https://www.cnblogs.com/makalochen/p/13767485.html
3.自调用函数:
https://www.cnblogs.com/renweiboke/articles/12807461.html
三、使用第三方工具转换:wandergis提供的coordtransform
使用方法见:http://wandergis.com/coordtransform/
thinkphp框架使用coordtransform的方法:在终端运行npm install coordtransform,执行完毕,会在根目录生成一个node_modules文件夹,如下:
要使用这个工具,只需要引入node_modules文件夹下的index.js就行了:
<script src="/node_modules/coordtransform/index.js"></script>
test文件夹下的index.html是使用示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>coordTransform</title>
</head>
<body>
<h1>请按F12打开控制台查看结果!(Please open console by F12!)</h1>
<script src="../index.js"></script>
<script>
//国测局坐标(火星坐标,比如高德地图在用),百度坐标,wgs84坐标(谷歌国外以及绝大部分国外在线地图使用的坐标)
//百度经纬度坐标转国测局坐标
var bd09togcj02 = coordtransform.bd09togcj02(116.404, 39.915);
//国测局坐标转百度经纬度坐标
var gcj02tobd09 = coordtransform.gcj02tobd09(116.404, 39.915);
//wgs84转国测局坐标
var wgs84togcj02 = coordtransform.wgs84togcj02(116.404, 39.915);
//国测局坐标转wgs84坐标
var gcj02towgs84 = coordtransform.gcj02towgs84(116.404, 39.915);
console.log(bd09togcj02);
console.log(gcj02tobd09);
console.log(wgs84togcj02);
console.log(gcj02towgs84);
//result
//bd09togcj02: [ 116.39762729119315, 39.90865673957631 ]
//gcj02tobd09: [ 116.41036949371029, 39.92133699351021 ]
//wgs84togcj02: [ 116.41024449916938, 39.91640428150164 ]
//gcj02towgs84: [ 116.39775550083061, 39.91359571849836 ]
</script>
</body>
</html>
测试了一下是很好用的,要注意的两点是:
1.注意Index.js的引用方式(所在目录路径)
2.WGS84坐标,需要先转换成国测局的gcj02坐标,然后由gcj02坐标转换成百度的BD-09坐标,也就是WGS84坐标不能直接转换成百度BD-09坐标