Android中高德地图与百度地图坐标转换

项目中实验数据点取自高德地图,它是火星坐标系统(下面会有解释),而现在希望用百度地图的SDK进行开发,两套不同的规范自然需要进行转换。如何解决这个问题呢?参考了网上很多人的博客和资料。

最终解决此问题用到的仍然是百度的官方文档有关于坐标转换的部分

http://lbsyun.baidu.com/index.php?title=androidsdk/guide/tool#.E5.9D.90.E6.A0.87.E8.BD.AC.E6.8D.A2

坐标转换

百度地图SDK采用的是百度自有的地理坐标系(bdll09),因此开发者在做位置标注的时候,需要将其他类型的坐标转换为百度坐标。相应的接口和转换方式如下:

<span class="co1" style="color:#666666;font-style:italic">// 将google地图、soso地图、aliyun地图、mapabc地图和amap地图// 所用坐标转换成百度坐标  </span>
CoordinateConverter converter  <span class="sy0" style="color:#339933;">=</span> <span class="kw1" style="font-family:Consolas,monaco,'Courier New',Courier,monospace!important;color:#000000;font-weight:bold">new</span> CoordinateConverter<span class="br0" style="color:#0990;">(</span><span class="br0" style="color:#0990;">)</span><span class="sy0" style="color:#339933;">;</span>  
converter.<span class="me1" style="color:#06633;">from</span><span class="br0" style="color:#0990;">(</span>CoordType.<span class="me1" style="color:#06633;">COMMON</span><span class="br0" style="color:#0990;">)</span><span class="sy0" style="color:#339933;">;</span>  
<span class="co1" style="color:#666666;font-style:italic">// sourceLatLng待转换坐标  </span>
converter.<span class="me1" style="color:#06633;">coord</span><span class="br0" style="color:#0990;">(</span>sourceLatLng<span class="br0" style="color:#0990;">)</span><span class="sy0" style="color:#339933;">;</span>  
LatLng desLatLng <span class="sy0" style="color:#339933;">=</span> converter.<span class="me1" style="color:#06633;">convert</span><span class="br0" style="color:#0990;">(</span><span class="br0" style="color:#0990;">)</span><span class="sy0" style="color:#339933;">;</span>  
 
<span class="co1" style="color:#666666;font-style:italic">// 将GPS设备采集的原始GPS坐标转换成百度坐标  </span>
CoordinateConverter converter  <span class="sy0" style="color:#339933;">=</span> <span class="kw1" style="font-family:Consolas,monaco,'Courier New',Courier,monospace!important;color:#000000;font-weight:bold">new</span> CoordinateConverter<span class="br0" style="color:#0990;">(</span><span class="br0" style="color:#0990;">)</span><span class="sy0" style="color:#339933;">;</span>  
converter.<span class="me1" style="color:#06633;">from</span><span class="br0" style="color:#0990;">(</span>CoordType.<span class="me1" style="color:#06633;">GPS</span><span class="br0" style="color:#0990;">)</span><span class="sy0" style="color:#339933;">;</span>  
<span class="co1" style="color:#666666;font-style:italic">// sourceLatLng待转换坐标  </span>
converter.<span class="me1" style="color:#06633;">coord</span><span class="br0" style="color:#0990;">(</span>sourceLatLng<span class="br0" style="color:#0990;">)</span><span class="sy0" style="color:#339933;">;</span>  
LatLng desLatLng <span class="sy0" style="color:#339933;">=</span> converter.<span class="me1" style="color:#06633;">convert</span><span class="br0" style="color:#0990;">(</span><span class="br0" style="color:#0990;">)</span><span class="sy0" style="color:#339933;">;</span>

使用上面的代码就能很好地进行坐标的转化。


下面列举其他牛人的一些内容:

大家都知道,美国GPS使用的是WGS84的坐标系统,以经纬度的形式来表示地球平面上的某一个位置,这应该是国际共识。但在我国,出于国家安全考虑,国内所有导航电子地图必须使用国家测绘局制定的加密坐标系统,即将一个真实的经纬度坐标加密成一个不正确的经纬度坐标,我们在业内将前者称之为地球坐标,后者称之为火星坐标,具体的说明可以参看百度百科中关于火星坐标系统的解释。


1.国内各地图API坐标系统比较

API

坐标系

百度地图API

百度坐标

腾讯搜搜地图API

火星坐标

搜狐搜狗地图API

搜狗坐标*

阿里云地图API

火星坐标

图吧MapBar地图API

图吧坐标

高德MapABC地图API

火星坐标

灵图51ditu地图API

火星坐标


2.下面是百度官方对百度坐标为何有偏移的解释

  国际经纬度坐标标准为WGS-84,国内必须至少使用国测局制定的GCJ-02,对地理位置进行首次加密。百度坐标在此基础上,进行了BD-09二次加密措施,更加保护了个人隐私。百度对外接口的坐标系并不是GPS采集的真实经纬度,需要通过坐标转换接口进行转换。


3.火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法

GCJ-02(火星坐标)BD-09(百度坐标)

