iOS调用第三方地图路线导航
做的项目里面有见面功能 所以就需要有导航 导航两种实现方式 (集成第三方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]];
}