示例中心
功能在线体验
控制台

驾车路线规划

该示例介绍了如何在地图以实际的路况显示驾车的路线。
00:00 / 01:00
扫描二维码在手机端体验功能
体验移动端 扫码体验移动端

示例特点

将规划出来的驾车路线按照实际的路况显示在地图上,同时将 DrivingRouteOverlay 开源,帮助您做特殊样式的显示方案。

用到产品

Android 地图 SDK

核心类/接口

接口

说明

版本

RouteSearch.DriveRouteQuery

DriveRouteQuery(RouteSearch.FromAndTo fromAndTo,int mode,java.util.List<LatLonPoint> passedByPoints,java.util.List<java.util.List<LatLonPoint>> avoidpolygons,java.lang.String avoidRoad)

构造函数,构造驾车路线规划查询参数对象。

V2.1.0版本起

RouteSearch

calculateDriveRouteAsyn(RouteSearch.DriveRouteQuery driveQuery)

驾车路线规划异步接口。

V2.1.0版本起

RouteSearch.OnRouteSearchListener

onDriveRouteSearched(DriveRouteResult driveRouteResult, int errorCode)

驾车路径规划结果的回调方法。

V2.1.0版本起

DriveRouteResult

getPaths()

返回驾车路径规划方案。

V2.1.0版本起

DrivePath

getSteps()

返回驾车规划方案的路段列表。

V2.1.0版本起

DriveStep

getPolyline()

返回驾车路段的坐标点集合。

V2.1.0版本起

核心难点

1、如何解析驾车路线规划结果对象?

a)通过 DriveRouteResult.getPaths() 方法获取全部的驾车路线规划的列表,列表中是 DrivePath 对象。

b)DrivePath 对象就是一个完整驾车路线方案,每条路线都是由多个 DriveStep 构成。

c)通过 DriveStep 对象,可以通过 getPolyline() 方法获取这个 Step 的坐标点集合,用来在地图上绘制线路;也可以通过 getAction() 方法获取驾车路段的导航主要操作(如:左转、直行等)。

2、如何更改显示在地图上的 DrivingRouteOverlay 的样式(如:起终点图标、线路的颜色、宽度等)?

在本示例中,DrivingRouteOverlay 已对所有开发者开源,您可以参考源码修改 Overlay 的样式。其中:

 

  • 修改 getcolor(String status) 方法的返回值,可以修改路线的颜色,包括开启路况后,各种路况对应的颜色。
  • 修改 getRouteWidth() 方法的返回值,可以修改路线的宽度。
00:00 / 01:00
扫描二维码在手机端体验功能
体验移动端 扫码体验移动端

示例特点

将规划出来的驾车路线按照实际的路况显示在地图上。

用到产品

iOS 地图 SDK

核心类/接口

接口

说明

版本

MAMapView

addOverlay:

向地图窗口添加Overlay。

V2.0.0版本起


addAnnotation:

向地图窗口添加标注。

V2.0.0版本起

MAMapViewDelegate

mapView:viewForAnnotation:

地图上的起始点,终点,拐点的标注的回调,可以自定义图标展示等。

V2.0.0版本起


mapView:rendererForOverlay:

地图上覆盖物的渲染的回调,可以设置路径线路的宽度,颜色等。

V3.0.0版本起

AMapSearchAPI

AMapDrivingRouteSearch:

驾车路径规划查询接口。

V3.0.0版本起

AMapDrivingRouteSearchRequest

strategy

驾车导航策略([default = 0]) 0-速度优先(时间);1-费用优先(不走收费路段的最快道路);2-距离优先;3-不走快速路;4-结合实时交通(躲避拥堵);5-多策略(同时使用速度优先、费用优先、距离优先三个策略);6-不走高速;7-不走高速且避免收费;8-躲避收费和拥堵;9-不走高速且躲避收费和拥堵

V3.0.0版本起


requireExtension

是否返回扩展信息,默认NO。

V3.0.0版本起

AMapRouteSearchBaseRequest

origin

出发点坐标。

