Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Android百度地图、高德地图、腾讯地图导航路线规划问题

$
0
0
      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时,有则启动,没有则转网页地图。


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, "网页版地图导航");
}
另外此处是高德地图对其他坐标进行转换的api:

   Demo代码地址:









作者:zengke1993 发表于2016/8/17 16:02:19 原文链接
阅读:15 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>