导航

在iOS系统中,实现导航基本有以下三种方法:

  • 可以将需要导航的位置丢给系统自带的APP进行导航
  • 发送网络请求到服务器获取导航数据, 自己手动绘制导航
  • 利用三方SDK实现导航(百度)

一、系统自带APP导航

  1. 获取用户输入的起点和终点
  2. 懒加载CLGeocoder地理编码对象
  3. 利用CLGeocoder对象进行地理编码获取到地标对象CLPlacemark
[self.geocoder geocodeAddressString:self.startText.text
completionHandler:^(NSArray *placemarks, NSError *error {
    // 获取开始位置的地标
    CLPlacemark *startPlace = [placemarks firstObject];

    // 获取结束位置的地标
    [self.geocoder geocodeAddressString:self.destinationText.text
completionHandler:^(NSArray *placemarks, NSError *error) {
        CLPlacemark *endPlace = [placemarks firstObject];

        // 开始导航
        [self startPlacemarks:startPlace
endPlacemark:endPlace];
  }];
}];

- (void)startPlacemarks:(CLPlacemark *)startPlacemark endPlacemark:(CLPlacemark *)endPlacemark {
    // 创建起点
    MKPlacemark *start = [[MKPlacemark alloc] initWithPlacemark:startPlacemark];

    MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:start];

    // 创建终点
    MKPlacemark *end = [[MKPlacemark alloc] initWithPlacemark:endPlacemark];
    MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:end];

    // 设置起点和终点数组
    NSArray *items = @[startItem,endItem];

    // 设置启动参数
    // 导航模式(驾车/走路)
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[MKLaunchOptionsDirectionsModeKey] = MKLaunchOptionsDirectionsModeDriving;

    // 地图显示模式
    md[MKLaunchOptionsMapTypeKey] = @(MKMapTypeHybrid);

    // 只要调用MKMapItem的open方法, 就可以打开系统自带的地图APP进行导航
    // Items: 告诉系统地图APP要从哪到哪
    //launchOptions: 启动系统自带地图APP的附加参数(导航的模式/是否需要先交通状况/地图的模式/...)
    [MKMapItem openMapsWithItems:items launchOptions:dict];
}

二、手动绘制导航

  1. 获取用户输入的起点和终点
  2. 懒加载CLGeocoder地理编码对象
  3. 利用CLGeocoder对象进行地理编码获取到地标对象CLPlacemark
    // 获取开始位置的地标
[self.geocoder geocodeAddressString:startStr
completionHandler:^(NSArray *placemarks, NSError *error) {
     if (placemarks.count == 0) return;
     // 开始位置的地标
     CLPlacemark *startCLPlacemark = [placemarks firstObject];

     // 添加起点的大头针
     CJAnnotation *startAnno = [[CJAnnotation alloc ] init];
     startAnno.title = startCLPlacemark.locality;
     startAnno.subtitle = startCLPlacemark.name;
     startAnno.coordinate = startCLPlacemark.location.coordinate;

     [self.mapVIew addAnnotation:startAnno];

     //获取结束位置的地标
     [self.geocoder geocodeAddressString:endStr
completionHandler:^(NSArray *placemarks, NSError *error) {
        if (placemarks.count == 0) return;
        // 结束位置的地标
        CLPlacemark *endCLPlacemark = [placemarks firstObject];

        // 添加终点的大头针
        CJAnnotation *endAnno = [[CJAnnotation alloc ] init];
        endAnno.title = endCLPlacemark.locality;
        endAnno.subtitle = endCLPlacemark.name;
        endAnno.coordinate = endCLPlacemark.location.coordinate;

        [self.mapVIew addAnnotation:endAnno];

        // 开始导航
        [self startDirectionsWithstartCLPlacemark:startCLPlacemark
endCLPlacemark:endCLPlacemark];
  }];
}];

4.发送请求获取路线相关信息

/**
 *  发送请求获取路线相信信息
 *  @param startCLPlacemark 起点的地标
 *  @param endCLPlacemark   终点的地标
 */
- (void)startDirectionsWithstartCLPlacemark:(CLPlacemark *)startCLPlacemark
endCLPlacemark:(CLPlacemark *)endCLPlacemark {
    // 创建起点对象
    MKPlacemark *startPlacemark = [[MKPlacemark alloc] initWithPlacemark:startCLPlacemark];

    MKMapItem *startItem = [[MKMapItem alloc] initWithPlacemark:startPlacemark];

    // 创建终点对象
    MKPlacemark *endPlacemark = [[MKPlacemark alloc] initWithPlacemark:endCLPlacemark];

    MKMapItem *endItem = [[MKMapItem alloc] initWithPlacemark:endPlacemark];

    // 创建request对象
    MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];

    // 设置起点
    request.source = startItem;

    // 设置终点
    request.destination = endItem;

    // 1.发送请求到苹果的服务器获取导航路线信息
    // 接收一个MKDirectionsRequest请求对象, 我们需要在该对象中说清楚:从哪里 --> 到哪里
    MKDirections *directions = [[MKDirections alloc] initWithRequest:request];

    // 2.计算路线信息, 计算完成之后会调用blcok
    // 在block中会传入一个响应者对象(response), 这个响应者对象中就存放着路线信息
    [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
        // 打印获取到的路线信息
        // 2.1获取所有的路线
        NSArray *routes = response.routes;
        for (MKRoute *route in routes) {
            NSLog(@"%f千米 %f小时", route.distance / 1000, route.expectedTravelTime/ 3600);
            //  3.绘制路线(本质: 往地图上添加遮盖)
            // 传递当前路线的几何遮盖给地图, 地图就会根据遮盖自动绘制路线
            // 当系统开始绘制路线时会调用代理方法询问当前路线的宽度/颜色等信息
            [self.mapVIew addOverlay:route.polyline]; 
      } 
  }];
}