V3.0.0版本起


destination

目的地坐标。

V3.0.0版本起

AMapSearchDelegate

onRouteSearchDone:response:

路径规划查询完成回调。

V3.0.0版本起

核心难点

1、如何解析驾车规划结果对象。

a)通过 response.route.paths 可以获取到 AMapPath 列表。

b)AMapPath 对象就是一条驾车路线,每个方案都是由多个 AMapStep 构成。

c)可以通过 AMapStep.polyline 属性获取这个路段的坐标点,用于绘制路线;也可通过 AMapStep.action 属性获取该导航路段的动作(如:直行、右转等),用于路线的详情展示 。

在本示例中,MANaviRoute 是一个生成路线 Polyline 和起终点以及中间节点的 Annotaion 的工具类,省去了您去解析 response 对象的成本。

//在地图上显示当前选择的路径
- (void)presentCurrentRouteCourse{

    if (self.totalRouteNums <= 0) {
        return;
    }

    [self.naviRoute removeFromMapView];  //清空地图上已有的路线

    self.infoLabel.text = [NSString stringWithFormat:@"共%u条路线,当前显示第%u条",(unsigned)self.totalRouteNums,(unsigned)self.currentRouteIndex + 1];  //提示信息

    MANaviAnnotationType type = MANaviAnnotationTypeDrive; //驾车类型

    AMapGeoPoint *startPoint = [AMapGeoPoint locationWithLatitude:self.startAnnotation.coordinate.latitude longitude:self.startAnnotation.coordinate.longitude]; //起点

    AMapGeoPoint *endPoint = [AMapGeoPoint locationWithLatitude:self.destinationAnnotation.coordinate.latitude longitude:self.destinationAnnotation.coordinate.longitude];  //终点

    //根据已经规划的路径,起点,终点,规划类型,是否显示实时路况,生成显示方案
    self.naviRoute = [MANaviRoute naviRouteForPath:self.route.paths[self.currentRouteIndex] withNaviType:type showTraffic:self.showTrafficSwitch.on startPoint:startPoint endPoint:endPoint];

    [self.naviRoute addToMapView:self.mapView];  //显示到地图上

    UIEdgeInsets edgePaddingRect = UIEdgeInsetsMake(RoutePlanningPaddingEdge, RoutePlanningPaddingEdge, RoutePlanningPaddingEdge, RoutePlanningPaddingEdge); 

    //缩放地图使其适应polylines的展示
    [self.mapView setVisibleMapRect:[CommonUtility mapRectForOverlays:self.naviRoute.routePolylines]
                        edgePadding:edgePaddingRect
                           animated:YES];
}
//在地图上显示当前选择的路径
func presentCurrentRouteCourse() {
    if self.totalRouteNums <= 0 {
        return
    }
    self.naviRoute?.removeFromMapView() //清空地图上已有的路线

    self.infoLabel.text = "共\(UInt(self.totalRouteNums))条路线,当前显示第\(UInt(self.currentRouteIndex) + 1)条"  //提示信息

    let type = MANaviAnnotationType.drive //驾车类型

    let startPoint = AMapGeoPoint.location(withLatitude: CGFloat(self.startAnnotation.coordinate.latitude), longitude: CGFloat(self.startAnnotation.coordinate.longitude)) //起点

    let endPoint = AMapGeoPoint.location(withLatitude: CGFloat(self.destinationAnnotation.coordinate.latitude), longitude: CGFloat(self.destinationAnnotation.coordinate.longitude))  //终点

    //根据已经规划的路径,起点,终点,规划类型,是否显示实时路况,生成显示方案
    self.naviRoute = MANaviRoute(for: self.route.paths[self.currentRouteIndex], withNaviType: type, showTraffic: self.showTrafficSwitch.isOn, start: startPoint, end: endPoint)
    self.naviRoute?.add(to: self.mapView)

    //显示到地图上
    let edgePaddingRect = UIEdgeInsetsMake(RoutePlanningPaddingEdge, RoutePlanningPaddingEdge, RoutePlanningPaddingEdge, RoutePlanningPaddingEdge)
    //缩放地图使其适应polylines的展示
    self.mapView.setVisibleMapRect(CommonUtility.mapRect(forOverlays: self.naviRoute?.routePolylines), edgePadding: edgePaddingRect, animated: true)
}

