出行类APP的路径选择。
核心类/接口
类 | 接口 | 说明 | 版本 |
---|---|---|---|
AMapNaviBaseManager | pausesLocationUpdatesAutomatically | 指定定位是否会被系统自动暂停。默认为YES。 | V2.0.0版本起 |
allowsBackgroundLocationUpdates | 开始模拟导航。 | V2.0.0版本起 | |
startEmulatorNavi | 是否允许后台定位。 | V2.0.0版本起 | |
AMapNaviDriveManager | calculateDriveRouteWithStartPoints:endPoints:wayPoints:drivingStrategy: | 带起点的驾车路径规划。 | V2.0.0版本起 |
selectNaviRouteWithRouteID: | 多路径规划时选择路径。 | V2.0.0版本起 | |
getTrafficStatusesWithStartPosition:distance: | 获取某一范围内的路况光柱信息。 | V2.0.0版本起 | |
AMapNaviRoute | routeLength | 导航路径总长度(单位:米)。 | V2.0.0版本起 |
routeTime | 导航路径所需的时间(单位:秒)。 | V2.0.0版本起 | |
routeTollCost | 导航路线的花费金额(单位:元) | V2.0.0版本起 | |
AMapNaviDriveManagerDelegate | driveManagerOnCalculateRouteSuccess: | 驾车路径规划成功后的回调函数 | V2.0.0版本起 |
AMapNaviRoute | routeTrafficLightCount | 获取整条线路的红绿灯数量 | V2.0.0版本起 |
1、显示规划路线的路况。
- (void)addRoutePolylineWithRouteID:(NSInteger)routeID
{
//必须选中路线后,才可以通过driveManager获取实时交通路况
if (![self.driveManager selectNaviRouteWithRouteID:routeID])
{
return;
}
NSArray <AMapNaviPoint *> *oriCoordinateArray = [self.driveManager.naviRoute.routeCoordinates copy];
NSArray <AMapNaviTrafficStatus *> *trafficStatus = [self.driveManager getTrafficStatusesWithStartPosition:0 distance:(int)self.driveManager.naviRoute.routeLength];
NSMutableArray <AMapNaviPoint *> *resultCoords = [[NSMutableArray alloc] init];
NSMutableArray <NSNumber *> *coordIndexes = [[NSMutableArray alloc] init];
NSMutableArray <UIColor *> *strokeColors = [[NSMutableArray alloc] init];
[resultCoords addObject:[oriCoordinateArray objectAtIndex:0]];
//依次计算每个路况的长度对应的polyline点的index
unsigned int i = 1;
NSInteger sumLength = 0;
NSInteger statusesIndex = 0;
NSInteger curTrafficLength = [[trafficStatus firstObject] length];
for ( ; i < [oriCoordinateArray count]; i++)
{
double segDis = [self calcDistanceBetweenPoint:[oriCoordinateArray objectAtIndex:i-1]
andPoint:[oriCoordinateArray objectAtIndex:i]];
//两点间插入路况改变的点
if (sumLength + segDis >= curTrafficLength)
{
if (sumLength + segDis == curTrafficLength)
{
[resultCoords addObject:[oriCoordinateArray objectAtIndex:i]];
[coordIndexes addObject:[NSNumber numberWithInteger:((int)[resultCoords count]-1)]];
}
else
{
double rate = (segDis==0 ? 0 : ((curTrafficLength - sumLength) / segDis));
AMapNaviPoint *extrnPoint = [self calcPointWithStartPoint:[oriCoordinateArray objectAtIndex:i-1]
endPoint:[oriCoordinateArray objectAtIndex:i]
rate:MAX(MIN(rate, 1.0), 0)];
if (extrnPoint)
{
[resultCoords addObject:extrnPoint];
[coordIndexes addObject:[NSNumber numberWithInteger:((int)[resultCoords count]-1)]];
[resultCoords addObject:[oriCoordinateArray objectAtIndex:i]];
}
else
{
[resultCoords addObject:[oriCoordinateArray objectAtIndex:i]];
[coordIndexes addObject:[NSNumber numberWithInteger:((int)[resultCoords count]-1)]];
}
}
//添加对应的strokeColors
[strokeColors addObject:[self defaultColorForStatus:[[trafficStatus objectAtIndex:statusesIndex] status]]];
sumLength = sumLength + segDis - curTrafficLength;
if (++statusesIndex >= [trafficStatus count])
{
break;
}
curTrafficLength = [[trafficStatus objectAtIndex:statusesIndex] length];
}
else
{
[resultCoords addObject:[oriCoordinateArray objectAtIndex:i]];
sumLength += segDis;
}
}
//将最后一个点对齐到路径终点
if (i < [oriCoordinateArray count])
{
while (i < [oriCoordinateArray count])
{
[resultCoords addObject:[oriCoordinateArray objectAtIndex:i]];
i++;
}
[coordIndexes removeLastObject];
[coordIndexes addObject:[NSNumber numberWithInteger:((int)[resultCoords count]-1)]];
}
else
{
while (((int)[coordIndexes count])-1 >= (int)[trafficStatus count])
{
[coordIndexes removeLastObject];
[strokeColors removeLastObject];
}
[coordIndexes addObject:[NSNumber numberWithInteger:((int)[resultCoords count]-1)]];
//需要修改textureImages的最后一个与trafficStatus最后一个一致
[strokeColors addObject:[self defaultColorForStatus:[[trafficStatus lastObject] status]]];
}
//添加Polyline
NSInteger coordCount = [resultCoords count];
CLLocationCoordinate2D *coordinates = (CLLocationCoordinate2D *)malloc(coordCount * sizeof(CLLocationCoordinate2D));
for (int k = 0; k < coordCount; k++)
{
AMapNaviPoint *aCoordinate = [resultCoords objectAtIndex:k];
coordinates[k] = CLLocationCoordinate2DMake(aCoordinate.latitude, aCoordinate.longitude);
}
//创建SelectableTrafficOverlay
SelectableTrafficOverlay *polyline = [SelectableTrafficOverlay polylineWithCoordinates:coordinates count:coordCount drawStyleIndexes:coordIndexes];
polyline.routeID = routeID;
polyline.selected = NO;
polyline.polylineWidth = 10;
polyline.polylineStrokeColors = strokeColors;
if (coordinates != NULL)
{
free(coordinates);
}
[self.mapView addOverlay:polyline level:MAOverlayLevelAboveLabels];
}
func addRoutePolylineWithRouteID(_ routeID: Int) {
//必须选中路线后,才可以通过driveManager获取实时交通路况
if !driveManager.selectNaviRoute(withRouteID: routeID) {
return
}
guard let aRoute = driveManager.naviRoute else {
return
}
//获取路线坐标串
guard let oriCoordinateArray = aRoute.routeCoordinates else {
return
}
guard let trafficStatus = driveManager.getTrafficStatuses(withStartPosition: 0, distance: Int32(aRoute.routeLength)) else {
return
}
//创建带路况信息的polyline,具体代码见Demo
......
mapView.add(polyline, level: .aboveLabels)
}
2、地图上同时显示多条路线时,如何控制这些路线的层级。
- (void)selecteOverlayWithRouteID:(NSInteger)routeID
{
[self.mapView.overlays enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id<MAOverlay> overlay, NSUInteger idx, BOOL *stop)
{
if ([overlay isKindOfClass:[SelectableTrafficOverlay class]])
{
SelectableTrafficOverlay *selectableOverlay = overlay;
/* 获取overlay对应的renderer. */
MAMultiColoredPolylineRenderer * overlayRenderer = (MAMultiColoredPolylineRenderer *)[self.mapView rendererForOverlay:selectableOverlay];
if (selectableOverlay.routeID == routeID)
{
/* 设置选中状态. */
selectableOverlay.selected = YES;
/* 修改renderer选中颜色. */
NSMutableArray *strokeColors = [[NSMutableArray alloc] init];
for (UIColor *aColor in selectableOverlay.polylineStrokeColors)
{
[strokeColors addObject:[aColor colorWithAlphaComponent:1]];
}
selectableOverlay.polylineStrokeColors = strokeColors;
overlayRenderer.strokeColors = selectableOverlay.polylineStrokeColors;
/* 修改overlay覆盖的顺序. */
[self.mapView exchangeOverlayAtIndex:idx withOverlayAtIndex:self.mapView.overlays.count - 1];
[self.mapView showOverlays:@[overlay] animated:YES];
}
else
{
/* 设置选中状态. */
selectableOverlay.selected = NO;
/* 修改renderer选中颜色. */
NSMutableArray *strokeColors = [[NSMutableArray alloc] init];
for (UIColor *aColor in selectableOverlay.polylineStrokeColors)
{
[strokeColors addObject:[aColor colorWithAlphaComponent:0.25]];
}
selectableOverlay.polylineStrokeColors = strokeColors;
overlayRenderer.strokeColors = selectableOverlay.polylineStrokeColors;
}
[overlayRenderer glRender];
}
}];
}
/* 选择对应的polyline,改变polyline的颜色. */
func selecteOverlayWithRouteID(routeID: Int) {
guard let allOverlays = mapView.overlays else {
return
}
for (index, aOverlay) in allOverlays.enumerated() {
if let selectableOverlay = aOverlay as? SelectableTrafficOverlay {
/* 获取overlay对应的renderer. */
let overlayRenderer = mapView.renderer(for: selectableOverlay) as! MAMultiColoredPolylineRenderer
if selectableOverlay.routeID == routeID {
/* 设置选中状态. */
selectableOverlay.selected = true
/* 修改renderer选中颜色. */
var strokeColors = Array<UIColor>()
for aColor in selectableOverlay.polylineStrokeColors {
strokeColors.append(aColor.withAlphaComponent(1.0))
}
selectableOverlay.polylineStrokeColors = strokeColors
overlayRenderer.strokeColors = selectableOverlay.polylineStrokeColors
/* 修改overlay覆盖的顺序. */
mapView.exchangeOverlay(at: UInt(index), withOverlayAt: UInt(mapView.overlays.count - 1))
mapView.showOverlays([aOverlay], animated: true)
}
else {
/* 设置选中状态. */
selectableOverlay.selected = false
/* 修改renderer选中颜色. */
var strokeColors = Array<UIColor>()
for aColor in selectableOverlay.polylineStrokeColors {
strokeColors.append(aColor.withAlphaComponent(0.25))
}
selectableOverlay.polylineStrokeColors = strokeColors
overlayRenderer.strokeColors = selectableOverlay.polylineStrokeColors
}
overlayRenderer.glRender()
}
}
}
3、路线的红绿灯数的计算。
调用 AMapNaviRoute 类的 routeTrafficLightCount 获取整条线路的红绿灯数量即可。
出行类APP的路径选择。
核心类/接口
类 | 接口 | 说明 | 版本 |
---|---|---|---|
AMapNavi | strategyConvert(boolean congestion, boolean avoidspeed, boolean cost, boolean hightspeed, boolean multipleRoute) | 进行算路策略转换,将传入的特定规则转换成PathPlanningStrategy的枚举值。 | V1.8.0版本起 |
calculateDriveRoute(java.util.List from, java.util.List to, java.util.List wayPoints, int strategy) | 计算驾车路径(包含起点)。 | V1.0.0版本起 | |
selectRouteId(int id) | 选择路线ID。 | V1.8.0版本起 | |
startNavi(int naviType) | 开始导航(GPS或模拟)。 | V1.0.0版本起 | |
AMapNaviListener | onCalculateMultipleRoutesSuccess | 多路径驾车路径规划成功后的回调函数。 | V1.0.0版本起 |
AMapNaviPath | getAllLength() | 返回当前导航路线的总长度。 | V1.0.0版本起 |
getAllTime() | 返回当前导航路径所需的时间,单位:秒。 | V1.0.0版本起 | |
getTollCost() | 获取导航段的花费金额,单位:元。 | V1.0.0版本起 | |
AMapNaviStep | getTrafficLightNumber() | 返回当前导航路段的红绿灯数目。 | V1.7.0版本起 |
RouteOverLay | addToMap() | 将规划的路线添加到地图上。 | V1.8.0版本起 |
setTrafficLine(java.lang.Boolean enabled) | 是否开启交通线。 | V1.8.0版本起 | |
setTransparency(float value) | 设置该routeOverlay的透明度。 | V1.8.0版本起 |
1、将规划出来的路线按照实际的交通路况进行显示。
RouteOverLay routeOverLay = new RouteOverLay(mAMap, path, this);
routeOverLay.setTrafficLine(true);
routeOverLay.addToMap();
2、地图上同时显示多条路线时,如何控制这些路线的层级。
规划出来的路线最多有3条,以选中第一条为例,介绍控制层级的逻辑,代码如下:
/**
* 第一条路线是否focus
*
* @param focus focus为true 突出颜色显示,标示为选中状态,为false则标示非选中状态
*/
private void setLinelayoutOne(boolean focus) {
if (mRouteLineLayoutOne.getVisibility() != View.VISIBLE) {
return;
}
try {
int routeID = (int) mRouteLineLayoutOne.getTag();
RouteOverLay overlay = routeOverlays.get(routeID);
if (focus) {
mCalculateRouteOverView.setText(Utils.getRouteOverView(overlay.getAMapNaviPath()));
mAMapNavi.selectRouteId(routeID);
overlay.setTransparency(ROUTE_SELECTED_TRANSPARENCY);
mRouteViewOne.setVisibility(View.VISIBLE);
mRouteTextStrategyOne.setTextColor(getResources().getColor(R.color.colorBlue));
mRouteTextTimeOne.setTextColor(getResources().getColor(R.color.colorBlue));
mRouteTextDistanceOne.setTextColor(getResources().getColor(R.color.colorBlue));
} else {
overlay.setTransparency(ROUTE_UNSELECTED_TRANSPARENCY);
mRouteViewOne.setVisibility(View.INVISIBLE);
mRouteTextStrategyOne.setTextColor(getResources().getColor(R.color.colorDark));
mRouteTextTimeOne.setTextColor(getResources().getColor(R.color.colorBlack));
mRouteTextDistanceOne.setTextColor(getResources().getColor(R.color.colorDark));
}
} catch (Exception e) {
e.printStackTrace();
}
}
3、路线的红绿灯数的计算。
获取每个路段上的红绿灯的数据,进行叠加,进而得到这条路线上的红绿灯的总数。
public static int getTrafficNumber(AMapNaviPath path) {
int trafficLightNumber = 0;
if (path == null) {
return trafficLightNumber;
}
List<AMapNaviStep> steps = path.getSteps();
for (AMapNaviStep step : steps) {
trafficLightNumber += step.getTrafficLightNumber();
}
return trafficLightNumber;
}