百度地图API中如何用好摩卡托坐标 - Go语言中文社区

百度地图API中如何用好摩卡托坐标


百度地图API有两种坐标系,一种是百度经纬度,一种是摩卡托坐标系。在本章你将学会:

1、如何相互转换这两种坐标;

2、使用该坐标进行反地址解析;

3、坐标附近全部POI的查询;

4、计算两点间的距离。

最终画面效果图

百度地图API常用两种坐标系,一是球面坐标系,又称百度坐标,即point;第二就是平面坐标系,又称摩卡托坐标,即pixel。

为了方便用户调用,API中的参数大多为百度经纬度,又称球面坐标。而在后台计算时,为了加快运算速度,一般采取摩卡托坐标系,即平面坐标。(有了平面坐标,用户能自己快速海量地计算两点的距离。)

1、百度经纬度和摩卡托坐标的相互转换

MercatorProjection类,通过MapType的getProjection方法获得实例。类参考:

百度经纬度转换为摩卡托(worldCoordinate.x和worldCoordinate.y就是平面坐标的x和y)

varprojection1 = map.getMapType().getProjection();

varworldCoordinate = projection1.lngLatToPoint(pt);

摩卡托转换为百度经纬度(LngLat.lng和LngLat.lat就是经纬度)

  1. varprojection2 = map.getMapType().getProjection();  
  2. varLngLat = projection2.pointToLngLat(mctXY); 

2、使用坐标进行反地址解析

由于百度地图API只支持百度经纬度的反地址解析,所以,必须先将摩卡托坐标转换为百度经纬度,再使用如下方法。

  1. vargc = newBMap.Geocoder();  
  2. gc.getLocation(point, function(rs){  
  3. varaddComp = rs.addressComponents;  
  4. alert(addComp.province + ", " + addComp.city + ", " + addComp.district + ", " + addComp.street + ", " + addComp.streetNumber);  
  5. });  
  6. }); 

反地址解析可以返回如下数据:

3、坐标附近全部POI的查询

详细教程请参照文章《【百度地图API】如何用圆形搜索获取中心点周围100米内全部关键点?如天安门附近所有的餐厅、加油站、宾馆、大厦等》:http://www.cnblogs.com/milkmap/archive/2011/09/16/2178907.html

4、计算两点间距离的三种方法

通过本章介绍的经纬度转换的工具,我们得到如下的一组数据。

起点:

摩卡托坐标x:12057394.71

摩卡托坐标y:2589680.88

经纬度lng: 108.312241

经纬度lat: 22.787823

终点:

摩卡托坐标x:12058626.7

摩卡托坐标y:2592552.85

经纬度lng: 108.323308

经纬度lat: 22.811744

(A) 通过百度地图API调用(这里只能使用百度经纬度),map.getDistance(pointA,pointB),可以得到距离为:

alert(map.getDistance(newBMap.Point(108.312241,22.787823),newBMap.Point(108.323308,22.811744)));

(B) 自己利用球面坐标计算两点距离的方法:

设地球半径为R,地心为0,球面上两点A、B的球面坐标为A(α1,β1),B(α2,β2),α1、α2∈[-π,π],β1、β2∈[-π/2,π/2 ],

AB =R·arccos[cosβ1cosβ2cos(α1-α2)+sinβ1sinβ2]

利用勾股定理与正弦定理则可求出AB两点间的直线距离,在利用正弦定理可求出AB两点与地球0点夹角的度数,再利用如下公式:角EOD的度数/360度=E与D之间的球面距离/大圆周长,则可求出AB的球面距离。

