百度導航--總結

一 進入百度官方開發者平臺 -->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;
    }
}
相關文章
相關標籤/搜索