本文转载至 http://adad184.com/2015/08/11/practice-in-mapview-navigation-with-URI/

前言

之前介绍了我正在做的是一款定位主打的应用 然后最近我们需要做一个定位导航的功能 能够让用户从当前位置导航到指定目的地(默认以驾车的方式导航)

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

  • 应用内导航
    是指使用地图服务提供的SDK(比如高德,百度等等) 直接将导航功能嵌入到我们自己的APP内部
    但是这个方案我个人不喜欢 一是接入要一定的时间 二是增加APP的内存占用
  • 应用外导航
    是以URI跳转的方式(在iOS中就是以URL Scheme的方式) 直接跳到对应的地图APP中 直接利用对方的功能来导航
    这样的优点 一是接入方便 二是不增加自己APP的开销 缺点就是如果用户没有装这个地图应用就没办法使用这个地图的服务

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

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

研究

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

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

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

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

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

  1. 苹果地图
  2. 百度地图
  3. 高德地图
  4. 谷歌地图

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

下面来对比一下几种地图

地图 URL Scheme 文档 是否可以跳回到APP
苹果地图   文档
百度地图 baidumap:// 文档
高德地图 iosamap:// 文档
谷歌地图 comgooglemaps:// 文档

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

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

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

1
2
3
CLLocationCoordinate2D coordinate;
NSString *urlScheme;
NSString *appName;

苹果地图


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

1
2
3
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]];

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

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

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

1
2
3
4
5
6
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]}];

效果如下

百度地图


1
2
3
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你基本是用不上了(关于地图加密这里也不多谈 请自行学习)

效果如下

高德地图


1
2
3
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 也用不上

效果如下

退出导航后 会提示是否跳回到APP

谷歌地图


1
2
3
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如下

1
2
3
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]];

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

效果如下

补充说明

iOS9发布以后 很多朋友发现openURL的方式都失败了 这是因为iOS对openURL做了进一步限制
不过适配起来也很简单 在plist中加一条名为LSApplicationQueriesSchemes的Array类型的Key 并把上述地图的scheme添加进去就行了 如图

小结


文中的demo可以在这里找到

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

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

URI跳转方式地图导航的代码实践的更多相关文章

  1. iOS_URI跳转方式多种地图导航的代码实践

    先来看一下我们要达到什么效果,就是当我们点导航的时候,会弹出下面这个选择列表. 当然,如果没有安装某个地图APP,那么对应的选项是不会出现的.检测APP是否安装,只要调用下面这个方法就可以了 [[UI ...

  2. iOS判断并使用百度地图 高德地图 导航 (使用URI,不集成sdk)

    [objc] view plaincopy  1. BOOL hasBaiduMap = NO;   2.         BOOL hasGaodeMap = NO;   3.            ...

  3. Windows phone 8 学习笔记(8) 定位地图导航(转)

    Windows phone 8 已经不使用自家的bing地图,新地图控件可以指定制图模式.视图等.bing地图的定位误差比较大,在模拟器中测试新地图貌似比较理想.本节主要讲解下位置服务以及新地图控件的 ...

  4. Windows phone 8 学习笔记(8) 定位地图导航

    原文:Windows phone 8 学习笔记(8) 定位地图导航 Windows phone 8 已经不使用自家的bing地图,新地图控件可以指定制图模式.视图等.bing地图的定位误差比较大,在模 ...

  5. Android studio 百度地图开发(3)地图导航

    Android studio 百度地图开发(3)地图导航 email:chentravelling@163.com 开发环境:win7 64位,Android Studio,请注意是Android S ...

  6. ionic3 应用内打开第三方地图导航 百度 高德

    1.安装检测第三方APP是否存在的插件 cordova plugin add cordova-plugin-appavailability --save npm install --save @ion ...

  7. 移动端app跳转百度地图

    http://lbsyun.baidu.com/index.php?title=uri/guide/helloworld(百度地图调起URI API)开发者只需按照接口规范构造一条标准的URI,便可在 ...

  8. 支付宝小程序室内地图导航开发-支付宝小程序JS加载esmap地图

    如果是微信小程序开发,请参考微信小程序室内地图导航开发-微信小程序JS加载esmap地图文章 一.在支付宝小程序里显示室内三维地图 需要满足的两个条件 调用ESMap室内地图需要用到小程序web-vi ...

  9. 天津政府应急系统之GIS一张图(arcgis api for flex)讲解(四)地图导航控件模块

    config.xml文件的配置如下: <widget left="10" top="50" config="widgets/Navigation ...

随机推荐

  1. Mac和Linux下pip更换源

    cd ~mkdir .pip vim .pip/pip.conf 在pip.conf中写入 [global]timeout = 6000index-url = https://pypi.tuna.ts ...

  2. python shlex 模块

    shkex 模块最常见的用法就是其中的split 函数,split 函数提供了和shell 处理命令行参数时一致的分隔方式 代码示例: shlex.split("python -u a.py ...

  3. 实现linux服务器之间无密码互访

    最近老是在群里看到许多同学问,linux之间无密码互访怎么弄啊,百度的看得我头晕之类的,所以我就写写怎么样在两台linux服务器之间实现无密码互访,也就是让它们互相信任的意思,废话不多说,直接上菜. ...

  4. js以类似jquery的模式绑定事件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. SpringCloud 集锦

    一.SpringCloud和Dubbo SpringCloud整合了一套较为完整的微服务解决方案框架,而Dubbo只是解决了微服务的几个方面的问题. content Dubbo SpringCloud ...

  6. linux 上安裝lnmp

    1.確保有一台服務器可以正常運行 2.熟練知道一些基本的命令 3.這裡我以lnmp集成環境為例 https://lnmp.org/install.html 4.安裝大約30分鐘左右 5.安裝完畢,訪問 ...

  7. bootstrapValidator 表单验证

    官网下载地址:http://plugins.jquery.com/bootstrapValidator/ html代码 <!DOCTYPE html> <html> <h ...

  8. 怎么使用ABBYY中的Bates编号

    ABBYY PDF Transformer+ 可让您将 Bates 编号添加到 PDF 文档.Bates 编号可方便文档搜索和检索,并更加有利于电子归档.下面小编给小伙伴们讲讲ABBYY PDF Tr ...

  9. SQL语句:一个表,通过一个字段查找另外一个字段不相同值

    select * from [dbo].[Sys_MemberKey] a where exists(select * from [Sys_MemberKey] b where a.FMachineC ...

  10. 源码分析四(HashMap与HashTable的区别 )

    这一节看一下HashMap与HashTable这两个类的区别,工作一段时间的程序员都知道, hashmap是非线程安全的,而且key值和value值允许为null,而hashtable是非线程安全的, ...