效果
终于有点时间了,将项目中调用外部地图(高德和百度)做个总结吧!
干货
在做这个需求前首先要知道一些东西。
导航一定有起点和终点,一般起点和终点有两种形式,坐标和名称。
坐标一般常见的有三种火星坐标、百度坐标、高德坐标
通过百度定位或者通过名字反编码出来的坐标都是百度坐标
通过高德定位或者通过名字反编码出来的坐标都是高德坐标,不是火星坐标,我看资料的时候总是见别人说是火星坐标,但是高德sdk里面说了是高德坐标,见
https://lbs.amap.com/api/android-location-sdk/guide/android-location/getlocation#stop-location
5.导航参数中如果有坐标,坐标的优先级大于名字
我从下面6个不同的方向测试了下,到底怎样写请求参数准确最高
1.起点终点都是坐标使用高德
2.起点终点都是名称使用高德
3.当前位置到终点使用高德
4.起点终点都是坐标使用百度
5.起点终点都是名称使用百度
6.当前位置到终点使用百度
我们做项目一般都只是会集成其中的一个 要么百度要么高德sdk,所以其中只要牵扯到坐标都是相关的坐标系,我这里为了省事,使用坐标拾取来获取坐标测试
先来测试前面三个调用高德地图的,我用高德拾取 弄了两个位置坐标,如下
private static final double LATITUDE_A = 28.1903; //起点纬度
private static final double LONGTITUDE_A = 113.031738; //起点经度
private static final double LATITUDE_B = 28.187519; //终点纬度
private static final double LONGTITUDE_B = 113.029713; //终点经度
先将这个方法写出来,判断客户端是否安装
/**
* 判断是否安装目标应用
* @param packageName 目标应用安装后的包名
* @return 是否已安装目标应用
*/
private boolean isInstallByread(String packageName) {
return new File("/data/data/" + packageName).exists();
}
对于第一种情况,使用起点和终点的坐标如下
/**
* 确定起终点坐标BY高德
*/
void setUpGaodeAppByLoca(){
try {
Intent intent = Intent.getIntent("androidamap://route?sourceApplication=softname&slat="+LATITUDE_A+"&slon="+LONGTITUDE_A+"&sname="+"万家丽国际Mall"+"&dlat="+LATITUDE_B+"&dlon="+LONGTITUDE_B+"&dname="+"东郡华城广场|A座"+"&dev=0&m=0&t=1");
if(isInstallByread("com.autonavi.minimap")){
startActivity(intent);
Log.e(TAG, "高德地图客户端已经安装") ;
}else {
Log.e(TAG, "没有安装高德地图客户端") ;
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
可以发现,其中的起点和终点都有坐标并且都有名称,运行后发现效果并不是很好,因为有一个公交规划路线没有,但是其实是有的,下面的方法测试时可以看到,这样就知道坐标的优先级要比名字高
第二个情况,起点终点都是名称
/**
* 确认起终点名称BY高德
*/
void setUpGaodeAppByName(){
try {
Intent intent = Intent.getIntent("androidamap://route?sourceApplication=softname"+"&sname="+"万家丽国际Mall"+"&dname="+"东郡华城广场|A座"+"&dev=0&m=0&t=1");
if(isInstallByread("com.autonavi.minimap")){
startActivity(intent);
Log.e(TAG, "高德地图客户端已经安装") ;
}else {
Log.e(TAG, "没有安装高德地图客户端") ;
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
通过这种方法所有的导航规划路线都可以查到,比较不错,这里有个小技巧,起点和终点的名称最好不要写的太广了,举个例子这里的起点写的是万家丽国际mall 如果你写成湖南省长沙市芙蓉区万家丽国际mall,很容易出问题,这里的问题指找不到导航规划路线,本人就是在这里对地址没处理导致一直找不到原因
第三个情况实际上是最好用的方法,如下
/**
* 我的位置BY高德
*/
void setUpGaodeAppByMine(){
try {
Intent intent = Intent.getIntent("androidamap://route?sourceApplication=softname&sname=我的位置&dlat="+LATITUDE_B+"&dlon="+LONGTITUDE_B+"&dname="+"东郡华城广场|A座"+"&dev=0&m=0&t=1");
if(isInstallByread("com.autonavi.minimap")){
startActivity(intent);
Log.e(TAG, "高德地图客户端已经安装") ;
}else {
Log.e(TAG, "没有安装高德地图客户端") ;
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
这个方法好用而且实际,毕竟导航一般都是通过当前位置去终点,使用上面的方法直接写入参数 我的位置 就可以了,这样进入高德或者百度地图app中直接就给定位了获取到当前位置了。不用在自己的项目中通过sdk获取到当前位置的坐标然后传入参数,既不准确又麻烦。
下面的是调用百度地图app,同样通过百度拾取 取了两个位置的百度坐标
//----------------以下都是百度坐标系的坐标------------------//
private static final double LATITUDE_QIDIAN = 28.196744; //起点纬度
private static final double LONGTITUDE_QIDIAN = 113.037904; //起点经度
private static final double LATITUDE_ZHONGDIAN = 28.193159; //终点纬度
private static final double LONGTITUDE_ZHONGDIAN = 113.036427; //终点经度
第四种情况,使用起点和终点的坐标
/**
* 注意下面的起终点坐标都是百度坐标,如果使用高德坐标系有很大的误差
*/
void setUpBaiduAPPByLoca(){
try {
Intent intent = Intent.getIntent("intent://map/direction?origin=latlng:"+LATITUDE_QIDIAN+","+LONGTITUDE_QIDIAN+"|name:万家丽国际Mall&destination=latlng:"+LATITUDE_ZHONGDIAN+","+LONGTITUDE_ZHONGDIAN+"|name:东郡华城广场|A座&mode=driving&src=yourCompanyName|yourAppName#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end");
if(isInstallByread("com.baidu.BaiduMap")){
startActivity(intent);
Log.e(TAG, "百度地图客户端已经安装") ;
}else {
Log.e(TAG, "没有安装百度地图客户端") ;
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
这里特别要注意,比如项目中使用高德sdk,获取坐标后上面的方法导航会有很大的误差(相对的),毕竟调用百度地图已经进入了app中,在百度地图里面使用高德坐标系应该也应该是有误差的,可以将上面的两个高德坐标系的坐标放上面的方法试一试,话说我开始还想过要不要将高德坐标系的坐标换算成火星坐标 然后在换算成百度坐标 再写入上面的方法……
第五种情况,起点和终点两个名称
/**
* 通过起终点名字使用百度地图
*/
void setUpBaiduAPPByName(){
try {
Intent intent = Intent.getIntent("intent://map/direction?origin=万家丽国际Mall&destination=东郡华城广场|A座&mode=driving&src=yourCompanyName|yourAppName#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end");
if(isInstallByread("com.baidu.BaiduMap")){
startActivity(intent);
Log.e(TAG, "百度地图客户端已经安装") ;
}else {
Log.e(TAG, "没有安装百度地图客户端") ;
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
这个url我测试了很多遍才试出来,开始一直搞错了,虽然可以进入百度app但是起点和终点名称总是出错的。
第六种情况,当前位置到终点导航规划路线
/**
* 我的位置到终点通过百度地图
*/
void setUpBaiduAPPByMine(){
try {
Intent intent = Intent.getIntent("intent://map/direction?origin=我的位置&destination=东郡华城广场|A座&mode=driving&src=yourCompanyName|yourAppName#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end");
if(isInstallByread("com.baidu.BaiduMap")){
startActivity(intent);
Log.e(TAG, "百度地图客户端已经安装") ;
}else {
Log.e(TAG, "没有安装百度地图客户端") ;
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
这里和第三种高德一样的,比较好
ok,已经完了可以根据自己的实际情况来选择,或者通过上面url的规律自己拼接。
项目源码