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

发布了246 篇原创文章 · 获赞 441 · 访问量 68万+

猜你喜欢

转载自blog.csdn.net/yechaoa/article/details/103384823
今日推荐