注意:
MKDirectionsRequest:说清楚:从哪里 --> 到哪里
MKDirectionsResponse:从哪里 --> 到哪里的具体路线信息

5.实现MKMapView的代理方法

// 绘制路线时就会调用(添加遮盖时就会调用)
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
  // 创建一条路径遮盖
  // 注意, 创建线条时候,一定要制定几何路线
  MKPolylineRenderer *line = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
  line.lineWidth = 5; // 路线的宽度
  line.strokeColor = [UIColor redColor]; // 路线的颜色

  // 返回路线
  return line;
}

注意:- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay这个代理方法已经过时。

三、集成百度iOS导航SDK

百度iOS导航 SDK是一套基于iOS 6及以上版本设备的应用程序接口, 您可以通过该接口实现专业的导航功能:

  • 路径规划:通过输入起点与终点,可以发起路径规划。
  • 导航功能:成功发起路径规划后,即可以进入真实GPS导航或模拟导航。真实导航中点击转向标可以切换到文字导航模式,文字导航界面点击HUD按钮可以进入HUD导航。
  • 巡航功能:也即电子狗功能,不用输入起点终点,一键即可进行巡航模式,准确发现前方电子眼信息。
  • 传入外部GPS功能:当SDK运行于无法获取GPS数据的设备时,可以利用其它GPS模块获取GPS信息,然后通过SDK提供的接口传入GPS数据发起导航或者巡航。

下面介绍使用百度iOS导航的具体步骤:
1.不管是要使用百度地图SDK还是导航SDK,首先必须成为百度开发者,并创建自己的应用。

2.获取API Key
为了给用户提供更安全优质的服务,LBS开放平台针对iOS平台的SDK产品引入Key认证机制,用户在使用之前需要先申请配置Key,并在程序相应位置填写您的Key。
Key的申请地址为:http://lbsyun.baidu.com/apiconsole/key
说明:若你需要在同一个工程中同时使用导航SDK和地图SDK,可以共用同一个key。

  • 访问API控制台页面,若您未登录百度账号,将会进入百度账号登录页面
  • 创建应用:点击"创建应用",系统将为您弹出创建AK页面,输入应用名称,将应用类型改为:“ iOS SDK”,并输入安全码(安全码为应用的Bundle Identifier。xcode切换到Summary标签查看Bundle Identifier)
  • 成功创建Key:在输入安全码后,点击“确定”完成应用的配置工作,您将会得到一个创建的Key。

3.下载最新的SDK,请前往:
http://lbsyun.baidu.com/index.php?title=ios-navsdk/sdkios-nav-download

4.将SDK和Framework添加进工程:把baiduNaviSDK文件夹添加到工程中,把AudioToolbox.framework、ImageIO.framework、CoreMotion.framework、CoreLocation.framework、CoreTelephony.framework、MediaPlayer.framework、AVFoundation.framework、SystemConfiguration.framework、libstdc++6.0.9.dylib、Security.framework、JavaScriptCore.framework,这几个framework添加到工程中。

5.修改Build Settings设置项:在Build Settings中, “Other Linker Flags”添加“-ObjC” 标识。

6.配置.plist文件:设置 “required background modes” , “Supported interface orientations”, “NSLocationAlwaysUsageDescription”

7.开启引擎:在AppDelegate.m添加如下头文件
#import "BNCoreServices.h"
在函数 “application:didFinishLaunchingWithOptions:” 中启动SDK引擎。

8.发起导航:发起导航前首先需要进行路径规划,如下:

//发起导航
- (void)startNavi{ 
//节点数组 
NSMutableArray *nodesArray = [[NSMutableArray alloc] initWithCapacity:2]; 
//起点
BNRoutePlanNode *startNode = [[BNRoutePlanNode alloc] init]; 
startNode.pos = [[BNPosition alloc] init]; startNode.pos.x = 113.936392; 
startNode.pos.y = 22.547058;
startNode.pos.eType = BNCoordinate_BaiduMapSDK; [nodesArray addObject:startNode];  
//终点 
BNRoutePlanNode *endNode = [[BNRoutePlanNode alloc] init]; 
endNode.pos = [[BNPosition alloc] init]; 
endNode.pos.x = 114.077075; 
endNode.pos.y = 22.543634;
endNode.pos.eType = BNCoordinate_BaiduMapSDK; [nodesArray addObject:endNode]; 
//发起路径规划 
[BNCoreServices_RoutePlan startNaviRoutePlan:BNRoutePlanMode_Recommend naviNodes:nodesArray time:nil delegete:self userInfo:nil];}

算路成功后,在回调函数中发起导航,如下:
//算路成功回调
-(void)routePlanDidFinished:(NSDictionary *)userInfo{ NSLog(@"算路成功");  
//路径规划成功,开始导航 
[BNCoreServices_UI showNaviUI: BN_NaviTypeReal delegete:self isNeedLandscape:YES];
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容