文档章节

URI跳转方式地图导航的代码实践

Alan_JL
 Alan_JL
发布于 2016/02/26 14:01
字数 1607
阅读 19
收藏 1

手机上的导航方式 分应用内导航应用外导航

  • 应用内导航
    是指使用地图服务提供的SDK(比如高德,百度等等) 直接将导航功能嵌入到我们自己的APP内部
    但是这个方案我个人不喜欢 一是接入要一定的时间 二是增加APP的内存占用

  • 应用外导航
    是以URI跳转的方式(在iOS中就是以URL Scheme的方式) 直接跳到对应的地图APP中 直接利用对方的功能来导航
    这样的优点 一是接入方便 二是不增加自己APP的开销 缺点就是如果用户没有装这个地图应用就没办法使用这个地图的服务

说起应用内导航 当年是被图吧坑惨了 两年前 高德和百度都没有推出导航SDK的时候 市面上好像就只有图吧有应用内导航SDK 所以不得已用了图吧SDK 如今图吧SDK仍是我心中最难用的地图SDK(话说百度的SDK和图吧的SDK设计感觉上是一脉相承的 不晓得是不是百度做地图时挖了一大批图吧的人?) 而且就是这个难用的SDK 竟然还是收费的

而今天要说的 就是第二种 因为网上说的都不是很全面 所以今天把对这种方式的研究结果总结一下

研究

先来看一下我们要达到什么效果 就是当我们点导航的时候 会弹出下面这个选择列表

当然 如果没有安装某个地图APP 那么对应的选项是不会出现的 检测APP是否安装 只要调用下面这个方法就可以了

[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"appurlscheme://"]

关于APP的URL Scheme相关内容这里就不介绍了 大家可以自行去研究

那么我们上图提到了4个地图应用 分别是

  1. 苹果地图

  2. 百度地图

  3. 高德地图

  4. 谷歌地图

这些也是当前我们用得最多的几种地图了(什么 你们说还有腾讯地图? 可惜腾讯地图暂时还不支持URI的方式打开 所以这里就没列出来 等可以用了我会补上)

下面来对比一下几种地图

苹果地图是系统自带的(而且苹果地图最好的方式也不是用URI的方式开打) 所以无需URL Scheme就可以打开的
其次 当跳到地图APP之后可以跳回是一种很好的体验(参考微信的跳转) 但是遗憾的是 苹果地图和百度地图都不支持跳回

接下来我们就回到正题 说一说每种地图的跳转方式

假设我们有一个指定的目的坐标coordinate 而我们自己的APP的URL Scheme是urlScheme 名称是appName

CLLocationCoordinate2D coordinate;NSString *urlScheme;NSString *appName;

苹果地图


苹果地图可以通过openURL的方式打开

