欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

WGS84从GPS中获取的坐标系,转换为百度BD-09坐标系

程序员文章站 2022-03-13 12:34:53
...

一、使用百度地图的API转换——单个坐标转换
百度官网API示例:https://lbsyun.baidu.com/jsdemo.htm#a5_2
主要代码:

  1. <script type="text/javascript">
  2. //待转化的GPS坐标
  3. var x = 116.32715863448607;
  4. var y = 39.990912172420714;
  5. var ggPoint = new BMap.Point(x,y);
  6. //地图初始化
  7. var bm = new BMap.Map("allmap");
  8. bm.centerAndZoom(ggPoint, 15);
  9. bm.addControl(new BMap.NavigationControl());
  10. //坐标转换完之后的回调函数:在对应位置添加一个标注点
  11. translateCallback = function (data){
  12. if(data.status === 0) {
  13. //data.status===0表示转换结果正常返回
  14. //新建一个标注点
  15. var marker = new BMap.Marker(data.points[0]);
  16. //将标注点添加到地图上
  17. bm.addOverlay(marker);
  18. var label = new BMap.Label("转换后的百度坐标",{offset:new BMap.Size(20,-10)});
  19. //在标注点的旁边添加一个label说明
  20. marker.setLabel(label); //添加百度label
  21. //设置百度地图中心点
  22. bm.setCenter(data.points[0]);
  23. }
  24. }
  25. //坐标转换
  26. setTimeout(function(){
  27. var convertor = new BMap.Convertor();
  28. var pointArr = [];
  29. pointArr.push(ggPoint);
  30. convertor.translate(pointArr, 1, 5, translateCallback)
  31. }, 1000);
  32. /**
  33. * 坐标常量说明:
  34. * COORDINATES_WGS84 = 1, WGS84坐标
  35. * COORDINATES_WGS84_MC = 2, WGS84的平面墨卡托坐标
  36. * COORDINATES_GCJ02 = 3,GCJ02坐标
  37. * COORDINATES_GCJ02_MC = 4, GCJ02的平面墨卡托坐标
  38. * COORDINATES_BD09 = 5, 百度bd09经纬度坐标
  39. * COORDINATES_BD09_MC = 6,百度bd09墨卡托坐标
  40. * COORDINATES_MAPBAR = 7,mapbar地图坐标
  41. * COORDINATES_51 = 8,51地图坐标
  42. */
  43. </script>

百度地图坐标转换API的请求参数和返回结果、状态码的说明文档:https://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition
WGS84从GPS中获取的坐标系,转换为百度BD-09坐标系
WGS84从GPS中获取的坐标系,转换为百度BD-09坐标系
WGS84从GPS中获取的坐标系,转换为百度BD-09坐标系

二、百度地图还提供了批量坐标转换的工具,API示例地址:
https://lbsyun.baidu.com/jsdemo.htm#Translategroup
但是,使用这个工具,需要注意它的一些局限性:
1.对转换的坐标的数量有限制:最多20个,如果超过限制,返回的data.status==25(上面图片的状态码说明中有)
2.要注意它使用的是setTimeout()方法,它是异步执行的,也就是它所在的程序块儿的主程序执行完之后,才会执行回调函数;这使得它并不是按先进先出的顺序返回结果,所以转换之后的坐标顺序可能是乱的。
解决办法就是,使用for循环+setTimeout闭包(传递一个变量,记录坐标的顺序):

  1. for(var i=0;i<path.length;i++){
  2. //将for循环的变量i传输到setTimeout内部j,记录到转换结果pointArr[j]的顺序就不会乱了
  3. (function(j) {
  4. setTimeout(function(){
  5. var point = [];
  6. //这里的path是待批量转换的WGS84坐标
  7. point.push(new BMapGL.Point(path[j].lon,path[j].lat));
  8. //坐标转换
  9. posTrans(point, translateCallback);
  10. }, 1000 );
  11. //转换完成之后的回调函数
  12. var translateCallback=function(data){
  13. if(data.status === 0) {
  14. //转换后的结果,j代表坐标点在原始队列中的顺序
  15. pointArr[j]=data.points[0];
  16. }
  17. }
  18. })(i);
  19. }
  20. //坐标转换
  21. function posTrans(points,callback){
  22. var convertor = new BMapGL.Convertor();
  23. convertor.translate(points, 1, 5, callback);//百度的坐标转换接口。
  24. }

最初看这些代码是晕的,原因是概念模糊,需要明白的一些概念:自调用函数(又叫自执行函数)、闭包、作用域(局部作用域、全局作用域)、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文件夹,如下:
WGS84从GPS中获取的坐标系,转换为百度BD-09坐标系
要使用这个工具,只需要引入node_modules文件夹下的index.js就行了:

  1. <script src="/node_modules/coordtransform/index.js"></script>

test文件夹下的index.html是使用示例:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>coordTransform</title>
  6. </head>
  7. <body>
  8. <h1>请按F12打开控制台查看结果!(Please open console by F12!)</h1>
  9. <script src="../index.js"></script>
  10. <script>
  11. //国测局坐标(火星坐标,比如高德地图在用),百度坐标,wgs84坐标(谷歌国外以及绝大部分国外在线地图使用的坐标)
  12. //百度经纬度坐标转国测局坐标
  13. var bd09togcj02 = coordtransform.bd09togcj02(116.404, 39.915);
  14. //国测局坐标转百度经纬度坐标
  15. var gcj02tobd09 = coordtransform.gcj02tobd09(116.404, 39.915);
  16. //wgs84转国测局坐标
  17. var wgs84togcj02 = coordtransform.wgs84togcj02(116.404, 39.915);
  18. //国测局坐标转wgs84坐标
  19. var gcj02towgs84 = coordtransform.gcj02towgs84(116.404, 39.915);
  20. console.log(bd09togcj02);
  21. console.log(gcj02tobd09);
  22. console.log(wgs84togcj02);
  23. console.log(gcj02towgs84);
  24. //result
  25. //bd09togcj02: [ 116.39762729119315, 39.90865673957631 ]
  26. //gcj02tobd09: [ 116.41036949371029, 39.92133699351021 ]
  27. //wgs84togcj02: [ 116.41024449916938, 39.91640428150164 ]
  28. //gcj02towgs84: [ 116.39775550083061, 39.91359571849836 ]
  29. </script>
  30. </body>
  31. </html>

测试了一下是很好用的,要注意的两点是:
1.注意Index.js的引用方式(所在目录路径)
2.WGS84坐标,需要先转换成国测局的gcj02坐标,然后由gcj02坐标转换成百度的BD-09坐标,也就是WGS84坐标不能直接转换成百度BD-09坐标