算法代码如下,其中bd_encrypt将 GCJ-02坐标转换成 BD-09坐标, bd_decrypt反之。

  1. void bd_encrypt(double gg_lat, double gg_lon, double &bd_lat, double &bd_lon)  
  2. {  
  3.     double x = gg_lon, y = gg_lat;  
  4.     double z = sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi);  
  5.     double theta = atan2(y, x) + 0.000003 * cos(x * x_pi);  
  6.     bd_lon = z * cos(theta) + 0.0065;  
  7.     bd_lat = z * sin(theta) + 0.006;  
  8. }  
  9.    
  10. void bd_decrypt(double bd_lat, double bd_lon, double &gg_lat, double &gg_lon)  
  11. {  
  12.     double x = bd_lon - 0.0065, y = bd_lat - 0.006;  
  13.     double z = sqrt(x * x + y * y) - 0.00002 * sin(y * x_pi);  
  14.     double theta = atan2(y, x) - 0.000003 * cos(x * x_pi);  
  15.     gg_lon = z * cos(theta);  
  16.     gg_lat = z * sin(theta);  
  17. }  

4.地球坐标系 (WGS-84) 到火星坐标系 (GCJ-02) 的转换算法

  WGS-84GCJ-02的转换(即GPS加偏算法是一个普通青年轻易无法接触到的公开秘密。这个算法的代码在互联网上是公开的,详情请使用Google搜索"wgtochina_lb" 

  整理后的算法代码请参考 https://on4wp7.codeplex.com/SourceControl/changeset/view/21483#353936 。知道了这个算法之后,就可以离线进行Google地图偏移校正,不必像之前那么麻烦。

至于GCJ-02WGS-84的转换(即GPS纠偏),可以使用二分法。


View.OnClickListener onClickListener=new View.OnClickListener() { @Override public void onClick(View view) { switch (view.getId()) { case R.id.baidu_btn: if (MDMUtil.appIsInstalled( getContext(),"com.baidu.BaiduMap")) {//传入指定应用包名 try { double[] gd_lat_lon ; if(RoutingXModel.isGpslatlon){ gd_lat_lon= gaoDeToBaidu(xModel.poc_lon,xModel.poc_lat); }else{ gd_lat_lon= new double[2]; gd_lat_lon[0]=xModel.poc_lon; gd_lat_lon[1]=xModel.poc_lat; } Intent intent = Intent.getIntent("intent://map/direction?" + "destination=latlng:" + gd_lat_lon[1] + "," + gd_lat_lon[0]+ "|name:我的目的地" + //终点 "&mode=driving&" + //导航路线方式 "&src=appname#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getContext().startActivity(intent); //启动调用 } catch (URISyntaxException e) { Log.e("intent", e.getMessage()); } } else {//未安装 //market为路径,id为包名 //显示手机上所有的market商店 Toast.makeText(getContext(), "您尚未安装百度地图", Toast.LENGTH_LONG).show(); Uri uri = Uri.parse("market://details?id=com.baidu.BaiduMap"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); if (intent.resolveActivity(getContext().getPackageManager()) != null){ getContext().startActivity(intent); } } dismiss(); break; case R.id.gaode_btn: if (MDMUtil.appIsInstalled( getContext(),"com.autonavi.minimap")) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); double[] gd_lat_lon ; if(!RoutingXModel.isGpslatlon){ gd_lat_lon= bdToGaoDe(xModel.poc_lat,xModel.poc_lon); }else{ gd_lat_lon= new double[2]; gd_lat_lon[0]=xModel.poc_lon; gd_lat_lon[1]=xModel.poc_lat; } //将功能Scheme以URI的方式传入data Uri uri = Uri.parse("androidamap://navi?sourceApplication=appname&poiname=fangheng&lat;=" + gd_lat_lon[1] + "&lon;=" + gd_lat_lon[0] + "&dev=0&style=4"); intent.setData(uri); //启动该页面即可 getContext().startActivity(intent); } else { Toast.makeText(getContext(), "您尚未安装高德地图", Toast.LENGTH_LONG).show(); Uri uri = Uri.parse("market://details?id=com.autonavi.minimap"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); if (intent.resolveActivity(getContext().getPackageManager()) != null){ getContext().startActivity(intent); } } dismiss(); break; case R.id.tencent_btn: Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); double[] gd_lat_lon ; if(!RoutingXModel.isGpslatlon){ gd_lat_lon= bdToGaoDe(xModel.poc_lat,xModel.poc_lon); }else{ gd_lat_lon= new double[2]; gd_lat_lon[0]=xModel.poc_lon; gd_lat_lon[1]=xModel.poc_lat; } //将功能Scheme以URI的方式传入data Uri uri = Uri.parse("qqmap://map/routeplan?type=drive&to;=我的目的地&tocoord;=" + gd_lat_lon[1]+ "," + gd_lat_lon[0]); intent.setData(uri); if (intent.resolveActivity(getContext().getPackageManager()) != null) { //启动该页面即可 getContext().startActivity(intent); } else { Toast.makeText(getContext(), "您尚未安装腾讯地图", Toast.LENGTH_LONG).show(); } dismiss(); break; case R.id.cancel_btn2: dismiss(); break; } } };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值