项目需要集成百度地图,那么关于如何集成百度地图的事,就自己去百度开放平台查看文档吧,这是非常简单的事,在这里就不多说了。
那么下面我就说说我在这个demo里所做的事。
首先,项目需要具备定位及计算两地的距离
其次,项目需要根据两个地点来拿到所有路线,并且可根据不同的策略拿到对应的最佳路线。
最后,需要拿到打车相关信息
那么这里我就自己写了一个单例类,这是在内部处理所有的代理,外部可以非常方便地调用,如果有好的建议,请在评论中赐教,谢谢!
// // HYBBaiduMapHelper.h // BaiduMapDemo // // Created by 黄仪标 on 14/11/18. // Copyright (c) 2014年 黄仪标. All rights reserved. // #import <Foundation/Foundation.h> #import "BMapKit.h" typedef void (^HYBUserLocationCompletion)(BMKUserLocation *userLocation); typedef void (^HYBRouteSearchCompletion)(BMKTransitRouteResult *result); /*! * @brief 百度地图相关API操作类 * * @author huangyibiao */ @interface HYBBaiduMapHelper : NSObject + (HYBBaiduMapHelper *)shared; /// /// 该方法在appdelegate的调用,在应用启动时,请求授权百度地图 - (BOOL)startWithAppKey:(NSString *)appKey; /// /// 下面的几个方法是定位使用 - (void)locateInView:(UIView *)mapSuerView frame:(CGRect)frame withCompletion:(HYBUserLocationCompletion)completion; - (void)viewWillAppear; - (void)viewWillDisappear; - (void)viewDidDeallocOrReceiveMemoryWarning; /// /// 下面的方法是计算两地的距离 /// 返回距离单位为米 - (CLLocationDistance)distanceWithStartPoint:(CLLocationCoordinate2D)startPoint endPoint:(CLLocationCoordinate2D)endPoint; /// /// 下面的方法是路线规划获取操作 /// 注意:不能同时调用下面的这三个方法,必须是先调用完一个,返回结果后,再继续调用别的,否则会覆盖前一个操作的数据 /// 公交检索方法 /// 前两个参数,分别表示起点和终点的位置名称 /// 第三个参数,表示在哪个城市里检索 - (void)transitRouteSearchFrom:(BMKPlanNode *)startNode to:(BMKPlanNode *)endNode city:(NSString *)city transitPolicy:(BMKTransitPolicy)transitPolicy completion:(HYBRouteSearchCompletion)completion; /// 驾乘检索方法 /// 前两个参数,分别表示起点和终点的位置名称 - (void)driveRouteSearchFrom:(BMKPlanNode *)startNode to:(BMKPlanNode *)endNode drivePolicy:(BMKDrivingPolicy)drivePolicy completion:(HYBRouteSearchCompletion)completion; /// 步行检索方法 /// 前两个参数,分别表示起点和终点的位置名称 - (void)walkRouteSearchFrom:(BMKPlanNode *)startNode to:(BMKPlanNode *)endNode completion:(HYBRouteSearchCompletion)completion; @end
// // HYBBaiduMapHelper.m // BaiduMapDemo // // Created by 黄仪标 on 14/11/18. // Copyright (c) 2014年 黄仪标. All rights reserved. // #import "HYBBaiduMapHelper.h" @interface HYBBaiduMapHelper () <BMKLocationServiceDelegate, BMKGeneralDelegate, BMKMapViewDelegate, BMKRouteSearchDelegate> { BMKMapManager *_mapManager; HYBUserLocationCompletion _locationCompletion; HYBRouteSearchCompletion _routeSearchCompletion; BMKMapView *_mapView; BMKLocationService *_locationService; BMKRouteSearch *_routeSearch; } @end @implementation HYBBaiduMapHelper + (HYBBaiduMapHelper *)shared { static HYBBaiduMapHelper *baiduMapHelper = nil; static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ if (!baiduMapHelper) { baiduMapHelper = [[[self class] alloc] init]; } }); return baiduMapHelper; } - (instancetype)init { if (self = [super init]) { _mapManager = [[BMKMapManager alloc] init]; } return self; } - (BOOL)startWithAppKey:(NSString *)appKey { if (![appKey isKindOfClass:[NSString class]] || appKey.length == 0 || appKey == nil) { return NO; } return [_mapManager start:appKey generalDelegate:self]; } - (void)locateInView:(UIView *)mapSuerView frame:(CGRect)frame withCompletion:(HYBUserLocationCompletion)completion { _locationCompletion = [completion copy]; [_locationService stopUserLocationService]; _locationService = nil; _locationService.delegate = nil; _locationService = [[BMKLocationService alloc] init]; [_locationService startUserLocationService]; if (_mapView) { [_mapView removeFromSuperview]; _mapView = nil; } _mapView.delegate = nil; _mapView.showsUserLocation = NO; _mapView = [[BMKMapView alloc] initWithFrame:frame]; [mapSuerView addSubview:_mapView]; _mapView.delegate = self; // 先关闭显示的定位图层 _mapView.showsUserLocation = NO; // 设置定位的状态 _mapView.userTrackingMode = BMKUserTrackingModeNone; _mapView.showsUserLocation = YES; return; } - (void)viewWillAppear { [_mapView viewWillAppear]; _mapView.delegate = self; _locationService.delegate = self; _routeSearch.delegate = self; return; } - (void)viewWillDisappear { [_mapView viewWillDisappear]; _mapView.delegate = nil; _locationService.delegate = nil; _routeSearch.delegate = nil; return; } - (void)viewDidDeallocOrReceiveMemoryWarning { [self viewWillDisappear]; _mapView.showsUserLocation = NO; [_locationService stopUserLocationService]; [_mapView removeFromSuperview]; _mapView = nil; _locationService = nil; _routeSearch.delegate = nil; _routeSearch = nil; return; } /// /// 计算两点的距离 - (CLLocationDistance)distanceWithStartPoint:(CLLocationCoordinate2D)startPoint endPoint:(CLLocationCoordinate2D)endPoint { BMKMapPoint point1 = BMKMapPointForCoordinate(startPoint); BMKMapPoint point2 = BMKMapPointForCoordinate(endPoint); CLLocationDistance distance = BMKMetersBetweenMapPoints(point1, point2); return distance; } /// /// 下面的方法是路线规划获取操作 /// 公交检索方法 /// 前两个参数,分别表示起点和终点的位置名称 /// 第三个参数,表示在哪个城市里检索 - (void)transitRouteSearchFrom:(BMKPlanNode *)startNode to:(BMKPlanNode *)endNode city:(NSString *)city transitPolicy:(BMKTransitPolicy)transitPolicy completion:(HYBRouteSearchCompletion)completion { _routeSearchCompletion = [completion copy]; if (_routeSearch == nil) { _routeSearch = [[BMKRouteSearch alloc] init]; } _routeSearch.delegate = self; // 公交检索 BMKTransitRoutePlanOption *transitRoutePlan = [[BMKTransitRoutePlanOption alloc] init]; transitRoutePlan.city = city; transitRoutePlan.from = startNode; transitRoutePlan.to = endNode; transitRoutePlan.transitPolicy = transitPolicy; if ([_routeSearch transitSearch:transitRoutePlan]) { NSLog(@"bus检索发送成功"); } else { NSLog(@"bus检索发送失败"); } return; } /// 驾乘检索方法 /// 前两个参数,分别表示起点和终点的位置名称 - (void)driveRouteSearchFrom:(BMKPlanNode *)startNode to:(BMKPlanNode *)endNode drivePolicy:(BMKDrivingPolicy)drivePolicy completion:(HYBRouteSearchCompletion)completion { _routeSearchCompletion = [completion copy]; if (_routeSearch == nil) { _routeSearch = [[BMKRouteSearch alloc] init]; } _routeSearch.delegate = self; // 公交检索 BMKDrivingRoutePlanOption *driveRoutePlan = [[BMKDrivingRoutePlanOption alloc] init]; driveRoutePlan.from = startNode; driveRoutePlan.to = endNode; driveRoutePlan.drivingPolicy = drivePolicy; if ([_routeSearch drivingSearch:driveRoutePlan]) { NSLog(@"drive 检索发送成功"); } else { NSLog(@"drive 检索发送失败"); } return; } /// 步行检索方法 /// 前两个参数,分别表示起点和终点的位置名称 - (void)walkRouteSearchFrom:(BMKPlanNode *)startNode to:(BMKPlanNode *)endNode completion:(HYBRouteSearchCompletion)completion { _routeSearchCompletion = [completion copy]; if (_routeSearch == nil) { _routeSearch = [[BMKRouteSearch alloc] init]; } _routeSearch.delegate = self; // 公交检索 BMKWalkingRoutePlanOption *walkRoutePlan = [[BMKWalkingRoutePlanOption alloc] init]; walkRoutePlan.from = startNode; walkRoutePlan.to = endNode; if ([_routeSearch walkingSearch:walkRoutePlan]) { NSLog(@"walk 检索发送成功"); } else { NSLog(@"walk 检索发送失败"); } return; } #pragma mark - BMKGeneralDelegate - (void)onGetNetworkState:(int)iError { if (0 == iError) { NSLog(@"联网成功"); } else { NSLog(@"onGetNetworkState %d",iError); } return; } - (void)onGetPermissionState:(int)iError { if (0 == iError) { NSLog(@"百度地图授权成功"); } else { NSLog(@"onGetPermissionState %d",iError); } return; } #pragma mark - BMKLocationServiceDelegate /** *在将要启动定位时,会调用此函数 */ - (void)willStartLocatingUser { NSLog(@"location start"); return; } /** *在停止定位后,会调用此函数 */ - (void)didStopLocatingUser { NSLog(@"user location stop"); return; } /** *用户方向更新后,会调用此函数 *@param userLocation 新的用户位置 */ - (void)didUpdateUserHeading:(BMKUserLocation *)userLocation { NSLog(@"user derection change"); [_mapView updateLocationData:userLocation]; return; } /** *用户位置更新后,会调用此函数 *@param userLocation 新的用户位置 */ - (void)didUpdateUserLocation:(BMKUserLocation *)userLocation { NSLog(@"didUpdateUserLocation lat %f,long %f", userLocation.location.coordinate.latitude, userLocation.location.coordinate.longitude); [_mapView updateLocationData:userLocation]; if (_locationCompletion) { _locationCompletion(userLocation); } [_locationService stopUserLocationService]; return; } /** *定位失败后,会调用此函数 *@param error 错误号 */ - (void)didFailToLocateUserWithError:(NSError *)error { if (_locationCompletion) { _locationCompletion(nil); } [_locationService stopUserLocationService]; return; } #pragma mark - BMKRouteSearchDelegate - (void)onGetTransitRouteResult:(BMKRouteSearch *)searcher result:(BMKTransitRouteResult *)result errorCode:(BMKSearchErrorCode)error { if (error == BMK_SEARCH_NO_ERROR) { // 检索成功的处理 for (BMKTransitRouteLine *line in result.routes) { NSLog(@"-----------------------------------------------------"); NSLog(@" 时间:%2d %2d:%2d:%2d 长度: %d米", line.duration.dates, line.duration.hours, line.duration.minutes, line.duration.seconds, line.distance); for (BMKTransitStep *step in line.steps) { NSLog(@"%@ %@ %@ %@ %@", step.entrace.title, step.exit.title, step.instruction, (step.stepType == BMK_BUSLINE ? @"公交路段" : (step.stepType == BMK_SUBWAY ? @"地铁路段" : @"步行路段")), [NSString stringWithFormat:@"名称:%@ 所乘站数:%d 全程价格:%d 区间价格:%d", step.vehicleInfo.title, step.vehicleInfo.passStationNum, step.vehicleInfo.totalPrice, step.vehicleInfo.zonePrice]); } } // 打车信息 NSLog(@"打车信息------------------------------------------"); NSLog(@"路线打车描述信息:%@ 总路程: %d米 总耗时:约%f分钟 每千米单价:%f元 全程总价:约%d元", result.taxiInfo.desc, result.taxiInfo.distance, result.taxiInfo.duration / 60.0, result.taxiInfo.perKMPrice, result.taxiInfo.totalPrice); } else if (error == BMK_SEARCH_AMBIGUOUS_ROURE_ADDR) { // 检索地址有岐义,可获取推荐地址 // 获取建议检索起终点 NSLog(@"无检索结果,返回了建议检索信息"); NSLog(@"起点推荐信息:--------------------------------"); for (BMKPoiInfo *info in result.suggestAddrResult.startPoiList) { NSLog(@"POI名称:%@ POI地址:%@ POI所在城市:%@", info.name, info.address, info.city); } NSLog(@"终点推荐信息:--------------------------------"); for (BMKPoiInfo *info in result.suggestAddrResult.endPoiList) { NSLog(@"POI名称:%@ POI地址:%@ POI所在城市:%@", info.name, info.address, info.city); } } else { NSLog(@"无公交检索结果 "); } // 回调block根据实际需要返回,可修改返回结构 if (_routeSearchCompletion) { _routeSearchCompletion(nil); // 这里只是返回空,这个需要根据实际需要返回 } return; } - (void)onGetDrivingRouteResult:(BMKRouteSearch *)searcher result:(BMKDrivingRouteResult *)result errorCode:(BMKSearchErrorCode)error { if (error == BMK_SEARCH_NO_ERROR) { // 检索成功的处理 for (BMKDrivingRouteLine *line in result.routes) { NSLog(@"-----------------------------------------------------"); NSLog(@" 时间:%2d %2d:%2d:%2d 长度: %d米", line.duration.dates, line.duration.hours, line.duration.minutes, line.duration.seconds, line.distance); for (BMKDrivingStep *step in line.steps) { NSLog(@"入口:%@ 出口:%@ 路段总体指示信息:%@ 入口信息:%@ 出口信息:%@ 转弯数:%d", step.entrace.title, step.exit.title, step.instruction, step.entraceInstruction, step.exitInstruction, step.numTurns); } } } else if (error == BMK_SEARCH_AMBIGUOUS_ROURE_ADDR) { // 检索地址有岐义,可获取推荐地址 // 获取建议检索起终点 NSLog(@"无检索结果,返回了建议检索信息"); NSLog(@"起点推荐信息:--------------------------------"); for (BMKPoiInfo *info in result.suggestAddrResult.startPoiList) { NSLog(@"POI名称:%@ POI地址:%@ POI所在城市:%@", info.name, info.address, info.city); } NSLog(@"终点推荐信息:--------------------------------"); for (BMKPoiInfo *info in result.suggestAddrResult.endPoiList) { NSLog(@"POI名称:%@ POI地址:%@ POI所在城市:%@", info.name, info.address, info.city); } } else { NSLog(@"无公交检索结果 "); } // 回调block根据实际需要返回,可修改返回结构 if (_routeSearchCompletion) { _routeSearchCompletion(nil); // 这里只是返回空,这个需要根据实际需要返回 } return; } - (void)onGetWalkingRouteResult:(BMKRouteSearch *)searcher result:(BMKWalkingRouteResult *)result errorCode:(BMKSearchErrorCode)error { if (error == BMK_SEARCH_NO_ERROR) { // 检索成功的处理 for (BMKDrivingRouteLine *line in result.routes) { NSLog(@"步行检索结果 :-----------------------------------------------------"); NSLog(@" 时间:%2d %2d:%2d:%2d 长度: %d米", line.duration.dates, line.duration.hours, line.duration.minutes, line.duration.seconds, line.distance); for (BMKWalkingStep *step in line.steps) { NSLog(@"入口:%@ 出口:%@ 路段总体指示信息:%@ 入口信息:%@ 出口信息:%@", step.entrace.title, step.exit.title, step.instruction, step.entraceInstruction, step.exitInstruction); } } } else if (error == BMK_SEARCH_AMBIGUOUS_ROURE_ADDR) { // 检索地址有岐义,可获取推荐地址 // 获取建议检索起终点 NSLog(@"无检索结果,返回了建议检索信息"); NSLog(@"起点推荐信息:--------------------------------"); for (BMKPoiInfo *info in result.suggestAddrResult.startPoiList) { NSLog(@"POI名称:%@ POI地址:%@ POI所在城市:%@", info.name, info.address, info.city); } NSLog(@"终点推荐信息:--------------------------------"); for (BMKPoiInfo *info in result.suggestAddrResult.endPoiList) { NSLog(@"POI名称:%@ POI地址:%@ POI所在城市:%@", info.name, info.address, info.city); } } else { NSLog(@"无公交检索结果 "); } // 回调block根据实际需要返回,可修改返回结构 if (_routeSearchCompletion) { _routeSearchCompletion(nil); // 这里只是返回空,这个需要根据实际需要返回 } return; } @end
下面就是测试一个我们的数据是否真的拿到了:
// // RootViewController.m // BaiduMapDemo // // Created by 黄仪标 on 14/11/18. // Copyright (c) 2014年 黄仪标. All rights reserved. // #import "RootViewController.h" #import "HYBBaiduMapHelper.h" #import "BMapKit.h" @interface RootViewController () @end @implementation RootViewController - (void)viewDidLoad { [super viewDidLoad]; // 功能1、定位 [[HYBBaiduMapHelper shared] locateInView:self.view frame:self.view.bounds withCompletion:^(BMKUserLocation *userLocation) { NSLog(@"%f %f", userLocation.location.coordinate.latitude, userLocation.location.coordinate.longitude); }]; // 功能2:”计算距离 CLLocationDistance distance = [[HYBBaiduMapHelper shared] distanceWithStartPoint:CLLocationCoordinate2DMake(39.915,116.404) endPoint:CLLocationCoordinate2DMake(38.915,115.404)]; NSLog(@"distance = %fm", distance); // 功能3:公交检索 BMKPlanNode *startNode = [[BMKPlanNode alloc] init]; startNode.name = @"梆子井"; startNode.cityName = @"北京"; BMKPlanNode *endNode = [[BMKPlanNode alloc] init]; endNode.name = @"金长安大厦"; endNode.cityName = @"北京"; // 功能3:公交检索 [[HYBBaiduMapHelper shared] transitRouteSearchFrom:startNode to:endNode city:@"北京" transitPolicy:BMK_TRANSIT_TRANSFER_FIRST completion:^(BMKTransitRouteResult *result) { // 功能4:驾乘检索 [[HYBBaiduMapHelper shared] driveRouteSearchFrom:startNode to:endNode drivePolicy:BMK_DRIVING_TIME_FIRST completion:^(BMKTransitRouteResult *result) { // 功能5:步行检索 [[HYBBaiduMapHelper shared] walkRouteSearchFrom:startNode to:endNode completion:^(BMKTransitRouteResult *result) { ; }]; }]; }]; return; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [[HYBBaiduMapHelper shared] viewWillAppear]; return; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [[HYBBaiduMapHelper shared] viewWillDisappear]; return; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; [[HYBBaiduMapHelper shared] viewDidDeallocOrReceiveMemoryWarning]; return; } - (void)dealloc { [[HYBBaiduMapHelper shared] viewDidDeallocOrReceiveMemoryWarning]; return; } @end
想要深入研究的同学,可以去官网看官方提供的Demo,
如果想在我的demo之上进一步追加或者修改功能,可以下载本demo。