作者:裡脊串 授權本站轉載。
前言
之前介紹了我正在做的是一款定位主打的應用。然後最近我們需要做一個定位導航的功能,能夠讓用戶從當前位置導航到指定目的地(默認以駕車的方式導航)。
手機上的導航方式,分應用內導航和應用外導航:
應用內導航
是指使用地圖服務提供的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個地圖應用,分別是:
蘋果地圖
百度地圖
高德地圖
谷歌地圖
這些也是當前我們用得最多的幾種地圖了(什麼,你們說還有騰訊地圖? 可惜騰訊地圖暫時還不支持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 也用不上
效果如下:
退出導航後,會提示是否跳回到APP
谷歌地圖
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可以在這裡找到
相對來說,高德地圖做得更用心一點,畢竟也是蘋果的服務提供商。而百度相對來說則差一點。谷歌的話,不翻牆還是用不了。而蘋果自帶的地圖則不多說了,功能還是太簡單了。
這裡只是用最簡單的方式對導航功能進行了調用,各家的地圖其實還有很多參數和功能沒有使用到。需要知道的同學可以在文章開頭的文檔鏈接中找到詳細的描述。