【整理之路二】百度地图的路径规划和调用本机地图导航
生活随笔
收集整理的這篇文章主要介紹了
【整理之路二】百度地图的路径规划和调用本机地图导航
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、細說百度地圖的路徑規劃
路徑規劃主要有這么幾種 1.公交路徑規劃 1.1 市內公交規劃(暫時不在這里說) 1.2 跨市/省公交規劃
// 導入頭文件#import <BaiduMapAPI_Search/BMKSearchComponent.h>#import <BaiduMapAPI_Map/BMKPolylineView.h>#import <BaiduMapAPI_Utils/BMKGeometry.h>#pragma mark: - 公交路線- (void)showBusSearch {//線路檢索節點信息BMKPlanNode *start = [[BMKPlanNode alloc] init];start.pt = self.userLocation.location.coordinate;start.cityName = @"南寧";BMKPlanNode *end = [[BMKPlanNode alloc] init];// 108.296699,22.842406CLLocationCoordinate2D endCoordinate = CLLocationCoordinate2DMake(22.842406, 108.296699);end.pt = endCoordinate;end.cityName = @"南寧";BMKMassTransitRoutePlanOption *drivingRouteSearchOption = [[BMKMassTransitRoutePlanOption alloc] init];drivingRouteSearchOption.from = start;drivingRouteSearchOption.to = end;BOOL flag = [_routesearch massTransitSearch:drivingRouteSearchOption];if (flag) {NSLog(@"%s - 設置成功!",__func__);}else {debugLog(@"設置失敗");}}/***返回公共交通路線檢索結果(new)回調方法*@param searcher 搜索對象*@param result 搜索結果,類型為BMKMassTransitRouteResult*@param error 錯誤號,@see BMKSearchErrorCode*/- (void)onGetMassTransitRouteResult:(BMKRouteSearch*)searcher result:(BMKMassTransitRouteResult*)result errorCode:(BMKSearchErrorCode)error {debugLog(@"公交方案-%@",result.routes);if (error == BMK_SEARCH_NO_ERROR) {for (int i = 0; i < result.routes.count; i++ ) {BMKMassTransitRouteLine *massTransitRouteLine = result.routes[i];// 保存換乘說明NSMutableArray *instructions = [NSMutableArray array];// 換乘的交通工具NSMutableArray *stepTypes = [NSMutableArray array];// 價格信息debugLog(@"價格-%f",massTransitRouteLine.price);debugLog(@"時間分鐘-%d",massTransitRouteLine.duration.minutes);debugLog(@"起點-%@",massTransitRouteLine.starting.title);debugLog(@"終點-%@",massTransitRouteLine.terminal.title);debugLog(@"路段方案%@",massTransitRouteLine.steps);// 所有路段的信息for ( int j = 0; j < massTransitRouteLine.steps.count; j++) {BMKMassTransitStep *step = massTransitRouteLine.steps[j];debugLog(@"%@",step.steps);for ( int k = 0; k< step.steps.count; k++) {BMKMassTransitSubStep *subStep = step.steps[k];debugLog(@"換乘說明-%@",subStep.instructions);[instructions addObject:subStep.instructions];debugLog(@"路段類型-%u",subStep.stepType);if(subStep.stepType != 5) { // 5為步行if (subStep.vehicleInfo.name) {[stepTypes addObject:subStep.vehicleInfo.name];}}// 當路段為公交路段或地鐵路段時,可以獲取交通工具信息debugLog(@"交通工具信息-%@",subStep.vehicleInfo.name);}}}} }復制代碼2.駕車路徑規劃
#pragma mark 駕車路線 -(void)showDriveSearch {//線路檢索節點信息BMKPlanNode *start = [[BMKPlanNode alloc] init];start.pt = self.userLocation.location.coordinate;start.cityName = @"南寧";BMKPlanNode *end = [[BMKPlanNode alloc] init];CLLocationCoordinate2D endCoordinate = CLLocationCoordinate2DMake(22.842406, 108.296699);end.pt = endCoordinate;end.cityName = @"南寧";BMKDrivingRoutePlanOption *drivingRouteSearchOption = [[BMKDrivingRoutePlanOption alloc] init];drivingRouteSearchOption.from = start;drivingRouteSearchOption.to = end;BOOL flag = [_routesearch drivingSearch:drivingRouteSearchOption];if (flag) {NSLog(@"%s - 設置成功!",__func__);}else {debugLog(@"設置失敗");} }#pragma mark 返回駕乘搜索結果 - (void)onGetDrivingRouteResult:(BMKRouteSearch*)searcher result:(BMKDrivingRouteResult*)result errorCode:(BMKSearchErrorCode)error {if (error == BMK_SEARCH_NO_ERROR) {for (int i = 0; i < result.routes.count; i++) {NSMutableArray *instruction = [NSMutableArray array];NSMutableArray *waypoints = [NSMutableArray array];//表示一條駕車路線BMKDrivingRouteLine *plan = result.routes[i];for (int k = 0; k < plan.wayPoints.count; k++) {BMKPlanNode *node = plan.wayPoints[k];[waypoints addObject:node.name];}for (int j = 0; j < plan.steps.count; j++) {//表示駕車路線中的一個路段BMKDrivingStep* transitStep = [plan.steps objectAtIndex:j];[instruction addObject:transitStep.instruction];}}}}復制代碼3.步行路徑規劃
#pragma mark: - 步行 - (void)showWalkSearch {//線路檢索節點信息BMKPlanNode *start = [[BMKPlanNode alloc] init];start.pt = self.userLocation.location.coordinate;start.cityName = @"南寧";BMKPlanNode *end = [[BMKPlanNode alloc] init];CLLocationCoordinate2D endCoordinate = CLLocationCoordinate2DMake(22.842406, 108.296699);end.pt = endCoordinate;end.cityName = @"南寧";BMKWalkingRoutePlanOption *drivingRouteSearchOption = [[BMKWalkingRoutePlanOption alloc] init];drivingRouteSearchOption.from = start;drivingRouteSearchOption.to = end;BOOL flag = [_routesearch walkingSearch:drivingRouteSearchOption];if (flag) {NSLog(@"%s - 設置成功!",__func__);}else {debugLog(@"設置失敗");} }/***返回步行搜索結果*@param searcher 搜索對象*@param result 搜索結果,類型為BMKWalkingRouteResult*@param error 錯誤號,@see BMKSearchErrorCode*/ - (void)onGetWalkingRouteResult:(BMKRouteSearch*)searcher result:(BMKWalkingRouteResult*)result errorCode:(BMKSearchErrorCode)error {debugLog(@"步行方案--%@",result.routes);if (error == BMK_SEARCH_NO_ERROR) {for (int i = 0; i < result.routes.count; i++) {NSMutableArray *instructions = [NSMutableArray array];BMKWalkingRouteLine *walkingRouteLine = result.routes[i];//debugLog(@"途徑 ---%@", walkingRouteLine.wayPointPoiList);debugLog(@"路線長度 -- %d", walkingRouteLine.distance);debugLog(@"需要花費的時間 %d",walkingRouteLine.duration.minutes);for (int j = 0; j < walkingRouteLine.steps.count; j++) {BMKWalkingStep *step = walkingRouteLine.steps[j];debugLog(@"入口信息 -- %@",step.entraceInstruction);debugLog(@"出口信息 -- %@",step.exitInstruction);debugLog(@"指示信息 -- %@",step.instruction);[instructions addObject:step.instruction];}}} }復制代碼4.騎車路徑規劃(暫時不總結)
5.根據路徑規劃劃線
- (void)showCarRoutePlan {// 計算路線方案中的路段數目int size = (int)[self.drivingRouteLine.steps count];BMKDrivingRouteLine *plan = self.drivingRouteLine;int planPointCounts = 0;for (int i = 0; i < size; i++) {//表示駕車路線中的一個路段BMKDrivingStep* transitStep = [plan.steps objectAtIndex:i];if(i==0){RouteAnnotation* item = [[RouteAnnotation alloc]init];item.coordinate = plan.starting.location;item.title = @"起點";item.type = 0;[_mapView addAnnotation:item]; // 添加起點標注}else if(i==size-1){RouteAnnotation* item = [[RouteAnnotation alloc]init];item.coordinate = plan.terminal.location;item.title = @"終點";item.type = 1;[_mapView addAnnotation:item]; // 添加終點標注}//添加annotation節點RouteAnnotation* item = [[RouteAnnotation alloc]init];item.coordinate = transitStep.entrace.location;item.title = transitStep.entraceInstruction;item.degree = transitStep.direction * 30;item.type = 4;[_mapView addAnnotation:item];//軌跡點總數累計planPointCounts += transitStep.pointsCount;}// 添加途經點if (plan.wayPoints) {for (BMKPlanNode* tempNode in plan.wayPoints) {RouteAnnotation* item = [[RouteAnnotation alloc]init];item.coordinate = tempNode.pt;item.type = 5;item.title = tempNode.name;[_mapView addAnnotation:item];}}//軌跡點BMKMapPoint * temppoints = new BMKMapPoint[planPointCounts];int i = 0;for (int j = 0; j < size; j++) {BMKDrivingStep* transitStep = [plan.steps objectAtIndex:j];int k=0;for(k=0;k<transitStep.pointsCount;k++) {temppoints[i].x = transitStep.points[k].x;temppoints[i].y = transitStep.points[k].y;i++;}}// 通過points構建BMKPolylineBMKPolyline* polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];[_mapView addOverlay:polyLine]; // 添加路線overlaydelete []temppoints;[self mapViewFitPolyLine:polyLine]; }- (void)showBusRoutePlan {BMKMassTransitRouteLine *routeLine = self.massTransitRouteLine;BOOL startCoorIsNull = YES;CLLocationCoordinate2D startCoor;//起點經緯度CLLocationCoordinate2D endCoor;//終點經緯度NSInteger size = [routeLine.steps count];NSInteger planPointCounts = 0;for (NSInteger i = 0; i < size; i++) {BMKMassTransitStep *transitStep = [routeLine.steps objectAtIndex:i];for (BMKMassTransitSubStep *subStep in transitStep.steps) {//添加annotation節點RouteAnnotation *item = [[RouteAnnotation alloc]init];item.coordinate = subStep.entraceCoor;item.title = subStep.instructions;item.type = 2;[_mapView addAnnotation:item];if (startCoorIsNull) {startCoor = subStep.entraceCoor;startCoorIsNull = NO;}endCoor = subStep.exitCoor;//軌跡點總數累計planPointCounts += subStep.pointsCount;//steps中是方案還是子路段,YES:steps是BMKMassTransitStep的子路段(A到B需要經過多個steps);NO:steps是多個方案(A到B有多個方案選擇)if (transitStep.isSubStep == NO) {//是子方案,只取第一條方案break;}else {//是子路段,需要完整遍歷transitStep.steps}}}//添加起點標注RouteAnnotation *startAnnotation = [[RouteAnnotation alloc]init];startAnnotation.coordinate = startCoor;startAnnotation.title = @"起點";startAnnotation.type = 0;[_mapView addAnnotation:startAnnotation]; // 添加起點標注//添加終點標注RouteAnnotation *endAnnotation = [[RouteAnnotation alloc]init];endAnnotation.coordinate = endCoor;endAnnotation.title = @"終點";endAnnotation.type = 1;[_mapView addAnnotation:endAnnotation]; // 添加起點標注//軌跡點BMKMapPoint *temppoints = new BMKMapPoint[planPointCounts];NSInteger index = 0;for (BMKMassTransitStep *transitStep in routeLine.steps) {for (BMKMassTransitSubStep *subStep in transitStep.steps) {for (NSInteger i = 0; i < subStep.pointsCount; i++) {temppoints[index].x = subStep.points[i].x;temppoints[index].y = subStep.points[i].y;index++;}//steps中是方案還是子路段,YES:steps是BMKMassTransitStep的子路段(A到B需要經過多個steps);NO:steps是多個方案(A到B有多個方案選擇)if (transitStep.isSubStep == NO) {//是子方案,只取第一條方案break;}else {//是子路段,需要完整遍歷transitStep.steps}}}// 通過points構建BMKPolylineBMKPolyline *polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];[_mapView addOverlay:polyLine]; // 添加路線overlaydelete []temppoints;[self mapViewFitPolyLine:polyLine];}- (void)showWalkRoutePlan {BMKWalkingRouteLine *plan = self.walkingRouteLine;NSInteger size = [plan.steps count];int planPointCounts = 0;for (int i = 0; i < size; i++) {BMKWalkingStep *transitStep = [plan.steps objectAtIndex:i];if(i==0){RouteAnnotation *item = [[RouteAnnotation alloc]init];item.coordinate = plan.starting.location;item.title = @"起點";item.type = 0;[_mapView addAnnotation:item]; // 添加起點標注}else if(i==size-1){RouteAnnotation *item = [[RouteAnnotation alloc]init];item.coordinate = plan.terminal.location;item.title = @"終點";item.type = 1;[_mapView addAnnotation:item]; // 添加起點標注}//添加annotation節點RouteAnnotation *item = [[RouteAnnotation alloc]init];item.coordinate = transitStep.entrace.location;item.title = transitStep.entraceInstruction;item.degree = transitStep.direction *30;item.type = 4;[_mapView addAnnotation:item];//軌跡點總數累計planPointCounts += transitStep.pointsCount;}//軌跡點BMKMapPoint *temppoints = new BMKMapPoint[planPointCounts];int i = 0;for (int j = 0; j < size; j++) {BMKWalkingStep *transitStep = [plan.steps objectAtIndex:j];int k=0;for(k=0;k<transitStep.pointsCount;k++) {temppoints[i].x = transitStep.points[k].x;temppoints[i].y = transitStep.points[k].y;i++;}}// 通過points構建BMKPolylineBMKPolyline *polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];[_mapView addOverlay:polyLine]; // 添加路線overlaydelete []temppoints;[self mapViewFitPolyLine:polyLine];}#pragma mark - 顯示大頭針 - (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation {if (![annotation isKindOfClass:[RouteAnnotation class]]) return nil;return [self getRouteAnnotationView:mapView viewForAnnotation:(RouteAnnotation *)annotation]; }#pragma mark 獲取路線的標注,顯示到地圖 - (BMKAnnotationView*)getRouteAnnotationView:(BMKMapView *)mapview viewForAnnotation:(RouteAnnotation*)routeAnnotation {BMKAnnotationView *view = nil;switch (routeAnnotation.type) {case 0:{view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"start_node"];if (view == nil) {view = [[BMKAnnotationView alloc] initWithAnnotation:routeAnnotation reuseIdentifier:@"start_node"];view.image = [UIImage imageNamed:@"map_start"];//[UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_start"]];view.centerOffset = CGPointMake(0, -(view.frame.size.height * 0.5));view.canShowCallout = true;}view.annotation = routeAnnotation;}break;case 1:{view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"end_node"];if (view == nil) {view = [[BMKAnnotationView alloc] initWithAnnotation:routeAnnotation reuseIdentifier:@"end_node"];view.image = [UIImage imageNamed:@"map_end"];//[UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_end"]];view.centerOffset = CGPointMake(0, -(view.frame.size.height * 0.5));view.canShowCallout = true;}view.annotation =routeAnnotation;}break;case 4:{view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"route_node"];if (view == nil) {view = [[BMKAnnotationView alloc] initWithAnnotation:routeAnnotation reuseIdentifier:@"route_node"];view.canShowCallout = true;} else {[view setNeedsDisplay];}UIImage *image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_direction"]];view.image = [image imageRotatedByDegrees:routeAnnotation.degree];view.annotation = routeAnnotation;}break;default:break;}return view; }#pragma mark 根據overlay生成對應的View -(BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id<BMKOverlay>)overlay {if ([overlay isKindOfClass:[BMKPolyline class]]) {BMKPolylineView* polylineView = [[BMKPolylineView alloc] initWithOverlay:overlay];polylineView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:1];polylineView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];polylineView.lineWidth = 3.0;return polylineView;}return nil; }#pragma mark 根據polyline設置地圖范圍 - (void)mapViewFitPolyLine:(BMKPolyline *) polyLine {CGFloat ltX, ltY, rbX, rbY;if (polyLine.pointCount < 1) return;BMKMapPoint pt = polyLine.points[0];ltX = pt.x, ltY = pt.y;rbX = pt.x, rbY = pt.y;for (int i = 0; i < polyLine.pointCount; i++) {BMKMapPoint pt = polyLine.points[i];if (pt.x < ltX) {ltX = pt.x;}if (pt.x > rbX) {rbX = pt.x;}if (pt.y > ltY) {ltY = pt.y;}if (pt.y < rbY) {rbY = pt.y;}}BMKMapRect rect;rect.origin = BMKMapPointMake(ltX , ltY);rect.size = BMKMapSizeMake(rbX - ltX, rbY - ltY);[_mapView setVisibleMapRect:rect];_mapView.zoomLevel = _mapView.zoomLevel - 0.3; }// RouteAnnotation 自定義的類/** 路線的標注*/@interface RouteAnnotation : BMKPointAnnotation@property (nonatomic) int type; ///<0:起點 1:終點 2:公交 3:地鐵 4:駕乘 5:途經點@property (nonatomic) int degree;@end@implementation RouteAnnotation@end 復制代碼二、使用本機的地圖導航
通常自己的手機都會安裝有百度地圖、高德地圖、騰訊等等 1.實現步驟 1.1 添加應用白名單
<string>baidumap</string><string>iosamap</string><string>comgooglemaps</string><string>qqmap</string> 復制代碼1.2 info.plist添加對應的url schemes
百度地圖: baidumap:// 騰訊地圖: qqmap:// 谷歌地圖: comgooglemaps:// 高德地圖: iosamap:// 復制代碼1.3 使用的第三方框架
pod 'LCActionSheet' // 彈窗選擇pod 'JZLocationConverter' // 經緯度轉換(主要解決百度地圖和谷歌地圖用的不是同一種標準的問題) 復制代碼1.4 具體實現代碼
// 引入頭文件 #import <LCActionSheet/LCActionSheet.h> #import <JZLocationConverter/JZLocationConverter.h>#pragma mark - 導航方法 - (NSArray *)getInstalledMapApp {NSArray *locationArray = [self.poiMD.address_x_y componentsSeparatedByString:@","];// lat lngCLLocationCoordinate2D endLocation = CLLocationCoordinate2DMake([locationArray.lastObject floatValue], [locationArray.firstObject floatValue]);NSMutableArray *maps = [NSMutableArray array];//蘋果地圖NSMutableDictionary *iosMapDic = [NSMutableDictionary dictionary];iosMapDic[@"title"] = @"蘋果地圖";[maps addObject:iosMapDic];//百度地圖if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://"]]) {NSMutableDictionary *baiduMapDic = [NSMutableDictionary dictionary];baiduMapDic[@"title"] = @"百度地圖";NSString *urlString = [[NSString stringWithFormat:@"baidumap://map/direction?origin={{我的位置}}&destination=latlng:%f,%f|name=北京&mode=driving&coord_type=gcj02",endLocation.latitude,endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];baiduMapDic[@"url"] = urlString;[maps addObject:baiduMapDic];}//高德地圖if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"iosamap://"]]) {NSMutableDictionary *gaodeMapDic = [NSMutableDictionary dictionary];gaodeMapDic[@"title"] = @"高德地圖";NSString *urlString = [[NSString stringWithFormat:@"iosamap://navi?sourceApplication=%@&backScheme=%@&lat=%f&lon=%f&dev=0&style=2",@"導航功能",@"nav123456",endLocation.latitude,endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];gaodeMapDic[@"url"] = urlString;[maps addObject:gaodeMapDic];}//谷歌地圖if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"comgooglemaps://"]]) {NSMutableDictionary *googleMapDic = [NSMutableDictionary dictionary];googleMapDic[@"title"] = @"谷歌地圖";NSString *urlString = [[NSString stringWithFormat:@"comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving",@"導航測試",@"nav123456",endLocation.latitude, endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];googleMapDic[@"url"] = urlString;[maps addObject:googleMapDic];}//騰訊地圖if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"qqmap://"]]) {NSMutableDictionary *qqMapDic = [NSMutableDictionary dictionary];qqMapDic[@"title"] = @"騰訊地圖";NSString *urlString = [[NSString stringWithFormat:@"qqmap://map/routeplan?from=我的位置&type=drive&tocoord=%f,%f&to=終點&coord_type=1&policy=0",endLocation.latitude, endLocation.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];qqMapDic[@"url"] = urlString;[maps addObject:qqMapDic];}return maps; }- (void)showLCActionSheet {NSArray *maps = [self getInstalledMapApp];NSMutableArray *mapsA = [NSMutableArray array];for (NSDictionary *dict in maps) {[mapsA addObject:dict[@"title"]];}LCActionSheet *actionSheet = [LCActionSheet sheetWithTitle:@"請選擇" cancelButtonTitle:@"取消" clicked:^(LCActionSheet * _Nonnull actionSheet, NSUInteger buttonIndex) {debugLog(@"當前選擇 --- %d",buttonIndex);if (buttonIndex == 0) { // 當前選擇了取消return ;}if ((buttonIndex - 1) == 0) { // 蘋果地圖無論如何都是有的[self navAppleMap];return;}NSDictionary *dic = [self getInstalledMapApp][buttonIndex - 1];NSString *urlString = dic[@"url"];[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];} otherButtonTitleArray:mapsA];actionSheet.blurEffectStyle = UIBlurEffectStyleLight;actionSheet.scrolling = YES;actionSheet.visibleButtonCount = 3.6f;[actionSheet show]; }// 蘋果地圖 - (void)navAppleMap {NSArray *locationArray = [self.poiMD.address_x_y componentsSeparatedByString:@","];// lat lngCLLocationCoordinate2D endLocation = CLLocationCoordinate2DMake([locationArray.lastObject floatValue], [locationArray.firstObject floatValue]);CLLocationCoordinate2D gps = [JZLocationConverter bd09ToWgs84:endLocation];MKMapItem *currentLoc = [MKMapItem mapItemForCurrentLocation];MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:gps addressDictionary:nil]];NSArray *items = @[currentLoc,toLocation];NSDictionary *dic = @{MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving,MKLaunchOptionsMapTypeKey : @(MKMapTypeStandard),MKLaunchOptionsShowsTrafficKey : @(YES)};[MKMapItem openMapsWithItems:items launchOptions:dic]; }復制代碼總結
以上是生活随笔為你收集整理的【整理之路二】百度地图的路径规划和调用本机地图导航的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Fibonacci数列使用迭代器实现
- 下一篇: IntelliJ IDEA 添加copy