2、如何更改显示在地图上的路线的的样式(包括:出发点和目的地的图标、路线的颜色、宽度等等)。

//地图上的起始点,终点,拐点的标注,可以自定义图标展示等,只要有标注点需要显示,该回调就会被调用
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation {
    if ([annotation isKindOfClass:[MAPointAnnotation class]]) {
        
        //标注的view的初始化和复用
        static NSString *routePlanningCellIdentifier = @"RoutePlanningCellIdentifier";
        
        MAAnnotationView *poiAnnotationView = (MAAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:routePlanningCellIdentifier];
        
        if (poiAnnotationView == nil) {
            poiAnnotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:routePlanningCellIdentifier];
        }
        
        poiAnnotationView.canShowCallout = YES;
        poiAnnotationView.image = nil;
        
        //拐点的图标标注
        if ([annotation isKindOfClass:[MANaviAnnotation class]]) {
            switch (((MANaviAnnotation*)annotation).type) {
                case MANaviAnnotationTypeRailway:
                    poiAnnotationView.image = [UIImage imageNamed:@"railway_station"];
                    break;
                    
                case MANaviAnnotationTypeBus:
                    poiAnnotationView.image = [UIImage imageNamed:@"bus"];
                    break;
                    
                case MANaviAnnotationTypeDrive:
                    poiAnnotationView.image = [UIImage imageNamed:@"car"];
                    break;
                    
                case MANaviAnnotationTypeWalking:
                    poiAnnotationView.image = [UIImage imageNamed:@"man"];
                    break;
                    
                default:
                    break;
            }
        }else{
            //起点,终点的图标标注
            if ([[annotation title] isEqualToString:(NSString*)RoutePlanningViewControllerStartTitle]) {
                poiAnnotationView.image = [UIImage imageNamed:@"startPoint"];  //起点
            }else if([[annotation title] isEqualToString:(NSString*)RoutePlanningViewControllerDestinationTitle]){
                poiAnnotationView.image = [UIImage imageNamed:@"endPoint"];  //终点
            }
            
        }
        
        return poiAnnotationView;
    }
    
    return nil;
}
func mapView(_ mapView: MAMapView!, viewFor annotation: MAAnnotation!) -> MAAnnotationView! {
    
    if annotation.isKind(of: MAPointAnnotation.self) {
        
        //标注的view的初始化和复用
        let pointReuseIndetifier = "RoutePlanningCellIdentifier"
        var annotationView: MAAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: pointReuseIndetifier)
        
        if annotationView == nil {
            annotationView = MAAnnotationView(annotation: annotation, reuseIdentifier: pointReuseIndetifier)
            annotationView!.canShowCallout = true
            annotationView!.isDraggable = false
        }
        
        annotationView!.image = nil
        
        if annotation.isKind(of: MANaviAnnotation.self) {
            let naviAnno = annotation as! MANaviAnnotation
            
            switch naviAnno.type {
            case MANaviAnnotationType.railway:
                annotationView!.image = UIImage(named: "railway_station")
                break
            case MANaviAnnotationType.drive:
                annotationView!.image = UIImage(named: "car")
                break
            case MANaviAnnotationType.riding:
                annotationView!.image = UIImage(named: "ride")
                break
            case MANaviAnnotationType.walking:
                annotationView!.image = UIImage(named: "man")
                break
            case MANaviAnnotationType.bus:
                annotationView!.image = UIImage(named: "bus")
                break
            }
        }
        else {
            if annotation.title == "起点" {
                annotationView!.image = UIImage(named: "startPoint")
            }
            else if annotation.title == "终点" {
                annotationView!.image = UIImage(named: "endPoint")
            }
        }
        return annotationView!
    }
    
    return nil
}