Android 地圖導航調用百度地圖、高德地圖、騰訊地圖

效果圖

在這裏插入圖片描述 在這裏插入圖片描述在這裏插入圖片描述 在這裏插入圖片描述

前言

爲什麼調用第三方呢?集成在App裏面不行嗎?

  • 接入導航SDK,以百度爲例,apk包體積能增加小几十兆之多,上一版本還是幾兆的apk,迭代一版本直接幾十兆了,落差之大,難以接受。
  • 雖說當下流量不值錢了,但是下載時長越久,客戶丟失率越高。
  • 最關鍵的是,當下地圖並非一家獨大,客戶應該有自主選擇的權利,你集成了百度,但用戶卻鍾愛於高德,這極爲尷尬。
  • 且當下包括微信等一衆主流App都是通過調用第三方地圖來做的,這顯然有一定道理,也是大勢所趨。
  • 坑多,顯然是幹不過別人一個團隊專門來做地圖的,不如站在巨人的肩上。

綜上所訴,優點顯而易見。

座標系

有地圖就有經緯度,有經緯度就扯到座標系,簡單介紹一下座標系。

主要有以下三種:

  • WGS84:一種大地座標系,也是目前廣泛使用的GPS全球衛星定位系統使用的座標系。
  • GCJ02:由中國國家測繪局制訂的地理信息系統的座標系統,是由WGS84座標系經過加密後的座標系。
  • BD09:百度座標系,在GCJ02座標系基礎上再次加密。其中BD09LL表示百度經緯度座標,BD09MC表示百度墨卡托米制座標。

更多的座標知識介紹

百度使用的自家BD09LL座標系,高德和騰訊都是GCJ02即火星座標系,所以相互之間是需要轉換的,不然會有位置偏移。

轉換方法:

    /**
     * BD-09 座標轉換成 GCJ-02 座標
     */
    public static LatLng BD2GCJ(LatLng bd) {
        double x = bd.longitude - 0.0065, y = bd.latitude - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * Math.PI);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * Math.PI);
        double lng = z * Math.cos(theta);
        double lat = z * Math.sin(theta);
        return new LatLng(lat, lng);
    }

    /**
     * GCJ-02 座標轉換成 BD-09 座標
     */
    public static LatLng GCJ2BD(LatLng bd) {
        double x = bd.longitude, y = bd.latitude;
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * Math.PI);
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * Math.PI);
        double tempLon = z * Math.cos(theta) + 0.0065;
        double tempLat = z * Math.sin(theta) + 0.006;
        return new LatLng(tempLat, tempLon);
    }

業務需求

還是簡單描述一下業務需求,點擊一個地址或者按鈕或者地圖上的一個點,彈窗選擇第三方地圖導航,點擊選擇後調用第三方地圖進行導航。

1,點擊按鈕彈窗選擇

    @OnClick({R.id.tv_navigation})
    public void onViewClicked(View view) {
        switch (view.getId()) {
           ...
            case R.id.tv_navigation:
                showMapList();
                break;
        }
    }

2,彈窗

    private void showMapList() {
        final String[] mapNames = {"百度地圖", "高德地圖", "騰訊地圖"};
        final String[] packageNames = {"com.baidu.BaiduMap", "com.autonavi.minimap", "com.tencent.map"};
        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setTitle("請選擇地圖")
                .setItems(mapNames, (dialogInterface, i) -> {
                    boolean installed = isInstalled(packageNames[i]);
                    if (installed) {
                        switch (i) {
                            case 0:
                                gotoBaiDuMap();
                                break;
                            case 1:
                                gotoGaoDeMap();
                                break;
                            case 2:
                                gotoTencentMap();
                                break;
                        }
                    } else {
                        ToastUtil.showCenterToast(mapNames[i] + "未安裝");
                    }
                });
        builder.create().show();
    }

調用之前判斷一下是否安裝:

    /**
     * 檢測所選地圖是否安裝
     */
    private boolean isInstalled(String packageName) {
        PackageManager manager = this.getPackageManager();
        List<PackageInfo> installedPackages = manager.getInstalledPackages(0);
        if (installedPackages != null) {
            for (PackageInfo info : installedPackages) {
                if (info.packageName.equals(packageName))
                    return true;
            }
        }
        return false;
    }

3,調用地圖

別忘了 申請權限。

百度地圖

  • 參數說明:
    在這裏插入圖片描述

參數以字符串拼接的方式即可,這裏用StringBuffer拼接,比String易讀些。

  • 調用示例:
    private void gotoBaiDuMap() {
        // 駕車導航
        StringBuffer sb = new StringBuffer("baidumap://map/navi")
                .append("?coord_type=gcj02")
                .append("&query=").append("長寧圖書館")
                .append("&src=").append(this.getPackageName());
        Intent intent = new Intent();
        intent.setData(Uri.parse(sb.toString()));
        startActivity(intent);
    }

高德地圖

  • 參數說明:
    在這裏插入圖片描述
  • 調用示例:
    private void gotoGaoDeMap() {
        LatLng endPoint = BD2GCJ(new LatLng(31.220567, 121.395174));//轉換座標系
        StringBuffer sb = new StringBuffer("androidamap://navi")
                .append("?sourceApplication=").append(getString(R.string.app_name))
                .append("&lat=").append(endPoint.latitude)
                .append("&lon=").append(endPoint.longitude)
                .append("&dev=0");
        Intent intent = new Intent();
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setPackage("com.autonavi.minimap");
        intent.setData(Uri.parse(sb.toString()));
        startActivity(intent);
    }

騰訊地圖

  • 參數說明:
    在這裏插入圖片描述
  • 調用示例:
    private void gotoTencentMap() {
        LatLng startPoint = BD2GCJ(new LatLng(mLatitude, mLongitude));//座標轉換
        LatLng endPoint = BD2GCJ(new LatLng(31.220567, 121.395174));//座標轉換
        StringBuffer sb = new StringBuffer("qqmap://map/routeplan")
                .append("?type=drive")
                .append("&from=我的位置")
                .append("&fromcoord=").append(startPoint.latitude).append(",").append(startPoint.longitude)
                .append("&to=長寧圖書館")
                .append("&tocoord=").append(endPoint.latitude).append(",").append(endPoint.longitude)
                .append("&referer=你的key");
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(Uri.parse(sb.toString()));
        startActivity(intent);
    }

注意,騰訊地圖這裏的from和to參數雖然可以省略,但是地圖上就不顯示地址了,默認是 地圖上的點,而且referer參數需要申請開發者key。
在這裏插入圖片描述

文檔


https://blog.csdn.net/Ever69/article/details/82427085

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章