(C) 自己利用平面坐标系计算两点距离的方法:(可以自己后台运算

由百度经纬度得到摩卡托坐标后,能轻松计算出X和Y的值。***用勾股定理求得Z。

alert(Math.sqrt(Math.pow((12057394.71 - 12058626.7),2) + Math.pow((2589680.88 - 2592552.85),2)));

全部源代码:

  1. <!DOCTYPE html> 
  2. <html> 
  3. <head> 
  4. <meta http-equiv="Content-Type"content="text/html; charset=gb2312"/> 
  5. <title>摩卡托坐标的反地址解析</title> 
  6. <script type="text/javascript"src="http://api.map.baidu.com/api?v=1.2"></script> 
  7. </head> 
  8. <body> 
  9. <div style="width:400px;height:650px;border:1px solid gray;float:left;"id="container"></div> 
  10. <div style="width:500px;height:270px;float:left;margin:0 0 0 10px;"> 
  11. <p>摩卡托坐标x:<input type="text"value="12059034.69"id="mctX"/></p> 
  12. <p>摩卡托坐标y:<input type="text"value="2590880.82"id="mctY"/></p> 
  13. <p id="pointX"></p> 
  14. <p id="pointY"></p> 
  15. <p id="entertaiment"></p> 
  16. <p><input style="width:240px;height:130px;font-size:30px;"type="button"value="MCT反地址解析"onclick="mctGeo();"/></p> 
  17. <div id="panel"></div> 
  18. </div> 
  19. </body> 
  20. </html> 
  21. <script type="text/javascript"> 
  22. //以下两句话为创建地图  
  23. varmap =newBMap.Map("container");  
  24. map.centerAndZoom(newBMap.Point(108.318421,22.800617), 15);//鱼骨控件  
  25. map.addControl(newBMap.NavigationControl()); //点击地图进行地址解析  
  26. vargc =newBMap.Geocoder();  
  27. map.addEventListener("click", function(e){varpt =e.point;  
  28.  document.getElementById("pointX").innerHTML ="经纬度lng: "+pt.lng;  
  29. document.getElementById("pointY").innerHTML ="经纬度lat: "+pt.lat;varprojection1 =this.getMapType().getProjection();varworldCoordinate =projection1.lngLatToPoint(pt);  
  30. document.getElementById("mctX").value =worldCoordinate.x;  
  31. document.getElementById("mctY").value =worldCoordinate.y;  
  32. map.clearOverlays();  
  33. document.getElementById("panel").innerHTML ="";  
  34. gc.getLocation(pt, function(rs){varaddComp =rs.addressComponents;  
  35. document.getElementById("entertaiment").innerHTML =addComp.province +", "+addComp.city +", "+addComp.district +", "+addComp.street +", "+addComp.streetNumber;varallPois =rs.surroundingPois; //获取全部POI(该点半径为100米内有6个POI点)  
  36. for(i=0;i<allPois.length;++i){  
  37. document.getElementById("panel").innerHTML +="<p style='font-size:12px;'>"+(i+1) +"、"+allPois[i].title +",地址:"+allPois[i].address +"</p>";  
  38. map.addOverlay(newBMap.Marker(allPois[i].point));  
  39. }  
  40. },mOption);  
  41. });//摩卡托反地址解析  
  42. varmOption ={  
  43. poiRadius : 500, //半径为1000米内的POI,默认100米  
  44. numPois : 12//列举出50个POI,默认10个  
  45. }functionmctGeo(){  
  46. map.clearOverlays();  
  47. document.getElementById("panel").innerHTML ="";varmctXX =document.getElementById("mctX").value;varmctYY =document.getElementById("mctY").value; varmctXY =newBMap.Pixel(mctXX,mctYY); varprojection2 =map.getMapType().getProjection();varLngLat =projection2.pointToLngLat(mctXY);  
  48. document.getElementById("pointX").innerHTML ="经纬度lng: "+LngLat.lng;  
  49. document.getElementById("pointY").innerHTML ="经纬度lat: "+LngLat.lat;  
  50. gc.getLocation(LngLat, function(rs){varaddComp =rs.addressComponents;  
  51. document.getElementById("entertaiment").innerHTML =addComp.province +", "+addComp.city +", "+addComp.district +", "+addComp.street +", "+addComp.streetNumber;varallPois =rs.surroundingPois; //获取全部POI(该点半径为100米内有6个POI点)  
  52. for(i=0;i<allPois.length;++i){  
  53. document.getElementById("panel").innerHTML +="<p style='font-size:12px;'>"+(i+1) +"、"+allPois[i].title +",地址:"+allPois[i].address +"</p>";  
  54. map.addOverlay(newBMap.Marker(allPois[i].point));  
  55. }  
  56. },mOption);  
  57. }</script> 

原文链接:http://www.cnblogs.com/milkmap/archive/2012/01/31/2333875.html

版权声明:本文来源51CTO,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:http://developer.51cto.com/art/201202/314270.htm
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-16 02:00:00
  • 阅读 ( 1408 )
  • 分类:职场

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