一 進入百度官方開發者平臺 -->http://developer.baidu.com/map/php
而後選擇 百度導航SDK -->http://developer.baidu.com/map/index.php?title=ios-navsdk/guide/introductionnode
而後跟着步驟來就行了ios
可是 遇到一個坑 導航語音播報的時候須要一個延遲 不然會致使沒法成功播音播出路徑規劃時間的距離git
//異步處理 讓語音播報成功 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:^{ }]; });
到了這裏 基本導航沒多大問題 !數組
*****緩存
友情提示 :百度語音與百度導航使用的是一個語音包 不能同時使用,官方開發人員也作出相應回答:目前沒法解決 期待百度作的更好吧!app
其餘 細心一點就好 嘻嘻異步
mark一下本身的代碼:ide
//開啓導航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; } }