一 进入百度官方开发者平台 -->http://developer.baidu.com/map/
然后选择 百度导航SDK -->http://developer.baidu.com/map/index.php?title=ios-navsdk/guide/introduction
然后跟着步骤来就好了
但是 遇到一个坑 导航语音播报的时候需要一个延迟 否则会导致无法成功播音播出路径规划时间的距离
//异步处理 让语音播报成功 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( 1*NSEC_PER_SEC)), dispatch_get_main_queue(),^{ [BNCoreServices_Instance startServicesAsyn:^{ //发起路径规划 [BNCoreServices_RoutePlan startNaviRoutePlan:BNRoutePlanMode_Recommend | BN_Speak_Mode_Mid naviNodes:nodesArray time:nil delegete:self userInfo:nil]; } fail:^{ }]; });
到了这里 基本导航没多大问题 !
*****
友情提示 :百度语音与百度导航使用的是一个语音包 不能同时使用,官方开发人员也做出相应回答:目前无法解决 期待百度做的更好吧!
其他 细心一点就好 嘻嘻
mark一下自己的代码:
//开启导航vc #import "BNCoreServices.h" #import "BNRoutePlanModel.h" #import "BNCoreServices.h" @interface NavigationVCViewController ()<UITextFieldDelegate,BMKPoiSearchDelegate,BMKMapViewDelegate,BMKLocationServiceDelegate,BMKGeoCodeSearchDelegate,BNNaviUIManagerDelegate,BNNaviRoutePlanDelegate> { BMKPoiSearch *_searcher; NSString *_cityName; // 检索城市名 NSString *_keyWord; // 检索关键字 BMKNearbySearchOption *_option; BMKUserLocation *_userLocation; CLLocationCoordinate2D _endNodeLocation; BMKGeoCodeSearch* _geocodesearch; //反地理编码 NSMutableArray *annotations; int currentPage; // 当前页 BOOL showTack; //是否显示大头钉 } /** 百度定位地图服务 */ @property (nonatomic, strong) BMKLocationService *locService; //poi结果信息集合 @property (retain,nonatomic) NSMutableArray *poiResultArray; @end @implementation NavigationVCViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.title = loc(@"小云导航"); //初始化检索对象 _searcher =[[BMKPoiSearch alloc] init]; _searcher.delegate = self; _option = [[BMKNearbySearchOption alloc] init]; _serachTextfiled.delegate = self; if (!_poiResultArray) { _poiResultArray = [[NSMutableArray alloc] initWithCapacity:0]; } [_serachTextfiled addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; //定位服务 _locService = [[BMKLocationService alloc]init]; _geocodesearch = [[BMKGeoCodeSearch alloc]init]; [self locationMapView]; //定位 [self loadUI]; //加载视图 } -(void)loadUI { //搜索视图 _serachView.frame = CGRectMake(left_15, left_15, SCREEN_WIDTH-left_15 *2, 40); [self.view addSubview:_serachView]; //功能视图 _functionView.frame = CGRectMake(SCREEN_WIDTH-left_15*2 - _functionView.frame.size.width, _serachView.frame.origin.y + _serachView.frame.size.height + 5, _functionView.frame.size.width, _functionView.frame.size.height); [self.view addSubview:_functionView]; //搜索结视图 _resultsView.frame =CGRectMake(left_15, left_15 + _serachView.frame.size.height , SCREEN_WIDTH - left_15 *2 , _resultsView.frame.size.height); [self.view addSubview:_resultsView]; _resultsView.hidden = YES; //显示位置信息视图 _loactionView.frame = CGRectMake(left_15, SCREEN_HEIGHT - _loactionView.frame.size.height - left_15 - 64, SCREEN_WIDTH - left_15*2, _loactionView.frame.size.height); [self.view addSubview:_loactionView]; _serachMapView.delegate = self; } #pragma mark -监听表格滚动 -(void)scrollViewDidScroll:(UIScrollView *)scrollView { [_serachTextfiled resignFirstResponder]; } #pragma mark - 点击搜索按钮 - (BOOL)textFieldShouldReturn:(UITextField *)textField { showTack = YES; // 显示大头钉 //根据搜索框内的内容联想搜索 NSMutableString *_string = [NSMutableString stringWithString:_serachTextfiled.text]; // 发起检索 _option.pageCapacity = 10; _option.pageIndex = 0; _option.location = CLLocationCoordinate2DMake(_userLocation.location.coordinate.latitude, _userLocation.location.coordinate.longitude); _option.keyword = _string; BOOL flag = [_searcher poiSearchNearBy:_option]; if(flag) { NSLog(@"周边检索发送成功"); } else { NSLog(@"周边检索发送失败"); } [_serachTextfiled resignFirstResponder]; return YES; } #pragma mark -textField实时搜索 - (void) textFieldDidChange:(id) sender { } #pragma mark - tableview deletate -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return annotations.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier = @"cellIdentifier"; UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; if (!cell) { cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath]; } BMKPointAnnotation* item = [annotations objectAtIndex:indexPath.row]; cell.textLabel.text = item.title; return cell; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { BMKPointAnnotation* item = [annotations objectAtIndex:indexPath.row]; _endNodeLocation = item.coordinate; [_serachMapView setCenterCoordinate:item.coordinate animated:YES]; BMKMapPoint point1 = BMKMapPointForCoordinate( CLLocationCoordinate2DMake(_userLocation.location.coordinate.latitude, _userLocation.location.coordinate.longitude)); BMKMapPoint point2 = BMKMapPointForCoordinate(item.coordinate); CLLocationDistance distance = BMKMetersBetweenMapPoints(point1,point2); _distanceLable.text = [NSString stringWithFormat:@"距离%.2f公里",distance/1000]; _loactionLable.text = item.title; BMKReverseGeoCodeOption *reverseGeocodeSearchOption = [[BMKReverseGeoCodeOption alloc]init]; reverseGeocodeSearchOption.reverseGeoPoint = item.coordinate; BOOL flag = [_geocodesearch reverseGeoCode:reverseGeocodeSearchOption]; if(flag) { NSLog(@"反geo检索发送成功"); } else { NSLog(@"反geo检索发送失败"); } _resultsView.hidden = YES; _distanceLable.hidden = NO; _navigationButton.hidden = NO; NSLog(@"%f",distance); [_serachTextfiled resignFirstResponder]; } #pragma mark implement BMKMapViewDelegate /** *根据anntation生成对应的View *@param mapView 地图View *@param annotation 指定的标注 *@return 生成的标注View */ - (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id <BMKAnnotation>)annotation { // 生成重用标示identifier NSString *AnnotationViewID = @"xidanMark"; // 检查是否有重用的缓存 BMKAnnotationView* annotationView = [view dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID]; // 缓存没有命中,自己构造一个,一般首次添加annotation代码会运行到此处 if (annotationView == nil) { annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID]; ((BMKPinAnnotationView*)annotationView).pinColor = BMKPinAnnotationColorRed; // 设置重天上掉下的效果(annotation) ((BMKPinAnnotationView*)annotationView).animatesDrop = YES; } // 设置位置 annotationView.centerOffset = CGPointMake(0, -(annotationView.frame.size.height * 0.5)); annotationView.annotation = annotation; // 单击弹出泡泡,弹出泡泡前提annotation必须实现title属性 annotationView.canShowCallout = YES; // 设置是否可以拖拽 annotationView.draggable = NO; return annotationView; } /** *当选中一个annotation views时,调用此接口 *@param mapView 地图View *@param views 选中的annotation views */ - (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view { mapView.isSelectedAnnotationViewFront = YES; [mapView bringSubviewToFront:view]; [mapView setNeedsDisplay]; } - (void)mapView:(BMKMapView *)mapView didAddAnnotationViews:(NSArray *)views { // NSLog(@"didAddAnnotationViews"); } //实现PoiSearchDeleage处理回调结果 - (void)onGetPoiResult:(BMKPoiSearch*)searcher result:(BMKPoiResult*)poiResultList errorCode:(BMKSearchErrorCode)error { // 清楚屏幕中所有的annotation NSArray* array = [NSArray arrayWithArray:_serachMapView.annotations]; [_serachMapView removeAnnotations:array]; if (error == BMK_SEARCH_NO_ERROR) { if (poiResultList) { _resultsView.hidden = NO; } //在此处理正常结果 for (int i = 0; i < poiResultList.poiInfoList.count; i++) { annotations = [NSMutableArray array]; for (int i = 0; i < poiResultList.poiInfoList.count; i++) { BMKPoiInfo* poi = [poiResultList.poiInfoList objectAtIndex:i]; BMKPointAnnotation* item = [[BMKPointAnnotation alloc]init]; item.coordinate = poi.pt; item.title = poi.name; [annotations addObject:item]; } [_serachMapView addAnnotations:annotations]; [_serachMapView showAnnotations:annotations animated:YES]; } [_locService stopUserLocationService]; //关闭定位 [_resultsTableView reloadData]; } else if (error == BMK_SEARCH_AMBIGUOUS_KEYWORD){ //当在设置城市未找到结果,但在其他城市找到结果时,回调建议检索城市列表 // result.cityList; NSLog(@"起始点有歧义"); } else { NSLog(@"抱歉,未找到结果"); } } -(void) onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error { if (error == 0) { BMKPointAnnotation* item = [[BMKPointAnnotation alloc]init]; item.coordinate = result.location; item.title = result.address; _loactionAdrassLable.text = [NSString stringWithFormat:@"%@",item.title]; } } #pragma mark -页面即将进入处理的方法 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [_serachMapView viewWillAppear]; _serachMapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放 _locService.delegate = self; _geocodesearch.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放 } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [_serachMapView viewWillDisappear]; _serachMapView.delegate = nil; // 此处记得不用的时候需要置nil,否则影响内存的释放 _locService.delegate = nil; _geocodesearch.delegate = nil; // 不用时,置nil _searcher.delegate = nil; } /** *在地图View将要启动定位时,会调用此函数 *@param mapView 地图View */ - (void)willStartLocatingUser { NSLog(@"start locate"); } /** *用户方向更新后,会调用此函数 *@param userLocation 新的用户位置 */ - (void)didUpdateUserHeading:(BMKUserLocation *)userLocation { [_serachMapView updateLocationData:userLocation]; // NSLog(@"heading is %@",userLocation.heading); } /** *用户位置更新后,会调用此函数 *@param userLocation 新的用户位置 */ - (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation { _userLocation = userLocation; if (userLocation.location.horizontalAccuracy > kCLLocationAccuracyNearestTenMeters) { CLLocationCoordinate2D pt = (CLLocationCoordinate2D)CLLocationCoordinate2DMake(userLocation.location.coordinate.latitude, userLocation.location.coordinate.longitude); BMKReverseGeoCodeOption *reverseGeocodeSearchOption = [[BMKReverseGeoCodeOption alloc]init]; reverseGeocodeSearchOption.reverseGeoPoint = pt; BOOL flag = [_geocodesearch reverseGeoCode:reverseGeocodeSearchOption]; if(flag) { NSLog(@"反geo检索发送成功"); } else { NSLog(@"反geo检索发送失败"); } return; } [_serachMapView updateLocationData:userLocation]; } /** *在地图View停止定位后,会调用此函数 *@param mapView 地图View */ - (void)didStopLocatingUser { NSLog(@"stop locate"); } /** *定位失败后,会调用此函数 *@param mapView 地图View *@param error 错误号,参考CLError.h中定义的错误号 */ - (void)didFailToLocateUserWithError:(NSError *)error { NSLog(@"location error"); } #pragma mark - 功能视图的使用 - (IBAction)myLocationButtonClick:(UIButton *)sender { //我的位置 [self locationMapView]; } //定位方法 -(void)locationMapView { [_locService startUserLocationService]; _serachMapView.showsUserLocation = NO;//先关闭显示的定位图层 _serachMapView.userTrackingMode = BMKUserTrackingModeFollow;//设置定位的状态 _serachMapView.showsUserLocation = YES;//显示定位图层 _serachMapView.zoomLevel = 15; _locService.distanceFilter = 100; _loactionLable.text = loc(@"我的位置"); _distanceLable.hidden = YES; _navigationButton.hidden = YES; } - (IBAction)roadButtonClick:(UIButton *)sender { //显示路况 sender.selected = !sender.selected; if (sender.selected) { [_roadButton setTitle:@"show" forState:UIControlStateNormal]; _serachMapView.trafficEnabled = YES; //路况 }else{ [_roadButton setTitle:@"hide" forState:UIControlStateNormal]; _serachMapView.trafficEnabled = NO; //路况 } } #pragma mark - 进入导航 - (IBAction)navigationButtonClick:(id)sender { [self startNavi]; } //发起导航 - (void)startNavi { //节点数组 NSMutableArray *nodesArray = [[NSMutableArray alloc] initWithCapacity:2]; //起点 BNRoutePlanNode *startNode = [[BNRoutePlanNode alloc] init]; startNode.pos = [[BNPosition alloc] init]; startNode.pos.y = _userLocation.location.coordinate.latitude; startNode.pos.x = _userLocation.location.coordinate.longitude; startNode.pos.eType = BNCoordinate_BaiduMapSDK; [nodesArray addObject:startNode]; //终点 BNRoutePlanNode *endNode = [[BNRoutePlanNode alloc] init]; endNode.pos = [[BNPosition alloc] init]; endNode.pos.y = _endNodeLocation.latitude; endNode.pos.x = _endNodeLocation.longitude; endNode.pos.eType = BNCoordinate_BaiduMapSDK; [nodesArray addObject:endNode]; //异步处理 让语音播报成功 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( 1*NSEC_PER_SEC)), dispatch_get_main_queue(),^{ [BNCoreServices_Instance startServicesAsyn:^{ //发起路径规划 [BNCoreServices_RoutePlan startNaviRoutePlan:BNRoutePlanMode_Recommend | BN_Speak_Mode_Mid naviNodes:nodesArray time:nil delegete:self userInfo:nil]; } fail:^{ }]; }); } //算路成功回调 -(void)routePlanDidFinished:(NSDictionary *)userInfo { NSLog(@"算路成功"); //路径规划成功,开始导航 [BNCoreServices_UI showNaviUI: BN_NaviTypeReal delegete:self isNeedLandscape:YES]; } //算路失败回调 - (void)routePlanDidFailedWithError:(NSError *)error andUserInfo:(NSDictionary *)userInfo { NSLog(@"算路失败"); if ([error code] == BNRoutePlanError_LocationFailed) { NSLog(@"获取地理位置失败"); }else if([error code] == BNRoutePlanError_RoutePlanFailed) { NSLog(@"无法发起算路"); }else if([error code] == BNRoutePlanError_LocationServiceClosed) { NSLog(@"定位服务未开启"); }else if([error code] == BNRoutePlanError_NodesTooNear) { NSLog(@"节点之间距离太近 "); }else if([error code] == BNRoutePlanError_NodesInputError) { NSLog(@"节点输入有误"); }else if([error code] == BNRoutePlanError_WaitAMoment) { NSLog(@"上次算路取消了,需要等一会儿"); } } -(void)routePlanDidUserCanceled:(NSDictionary*)userInfo { NSLog(@"算路取消"); } #pragma mark - BNNaviUIManagerDelegate //退出导航回调 -(void)onExitNaviUI:(NSDictionary*)extraInfo { NSLog(@"退出导航"); } - (void)dealloc { if (_searcher != nil) { _searcher = nil; } if (_geocodesearch != nil) { _geocodesearch = nil; } if (_serachMapView) { _serachMapView = nil; } }