用過(guò)微信的應(yīng)該都知道這個(gè)功能,對(duì)方發(fā)一個(gè)位置給你,點(diǎn)進(jìn)去地圖展示對(duì)方跟你的當(dāng)前位置,界面提供了選擇各個(gè)地圖應(yīng)用進(jìn)行導(dǎo)航,更好這次需求也要搞這個(gè)功能。
這個(gè)功能實(shí)現(xiàn)不難,個(gè)人感覺(jué)比應(yīng)用內(nèi)嵌入第三方地圖導(dǎo)航SDK用起來(lái)更舒服,更接地氣,逼格也高點(diǎn),主要要的是簡(jiǎn)單(畢竟人家啥都處理好了)。
上項(xiàng)目效果圖(還是想吐槽下傻逼的產(chǎn)品,為啥不直接照搬微信的界面,至少比自己的好看)
這里有一個(gè)重點(diǎn),主要是彈出的選擇框的選項(xiàng)并不是固定的,而是根據(jù)你手機(jī)上有沒(méi)有安裝這個(gè)地圖應(yīng)用,沒(méi)有就不會(huì)出現(xiàn)。
這里就要用到
- (BOOL)canOpenURL:(NSURL*)urlNS_AVAILABLE_IOS(3_0);
判斷手機(jī)上有沒(méi)有安裝該地圖應(yīng)用。
所以要知道地圖應(yīng)用的url?Scheme。
這里提供了幾個(gè)常用地圖應(yīng)用的url?Scheme:
baidumap//百度地圖
iosamap//高德地圖
comgooglemaps//谷歌地圖
qqmap//騰訊地圖
….//其他地圖省略
蘋果地圖不需要,因?yàn)樗翘O果地圖啊,這樣也好,能保證沒(méi)有安裝其他地圖app,至少還有一個(gè)蘋果地圖,而且蘋果地圖在IOS9也做的越來(lái)越好了,本身API提供了一個(gè)跳轉(zhuǎn)打開(kāi)方法。
這里插入一個(gè)小細(xì)節(jié),在IOS9之后,蘋果進(jìn)一步完善了安全機(jī)制,必須在plist里面設(shè)置url scheme白名單,不然無(wú)法打開(kāi)對(duì)應(yīng)的應(yīng)用
前方高能,重點(diǎn)來(lái)了?。。?!
這里我抽了個(gè)方法返回支持導(dǎo)航的地圖信息數(shù)組:
#pragmamark - 導(dǎo)航方法
- (NSArray*)getInstalledMapAppWithEndLocation:(CLLocationCoordinate2D)endLocation
{
NSMutableArray*maps = [NSMutableArrayarray];
//蘋果地圖
NSMutableDictionary*iosMapDic = [NSMutableDictionarydictionary];
iosMapDic[@"title"] =@"蘋果地圖";
? ? [maps addObject:iosMapDic];
//百度地圖
if([[UIApplicationsharedApplication] canOpenURL:[NSURLURLWithString:@"baidumap://"]]) {
NSMutableDictionary*baiduMapDic = [NSMutableDictionarydictionary];
baiduMapDic[@"title"] =@"百度地圖";
NSString*urlString = [[NSStringstringWithFormat:@"baidumap://map/direction?origin={{我的位置}}&destination=latlng:%f,%f|name=北京&mode=driving&coord_type=gcj02",endLocation.latitude,endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
baiduMapDic[@"url"] = urlString;
? ? ? ? [maps addObject:baiduMapDic];
? ? }
//高德地圖
if([[UIApplicationsharedApplication] canOpenURL:[NSURLURLWithString:@"iosamap://"]]) {
NSMutableDictionary*gaodeMapDic = [NSMutableDictionarydictionary];
gaodeMapDic[@"title"] =@"高德地圖";
NSString*urlString = [[NSStringstringWithFormat:@"iosamap://navi?sourceApplication=%@&backScheme=%@&lat=%f&lon=%f&dev=0&style=2",@"導(dǎo)航功能",@"nav123456",endLocation.latitude,endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
gaodeMapDic[@"url"] = urlString;
? ? ? ? [maps addObject:gaodeMapDic];
? ? }
//谷歌地圖
if([[UIApplicationsharedApplication] canOpenURL:[NSURLURLWithString:@"comgooglemaps://"]]) {
NSMutableDictionary*googleMapDic = [NSMutableDictionarydictionary];
googleMapDic[@"title"] =@"谷歌地圖";
NSString*urlString = [[NSStringstringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving",@"導(dǎo)航測(cè)試",@"nav123456",endLocation.latitude, endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
googleMapDic[@"url"] = urlString;
? ? ? ? [maps addObject:googleMapDic];
? ? }
//騰訊地圖
if([[UIApplicationsharedApplication] canOpenURL:[NSURLURLWithString:@"qqmap://"]]) {
NSMutableDictionary*qqMapDic = [NSMutableDictionarydictionary];
qqMapDic[@"title"] =@"騰訊地圖";
NSString*urlString = [[NSStringstringWithFormat:@"qqmap://map/routeplan?from=我的位置&type=drive&tocoord=%f,%f&to=終點(diǎn)&coord_type=1&policy=0",endLocation.latitude, endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
qqMapDic[@"url"] = urlString;
? ? ? ? [maps addObject:qqMapDic];
? ? }
returnmaps;
}
這里只要傳入提供的坐標(biāo)點(diǎn),就打包好了需要的信息。
什么,你說(shuō)彈出?那玩意自己去寫,不想寫,自己去找,不然就用系統(tǒng)的actionSheet。
#pragmamark LCActionSheetDelegate
-(void)actionSheet:(LCActionSheet *)actionSheet didClickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex !=-1) {
if(buttonIndex ==0) {
[selfnavAppleMap];
return;
? ? ? ? }
NSDictionary*dic =self.maps[buttonIndex];
NSString*urlString = dic[@"url"];
[[UIApplicationsharedApplication] openURL:[NSURLURLWithString:urlString]];
? ? }
}
//蘋果地圖
- (void)navAppleMap
{
CLLocationCoordinate2Dgps = [JZLocationConverter bd09ToWgs84:self.destinationCoordinate2D];
MKMapItem*currentLoc = [MKMapItemmapItemForCurrentLocation];
MKMapItem*toLocation = [[MKMapItemalloc] initWithPlacemark:[[MKPlacemarkalloc] initWithCoordinate:gps addressDictionary:nil]];
NSArray*items = @[currentLoc,toLocation];
NSDictionary*dic = @{
MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsMapTypeKey: @(MKMapTypeStandard),
MKLaunchOptionsShowsTrafficKey: @(YES)
? ? ? ? ? ? ? ? ? ? ? ? ? };
[MKMapItemopenMapsWithItems:items launchOptions:dic];
}
最后結(jié)尾還有個(gè)小插曲,由于我們后臺(tái)給的目標(biāo)經(jīng)緯度是百度坐標(biāo)系,項(xiàng)目用的也是百度地圖,界面上展示是沒(méi)啥問(wèn)題了,但是由于不同的地圖有自己的坐標(biāo)系,而要用它們進(jìn)行導(dǎo)航,那傳給它們的必須是標(biāo)準(zhǔn)的經(jīng)緯度坐標(biāo),這就蛋疼了,百度這坑爹只有提供了標(biāo)準(zhǔn)的轉(zhuǎn)成它自己的坐標(biāo)系,而沒(méi)有提供反轉(zhuǎn)的方法,去官網(wǎng)開(kāi)發(fā)者社區(qū)發(fā)帖,也沒(méi)用,只是回答你沒(méi)有提供,所以我猜傳言百度地圖SDK是實(shí)習(xí)生寫的還是有一定的可靠性。
沒(méi)辦法,只能求爺爺告奶奶,去查找對(duì)應(yīng)的資料,還是找到一個(gè)第三方的轉(zhuǎn)換方法https://github.com/JackZhouCn/JZLocationConverter,但是仍然有一定的偏差,能接受的就接受吧。