NSString *urlString = [[NSString stringWithFormat:@"http://maps.apple.com/?daddr=%f,%f&saddr=slat,slng",coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

但是这种方式 不能以当前位置为起点 所以不符合我们的要求 网上说可以用下面这种方式 但是我没成功

NSString *urlString = [[NSString stringWithFormat:@"http://maps.apple.com/?daddr=%f,%f&saddr=Current+Location",coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

但是苹果提供了另一种方式 使用MKMapItem

MKMapItem *currentLocation = [MKMapItem mapItemForCurrentLocation];MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:nil]];

[MKMapItem openMapsWithItems:@[currentLocation, toLocation] 
               launchOptions:@{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving,                               MKLaunchOptionsShowsTrafficKey: [NSNumber numberWithBool:YES]}];

效果如下

百度地图


NSString *urlString = [[NSString stringWithFormat:@"baidumap://map/direction?origin={{我的位置}}&destination=latlng:%f,%f|name=目的地&mode=driving&coord_type=gcj02",coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

要注意几点

  1. origin={{我的位置}}
    这个是不能被修改的 不然无法把出发位置设置为当前位置

  2. destination=latlng:%f,%f|name=目的地
    name=XXXX name这个字段不能省略 否则导航会失败 而后面的文字则可以随便填

  3. coord_type=gcj02
    coord_type允许的值为bd09ll、gcj02、wgs84 如果你APP的地图SDK用的是百度地图SDK 请填bd09ll 否则 就填gcj02 wgs84你基本是用不上了(关于地图加密这里也不多谈 请自行学习)

效果如下

高德地图


NSString *urlString = [[NSString stringWithFormat:@"iosamap://navi?sourceApplication=%@&backScheme=%@&lat=%f&lon=%f&dev=0&style=2",appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

要注意几点

  1. sourceApplication=%@&backScheme=%@
    sourceApplication代表你自己APP的名称 会在之后跳回的时候显示出来 所以必须填写 backScheme是你APP的URL Scheme 不填是跳不回来的哟

  2. dev=0
    这里填0就行了 跟上面的gcj02一个意思 1代表wgs84 也用不上

效果如下

谷歌地图


NSString *urlString = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving",appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

要注意几点

  1. x-source=%@&x-success=%@
    跟高德一样 这里分别代表APP的名称和URL Scheme

  2. saddr=
    这里留空则表示从当前位置触发

效果如下 在有多条路线的时候 谷歌地图会让你选择其中一条

腾讯地图

既然提到了腾讯地图 那么还是说一下 从网上和官方文档可以得知 大概调用的URI如下

NSString *urlString = [[NSString stringWithFormat:@"qqmap://map/routeplan?type=drive&fromcoord=CurrentLocation&tocoord=%f,%f&coord_type=1&policy=0",coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

但是很遗憾 调用之后出错了 无法导航

效果如下

小结


文中的demo可以在这里找到

相对来说 高德地图做得更用心一点 毕竟也是苹果的服务提供商 而百度相对来说则差一点 谷歌的话 不翻墙还是用不了 而苹果自带的地图则不多说了 功能还是太简单了

这里只是用最简单的方式对导航功能进行了调用 各家的地图其实还有很多参数和功能没有使用到 需要知道的同学可以在文章开头的文档链接中找到详细的描述


© 著作权归作者所有

Alan_JL
粉丝 1
博文 3
码字总数 6096
作品 0
广州
iOS工程师
私信 提问
Android开发:显式/隐式Intent意图跳转Activity总结

显式跳转 在已知包名和类名的情况下常用的跳转方法: 是 nt mIntent = new Intent(); mIn Int etent.setClassName("com.android.settings","com.android.settings.Settings"); mContext.star......

五大三粗
2015/10/19
680
0
《React-Native系列》43、通用容器和导航设计方案

在现阶段我们的RN实践都是基于已发布过的APP,譬如将从某个入口进入的子模块都替换成RN页面。那么我们可以将这个子模块设计成一个通用RN容器,所有的RN页面都在RN容器内部跳转。 RN容器在iOS...

hsbirenjie
2016/11/23
0
0
NavigationService类使用介绍

对于NavigationService类来说在WP7上是十分重要的概念从.Net 3开始出现,主要用于打开新的对话框和相互之间的跳转,NavigationService类的相关成员和方法和浏览器有些相似,同时NavigationS...

鉴客
2012/02/24
616
0
NavigationService简介

对于NavigationService类来说在WP7上是十分重要的概念从.Net 3开始出现,主要用于打开新的对话框和相互之间的跳转,NavigationService类的相关成员和方法和浏览器有些相似,同时 Navigation...

caikezhan
2013/07/08
0
0
Windows Phone 7 - 页面导航

用于Windows Phone 的SilverLight 提供了 PhoneApplicationFrame 和PhoneApplicationPage类,这两个类是微软针对Silverlight for Windows Phone另外封装的,它为导航提供了使得。 PhoneAppli...

阿酷
2011/12/29
496
2

没有更多内容

加载失败,请刷新页面

加载更多

typescript 接口 函数类型 可索引类型

函数类型 可索引类型 数字索引签名 字符串索引签名 数字索引签名返回值 必须是 字符串索引签名返回值的子集 只读索引签名

lilugirl
今天
3
0
Oracle SQL语法实例合集

如需转载请注明出处https://my.oschina.net/feistel/blog/3052024 目的:迅速激活Oracle SQL 参考:《Oracle从入门到精通》 ------------------------------------------------------------......

LoSingSang
今天
2
0
增加 PostgreSQL 服务进程的最大打开文件数

https://serverfault.com/questions/628610/increasing-nproc-for-processes-launched-by-systemd-on-centos-7 要在systemd的配置里加才行...

helloclia
今天
2
0
组合模式在商品分类列表中的应用

在所有的树形结构中最适合的设计模式就是组合模式,我们看看常用商品分类中如何使用。 先定义一个树形结构的商品接口 public interface TreeProduct { List<TreeProduct> allProducts(...

算法之名
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部