一、细说百度地图的路径规划

路径规划主要有这么几种

1.公交路径规划

1.1 市内公交规划(暂时不在这里说)

1.2 跨市/省公交规划

// 导入头文件

#import

#import

#import

#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.842406

CLLocationCoordinate2D 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

temppoints[i].x = transitStep.points[k].x;

temppoints[i].y = transitStep.points[k].y;

i++;

}

}

// 通过points构建BMKPolyline

BMKPolyline* polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];

[_mapView addOverlay:polyLine]; // 添加路线overlay

delete []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构建BMKPolyline

BMKPolyline *polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];

[_mapView addOverlay:polyLine]; // 添加路线overlay

delete []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

temppoints[i].x = transitStep.points[k].x;

temppoints[i].y = transitStep.points[k].y;

i++;

}

}

// 通过points构建BMKPolyline

BMKPolyline *polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];

[_mapView addOverlay:polyLine]; // 添加路线overlay

delete []temppoints;

[self mapViewFitPolyLine:polyLine];

}

#pragma mark - 显示大头针

- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id )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)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 添加应用白名单

baidumap

iosamap

comgooglemaps

qqmap

1.2 info.plist添加对应的url schemes

百度地图: baidumap://

腾讯地图: qqmap://

谷歌地图: comgooglemaps://

高德地图: iosamap://

1.3 使用的第三方框架

pod 'LCActionSheet' // 弹窗选择

pod 'JZLocationConverter' // 经纬度转换(主要解决百度地图和谷歌地图用的不是同一种标准的问题)

1.4 具体实现代码

// 引入头文件

#import

#import

#pragma mark - 导航方法

- (NSArray *)getInstalledMapApp

{

NSArray *locationArray = [self.poiMD.address_x_y componentsSeparatedByString:@","];

// lat lng

CLLocationCoordinate2D 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 lng

CLLocationCoordinate2D 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];

}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