做的項目里面有見面功能? 所以就需要有導航? 導航兩種實現方式 (集成第三方SDK、URL跳轉第三方應用)? 項目要求實現直接跳轉 所以接下來做的是實現URL跳轉第三方地圖來導航了
實現如下的效果
項目中實現彈窗讓用戶輸入目的地? 實現導航使雙方見面
思路:把輸入的目的地地理編碼? 獲取到的經緯度再調用第三方的導航
實現中遇到的坑:首先地理編碼得到的地標會不止一個 (這個可以把所有的地標信息展示出來? 讓用戶來選擇是哪一個 可是沒有地圖出現直接這樣展示有點詭異 所以我放棄了這種)
其次遇到的坑:從地標中拿到了經緯度 這樣得到的是地球坐標(也就是GPS使用的是WGS84的坐標系統? 但在我國 出于國家安全考慮 國內所有導航電子地圖必須使用國家測繪局制定的加密坐標系統 即將一個真實的經緯度坐標加密成一個不正確的經緯度坐標 即火星坐標) 當然這樣也可以實現? 只是要考慮到每種地圖的坐標系都不同? 這樣做就是得每種都計算 所以也放棄了
接下來說一下我的實現
實現跳轉首先想到的肯定是配置URL Scheme 和白名單了
百度地圖 URL Scheme: baidumap:// ? ? ? ? ? ? ? ?文檔鏈接
高德地圖 URL Scheme:? iosamap:// ? ? ? ? ? ? ? ? ?文檔鏈接
谷歌地圖 URL Scheme:comgooglemaps:// ? ? ?文檔鏈接
騰訊地圖 URL Scheme:qqmap:// ? ? ? ? ? ? ? ? ? ? ? ?文檔鏈接
配置好白名單之后就要敲代碼了? 如果沒有安裝某個地圖App? 那么對應的選項就不應該出現? 檢測App是否安裝? 只需要調用下面的方法即可
[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"iosamap://"]]
我所做的是讓用戶輸入目的地 調用第三方地圖應用的路線接口 直接把目的地傳進去 用戶可以選擇導航 因為我們的應用做的是附近人的見面 所以我選擇的出行方式是walk 但是騰訊地圖用這種方式是實現不了的 蘋果自帶的地圖也實現不了 需要傳經緯度
通過位置調用地理編碼 為蘋果地圖和騰訊地圖的實現傳入經緯度
///? 地理編碼- (void)geocoderClick:(NSString *)addressString{
// 創建
Geocoder? ? CLGeocoder *geocoder = [CLGeocoder new];
// 調用方法
[geocoder geocodeAddressString:addressString completionHandler:^(NSArray* _Nullable placemarks, NSError * _Nullable error) {
if (placemarks.count == 0 || error) {
[MATools showServerResultInView:self.view withText:@"您輸入的地址有誤,請重新輸入" andImage:nil];
return;
}
CLPlacemark *pm = [placemarks lastObject];
CLLocationCoordinate2D gps = CLLocationCoordinate2DMake(pm.location.coordinate.latitude, pm.location.coordinate.longitude);
self.maps = [self getInstalledMapAppWithAddr:addressString withEndLocation:gps];
[self alertAmaps:gps];
}];
}
下面是我封裝的方法獲取手機上所安裝了的地圖
#pragma mark - 路線規劃方法
- (NSArray *)getInstalledMapAppWithAddr:(NSString *)addrString withEndLocation:(CLLocationCoordinate2D)endLocation
{
NSMutableArray *maps = [NSMutableArray array];
//蘋果地圖
NSMutableDictionary *iosMapDic = [NSMutableDictionary dictionary];
iosMapDic[@"title"] = @"蘋果地圖";
[maps addObject:iosMapDic];
NSString *appStr = NSLocalizedString(@"app_name", nil);
//高德地圖
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"iosamap://"]]) {
NSMutableDictionary *gaodeMapDic = [NSMutableDictionary dictionary];
gaodeMapDic[@"title"] = @"高德地圖";
NSString *urlString = [[NSString stringWithFormat:@"iosamap://path?sourceApplication=%@&sid=BGVIS1&did=BGVIS2&dname=%@&dev=0&t=2",appStr ,addrString] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet? URLQueryAllowedCharacterSet]];
gaodeMapDic[@"url"] = urlString;
[maps addObject:gaodeMapDic];
}
//百度地圖
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://"]]) {
NSMutableDictionary *baiduMapDic = [NSMutableDictionary dictionary];
baiduMapDic[@"title"] = @"百度地圖";
NSString *urlString = [[NSString stringWithFormat:@"baidumap://map/direction?origin=我的位置&destination=%@&mode=walking&src=%@",addrString ,appStr] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet? URLQueryAllowedCharacterSet]];
baiduMapDic[@"url"] = urlString;
[maps addObject:baiduMapDic];
}
//騰訊地圖
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"qqmap://"]]) {
NSMutableDictionary *qqMapDic = [NSMutableDictionary dictionary];
qqMapDic[@"title"] = @"騰訊地圖";
NSString *urlString = [[NSString stringWithFormat:@"qqmap://map/routeplan?from=我的位置&type=walk&tocoord=%f,%f&to=%@&coord_type=1&policy=0",endLocation.latitude , endLocation.longitude ,addrString] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet? URLQueryAllowedCharacterSet]];
qqMapDic[@"url"] = urlString;
[maps addObject:qqMapDic];
}
//谷歌地圖
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"comgooglemaps://"]]) {
NSMutableDictionary *googleMapDic = [NSMutableDictionary dictionary];
googleMapDic[@"title"] = @"谷歌地圖";
NSString *urlString = [[NSString stringWithFormat:@"comgooglemaps://?saddr=&daddr=%@&directionsmode=walking",addrString] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet? URLQueryAllowedCharacterSet]];
googleMapDic[@"url"] = urlString;
[maps addObject:googleMapDic];
}
return maps;
}
彈窗提示用戶所能打開的第三方地圖應用
- (void)alertAmaps:(CLLocationCoordinate2D)gps
{
if (self.maps.count == 0) {
return;
}
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
for (int i = 0; i < self.maps.count; i++) {
if (i == 0) {
[alertVC addAction:[UIAlertAction actionWithTitle:self.maps[i][@"title"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self navAppleMap:gps];
}]];
}else{
[alertVC addAction:[UIAlertAction actionWithTitle:self.maps[i][@"title"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self otherMap:i];
}]];
}
}
[alertVC addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alertVC animated:YES completion:nil];
}
蘋果地圖實現導航的方法 需要導入頭文件#import<CoreLocation/CoreLocation.h> #import<MapKit/MapKit.h>
// 蘋果地圖
- (void)navAppleMap:(CLLocationCoordinate2D)gps
{
MKMapItem *currentLoc = [MKMapItem mapItemForCurrentLocation];
MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:gps addressDictionary:nil]];
NSArray *items = @[currentLoc,toLocation];
NSDictionary *dic = @{
MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeWalking,
MKLaunchOptionsMapTypeKey: @(MKMapTypeStandard),
MKLaunchOptionsShowsTrafficKey: @(YES)
};
[MKMapItem openMapsWithItems:items launchOptions:dic];
}
通過url打開第三方地圖應用
///? 第三方地圖
- (void)otherMap:(NSInteger)index
{
NSDictionary *dic = self.maps[index];
NSString *urlString = dic[@"url"];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}