Android百度地图、高德地图、腾讯地图导航路线规划问题
在最近的项目中,需求是用户选择某个地址需要进行导航时,弹出百度地图、高德地图和腾讯地图让用户选择。如果该用户手机中已安装对应的地图App,则启动对应软件进行导航,否则跳转到网页版的地图进行导航。
如下为各个地图效果:
百度地图高德地图
腾讯地图
一开始做时,这不就简单吗,坐标嘛,都是一样的,去各个地图平台找到对应的URL api,传入当前的坐标和目的地址的坐标(当前使用的是百度地图的SDK)。利用Intent跳转不就行了嘛。完成之后才发现,too young too simple,原谅我对国家的安全知识了解有点少。坐标各地图是不一定相同的,地址是有偏移的。
下面是我找弄度娘来的(为什么不用google呢?):
我们平时用到的地球坐标系统,叫做WGS-84坐标,这个是国际通用的“准确”的坐标系统。国家保密插件,其实就是对真实坐标系统进行人为的加偏处理,即为GCJ-02坐标,戏称“火星坐标”。于是,我们有了下面的东西:
- 地球坐标:指WGS84坐标系统
- 火星坐标:指使用国家保密插件人为偏移后的坐标
- 地球地图:指与地球坐标对应的客观真实的地图
- 火星地图:指经过加密偏移后的,与火星坐标对应的地图
国内出版的各种地图系统(包括电子形式),必须至少采用GCJ-02对地理位置进行首次加密。于是,
- 谷歌地图的大陆地图、高德国内地图采用GCJ-02对地图进行加偏。
- 百度地图更是进一步发挥了天朝特色,除了GCJ-02加偏,自己又在此基础上继续进行加偏,相应的坐标称为BD-09坐标。
各地图厂商使用的坐标系:
- 火星坐标 GCJ02坐标系
- iOS 地图
- Gogole地图
- 搜搜(腾讯)、阿里云、高德地图
- 地球坐标 WGS84坐标系
- Google 卫星地图(国外地图应该都是……)
- 百度坐标 BD09坐标系
- 百度地图
好了,弄懂了之后。也很简单嘛,用的是百度地图SDK,那手上的坐标当然也是百度的。那调用高德和腾讯地图时,
只需把百度地图的坐标转换为火星坐标就行啊。
下面继续是度来的一个转换算法,原创地址:http://blog.csdn.net/myfmyfmyfmyf/article/details/45717797。
public class MapTranslateUtils { /** * 坐标转换,腾讯地图(火星坐标)转换成百度地图坐标 * @param lat 腾讯纬度 * @param lon 腾讯经度 * @return 返回结果:经度,纬度 */ public static double[] map_hx2bd(double lat, double lon){ double bd_lat; double bd_lon; double x_pi=3.14159265358979324; double x = lon, y = lat; double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi); bd_lon = z * Math.cos(theta) + 0.0065; bd_lat = z * Math.sin(theta) + 0.006; double[] doubles = new double[]{bd_lat,bd_lon}; System.out.println("bd_lat:"+bd_lat); System.out.println("bd_lon:"+bd_lon); return doubles; } /** * 坐标转换,百度地图坐标转换成腾讯地图坐标 * @param lat 百度坐标纬度 * @param lon 百度坐标经度 * @return 返回结果:纬度,经度 */ public static double[] map_bd2hx(double lat, double lon){ double tx_lat; double tx_lon; double x_pi=3.14159265358979324; double x = lon - 0.0065, y = lat - 0.006; double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); tx_lon = z * Math.cos(theta); tx_lat = z * Math.sin(theta); double[] doubles = new double[]{tx_lat,tx_lon}; return doubles; } }
<span style="font-family: 微软雅黑; background-color: rgb(255, 255, 255);"> ok,现在百度地图坐标系,火星坐标系都在手了。开干。</span>
那首先要创建 一个webView页面:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical">
<com.zk.common.TitleBarView
android:id="@+id/titleBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/title_bg"/>
<WebView
android:id="@+id/web_wv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
WebView的Activity:
public class WebViewActivity extends AppCompatActivity { private WebView detailsWebView; private String mUrl; private Handler handler; private ProgressDialog pd; private String mTitle; public static void launch(Activity activity, String url, String title) { Intent intent = new Intent(activity, WebViewActivity.class); intent.putExtra("url", url); intent.putExtra("title", title); activity.startActivity(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web_view); mUrl = this.getIntent().getStringExtra("url"); mTitle = this.getIntent().getStringExtra("title"); detailsWebView = (WebView) findViewById(R.id.web_wv); detailsWebView.getSettings().setJavaScriptEnabled(true); detailsWebView.getSettings().setDomStorageEnabled(true); detailsWebView.requestFocus(View.FOCUS_DOWN); detailsWebView.getSettings().setUserAgentString("User-Agent"); detailsWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return false; } }); // 设置web视图客户端 detailsWebView.setWebChromeClient(new WebChromeClient() { @Override public void onProgressChanged(WebView view, int progress) {// 载入进度改变而触发 if (progress == 100) { handler.sendEmptyMessage(1);// 如果全部载入,隐藏进度对话框 } detailsWebView.setVisibility(View.VISIBLE); } super.onProgressChanged(view, progress); } @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); } }); detailsWebView.setVisibility(View.GONE); pd = new ProgressDialog(this); pd.setProgressStyle(ProgressDialog.STYLE_SPINNER); pd.setMessage("数据载入中,请稍候!"); handler = new Handler() { public void handleMessage(Message msg) {// 定义一个Handler,用于处理下载线程与UI间通讯 super.handleMessage(msg); if (!Thread.currentThread().isInterrupted()) { switch (msg.what) { case 0: pd.show();// 显示进度对话框 break; case 1: pd.hide();// 隐藏进度对话框,不可使用dismiss()、cancel(),否则再次调用show()时,显示的对话框小圆圈不会动。 break; } } } }; loadurl(detailsWebView, mUrl); } public void loadurl(final WebView view, final String url) { handler.post(new Runnable() { @Override public void run() { handler.sendEmptyMessage(0); view.loadUrl(url);// 载入网页 } }); } }
首先,选择判断是否安装对应地图App时,有则启动,没有则转网页地图。
1、百度地图:开发平台URL地址:http://developer.baidu.com/map/wiki/index.php?title=uri/api/android
private void selectBaidu() { this.dismiss(); try { //调起App if (isInstallByread("com.baidu.BaiduMap")) { Intent intent = Intent.getIntent("intent://map/direction?origin=latlng:" + nowLat + "," + nowLng + "|name:&destination=" + desAddress + "&mode=driving®ion=" + "我的位置" + "&referer=Autohome|GasStation#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end"); mActivity.startActivity(intent); } else { /*String url = "http://api.map.baidu.com/direction?origin=latlng:" + mLatitude + "," + mLongitude + "|name:&destination=" + mDestination + "&mode=driving&output=html&src=天工项目共建"; WebViewActivity.launch(getActivity(), url, "网页版地图导航");*/ Toast.makeText(mActivity, "如果您没有安装百度地图APP," + "可能无法正常使用导航,建议选择其他地图", Toast.LENGTH_SHORT).show(); } } catch (URISyntaxException e) { e.printStackTrace(); } }
2、高德地图
: 开发平台URL地址: http://lbs.amap.com/api/uri-api/android-uri-explain/
private void selectGaode() { this.dismiss(); double[] txDesLatLng = MapTranslateUtils.map_bd2hx(desLat, desLng); double[] txNowLatLng = MapTranslateUtils.map_bd2hx(nowLat, nowLng); if (isInstallByread("com.autonavi.minimap")) { try { Intent intentOther = new Intent("android.intent.action.VIEW", Uri.parse("androidamap://navi?sourceApplication=amap&lat=" + desLat + "&lon=" + desLng + "&dev=1&stype=0")); intentOther.setPackage("com.autonavi.minimap"); intentOther.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); mActivity.startActivity(intentOther); } catch (Exception e) { String url = "http://m.amap.com/?from=" + nowLat + "," + nowLng + "(from)&to=" + desLat + "," + desLng + "(to)&type=0&opt=1&dev=0"; WebViewActivity.launch(mActivity, url, "网页版地图导航"); } } else { String url = "http://m.amap.com/?from=" + txNowLatLng[0] + "," + txNowLatLng[1] + "(from)&to=" + txDesLatLng[0] + "," + txDesLatLng[1] + "(to)&type=0&opt=1&dev=0"; WebViewActivity.launch(mActivity, url, "网页版地图导航"); } }
需要注意的是上面的dev参数,如果你传入的已经是火星坐标,参数为0就行,如果你传入的是高德坐标,则传入1。这里是个坑,要注意一下。
3、腾讯地图: 开发平台URL地址: http://lbs.qq.com/uri_v1/guide-route.html
看官方介绍目前腾讯还不支持直接启动腾讯地图App。
所以只能调用web的地图:
private void selectTencent() { this.dismiss(); double[] txDesLatLng = MapTranslateUtils.map_bd2hx(desLat, desLng); double[] txNowLatLng = MapTranslateUtils.map_bd2hx(nowLat, nowLng); String url = "http://apis.map.qq.com/uri/v1/routeplan?type=drive&from=&fromcoord=" + txNowLatLng[0] + "," + txNowLatLng[1] + "&to=&tocoord=" + txDesLatLng[0] + "," + txDesLatLng[1] + "&policy=0&referer=myapp"; WebViewActivity.launch(mActivity, url, "网页版地图导航"); }
作者:zengke1993 发表于2016/8/17 16:02:19 原文链接
阅读:15 评论:0 查看评论