示例中心
功能在线体验
menu 导航 closed 关闭

步行路线规划

该示例将步行路线规划方案以Overlay和列表两种方式显示。
00:00 / 01:00
扫描二维码在手机端体验功能
体验移动端 扫码体验移动端

示例特点

将规划出来的步行路线以 Overlay 和列表两种表现形式展示,同时将 WalkRouteOverlay 开源,帮助您做特殊样式的显示方案。

用到产品

Android 地图 SDK

核心类/接口

接口

说明

版本

RouteSearch.WalkRouteQuery

WalkRouteQuery(RouteSearch.FromAndTo fromAndTo, int mode)

构造函数,构造步行路线规划查询参数对象。

V2.1.0版本起

RouteSearch

calculateWalkRouteAsyn(RouteSearch.WalkRouteQuery walkQuery)

步行路线规划异步接口。

V2.1.0版本起

RouteSearch.OnRouteSearchListener

onWalkRouteSearched(WalkRouteResult walkRouteResult, int errorCode)

步行路径规划结果的回调方法。

V2.1.0版本起

WalkRouteResult

getPaths()

返回步行路径规划方案。

V2.1.0版本起

WalkPath

getSteps()

返回步行规划方案的路段列表。

V2.1.0版本起

WalkStep

getPolyline()

返回步行路段的坐标点集合。

V2.1.0版本起

核心难点

1、如何解析步行路线规划结果对象?

a)通过 WalkRouteResult.getPaths() 方法获取全部的步行路线规划的列表,列表中是 WalkPath 对象。

b)WalkPath 对象就是一个完整步行路线方案,每条路线都是由多个 WalkStep 构成。

c)通过 WalkStep 对象,可以通过 getPolyline() 方法获取这个 Step 的坐标点集合。

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

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

 

  • 修改 getStartBitmapDescriptor() 方法的返回值,可以修改起点的图标。
  • 修改 getWalkColor() 方法的返回值,可以修改步行路线的颜色。
00:00 / 01:00
扫描二维码在手机端体验功能
体验移动端 扫码体验移动端

示例特点

将规划出来的步行路线以 Overlay 显示在地图上,同时也以列表展示路线详情。

用到产品

iOS 地图 SDK

核心类/接口

接口

说明

版本

MAMapView

addOverlay:

向地图窗口添加Overlay。

V2.0.0版本起


addAnnotation:

向地图窗口添加标注。

V2.0.0版本起

MAMapViewDelegate

mapView:viewForAnnotation:

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

V2.0.0版本起


mapView:rendererForOverlay:

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

V3.0.0版本起

AMapSearchAPI

AMapWalkingRouteSearch:

步行路径规划查询接口。

V3.0.0版本起

AMapWalkingRouteSearchRequest

multipath

是否提供备选步行方案([default = 0])0-只提供一条步行方案; 1-提供备选步行方案(有可能无备选方案) 。

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 属性获取这个路段的坐标点,用于绘制路线。

在本示例中,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 = MANaviAnnotationTypeWalking; //走路类型

    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:NO 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.walking //步行类型

    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: false, 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、如何更改显示在地图上的路线的的样式(包括:出发点和目的地的图标、路线的颜色、宽度等等)。

//地图上覆盖物的渲染,可以设置路径线路的宽度,颜色等
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id<MAOverlay>)overlay {
    
    //虚线,如需要步行的
    if ([overlay isKindOfClass:[LineDashPolyline class]]) {
        MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:((LineDashPolyline *)overlay).polyline];
        polylineRenderer.lineWidth = 6;
        polylineRenderer.lineDash = YES;
        polylineRenderer.strokeColor = [UIColor redColor];
        
        return polylineRenderer;
    }
    
    //showTraffic为NO时,不需要带实时路况,路径为单一颜色,比如步行线路目前为海蓝色
    if ([overlay isKindOfClass:[MANaviPolyline class]]) {
        MANaviPolyline *naviPolyline = (MANaviPolyline *)overlay;
        MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:naviPolyline.polyline];
        
        polylineRenderer.lineWidth = 6;
        
        if (naviPolyline.type == MANaviAnnotationTypeWalking) {
            polylineRenderer.strokeColor = self.naviRoute.walkingColor;
        } else if (naviPolyline.type == MANaviAnnotationTypeRailway) {
            polylineRenderer.strokeColor = self.naviRoute.railwayColor;
        } else {
            polylineRenderer.strokeColor = self.naviRoute.routeColor;
        }
        
        return polylineRenderer;
    }
    
    //showTraffic为YES时,需要带实时路况,路径为多颜色渐变
    if ([overlay isKindOfClass:[MAMultiPolyline class]]) {
        MAMultiColoredPolylineRenderer * polylineRenderer = [[MAMultiColoredPolylineRenderer alloc] initWithMultiPolyline:overlay];
        
        polylineRenderer.lineWidth = 6;
        polylineRenderer.strokeColors = [self.naviRoute.multiPolylineColors copy];
        
        return polylineRenderer;
    }
    
    return nil;
}

//地图上的起始点,终点,拐点的标注,可以自定义图标展示等,只要有标注点需要显示,该回调就会被调用
- (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!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {
    
    //虚线,如需要步行的
    if overlay.isKind(of: LineDashPolyline.self) {
        let naviPolyline: LineDashPolyline = overlay as! LineDashPolyline
        let renderer: MAPolylineRenderer = MAPolylineRenderer(overlay: naviPolyline.polyline)
        renderer.lineWidth = 6
        renderer.strokeColor = UIColor.red
        renderer.lineDash = true
        
        return renderer
    }
    
    //showTraffic为NO时,不需要带实时路况,路径为单一颜色,比如步行线路目前为海蓝色
    if overlay.isKind(of: MANaviPolyline.self) {
        
        let naviPolyline: MANaviPolyline = overlay as! MANaviPolyline
        let renderer: MAPolylineRenderer = MAPolylineRenderer(overlay: naviPolyline.polyline)
        renderer.lineWidth = 6
        
        if naviPolyline.type == MANaviAnnotationType.walking {
            renderer.strokeColor = naviRoute?.walkingColor
        }
        else if naviPolyline.type == MANaviAnnotationType.railway {
            renderer.strokeColor = naviRoute?.railwayColor;
        }
        else {
            renderer.strokeColor = naviRoute?.routeColor;
        }
        
        return renderer
    }
    
    //showTraffic为YES时,需要带实时路况,路径为多颜色渐变
    if overlay.isKind(of: MAMultiPolyline.self) {
        let renderer: MAMultiColoredPolylineRenderer = MAMultiColoredPolylineRenderer(multiPolyline: overlay as! MAMultiPolyline!)
        renderer.lineWidth = 6
        renderer.strokeColors = naviRoute?.multiPolylineColors
        
        return renderer
    }
    
    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
}