应用场景
当我们进行逆地理位置后就能确定我们自己所在的位置(起点:经度和纬度),然后搜索我们所要到达的目的地(终点:经度和纬度)的时候就需要通过地图的导航功能规划一条路线,然后根据导航到达目的地。
实现思路
1、找到当前自己所在的起点位置经纬度;
2、找到到达终点的目的地位置经纬度;
3、进行路径规划并绘制线路;
4、根据道路信息进行路况分析;
5、为路径添加纹理;
根据以上步骤,本文只展示实现过程中的核心代码,其余代码请查看demo源码
1、添加地图
self.mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64)];
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.mapView.delegate = self;
self.mapView.mapType = MAMapTypeNavi;
self.mapView.showsCompass = YES;
self.mapView.showTraffic = YES;
// 路线颜色
[self.mapView setTrafficStatus:@{@(MATrafficStatusSlow):[UIColor yellowColor],@(MATrafficStatusJam):[UIColor redColor],@(MATrafficStatusSeriousJam):[UIColor redColor],@(MATrafficStatusSmooth):[UIColor whiteColor]}];
self.mapView.showsUserLocation = YES;
self.mapView.userTrackingMode = MAUserTrackingModeFollow;
[self.view addSubview:self.mapView];
2、初始化导航管理器
- (void)initDriveManager {
//请在 dealloc 函数中执行 [AMapNaviDriveManager destroyInstance] 来销毁单例
[[AMapNaviDriveManager sharedInstance] setDelegate:self];
}
3、确认导航的起始点与终点位置(AMapNaviPoint)
- (void)initProperties {
//为了方便展示驾车多路径规划,选择了固定的起终点
self.startPoint = [AMapNaviPoint locationWithLatitude:39.993135 longitude:116.474175];
self.endPoint = [AMapNaviPoint locationWithLatitude:39.908791 longitude:116.321257];
}
4、进行单(多)线路规划
#pragma mark - Button Action单路径规划
- (void)singleRoutePlanAction:(id)sender {
//进行单路径规划
self.isMultipleRoutePlan = NO;
[[AMapNaviDriveManager sharedInstance] calculateDriveRouteWithStartPoints:@[self.startPoint]
endPoints:@[self.endPoint]
wayPoints:nil
drivingStrategy:[self strategyWithIsMultiple:self.isMultipleRoutePlan]];
- (AMapNaviDrivingStrategy)strategyWithIsMultiple:(BOOL)isMultiple
{
return ConvertDrivingPreferenceToDrivingStrategy(isMultiple,
NO,
NO,
NO,
NO);
}
}
5、进行路径规划并绘制线路,并根据道路信息进行路况分析
驾车路径规划成功后的回调函数(AMapNaviDriveManager)
- (void)driveManager:(AMapNaviDriveManager *)driveManager onCalculateRouteSuccessWithType:(AMapNaviRoutePlanType)type
{
NSLog(@"onCalculateRouteSuccess");
//算路成功后显示路径
[self showMultiColorNaviRoutes];
}
算路成功后显示路径(MultiDriveRoutePolyline:线路绘制类)
- (void)showMultiColorNaviRoutes {
if ([[AMapNaviDriveManager sharedInstance].naviRoutes count] <= 0) {
return;
}
[self.mapView removeOverlays:self.mapView.overlays];
//将路径显示到地图上(正常顺序)
for (NSNumber *aRouteID in [[AMapNaviDriveManager sharedInstance].naviRoutes allKeys]) {
AMapNaviRoute *aRoute = [[[AMapNaviDriveManager sharedInstance] naviRoutes] objectForKey:aRouteID];
int count = (int)[[aRoute routeCoordinates] count];
//添加路径Polyline
CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(count * sizeof(CLLocationCoordinate2D));
for (int i = 0; i < count; i++) {
AMapNaviPoint *coordinate = [[aRoute routeCoordinates] objectAtIndex:i];
coords[i].latitude = [coordinate latitude];
coords[i].longitude = [coordinate longitude];
}
NSMutableArray<UIImage *> *textureImagesArrayNormal = [NSMutableArray new];
NSMutableArray<UIImage *> *textureImagesArraySelected = [NSMutableArray new];
// 添加路况图片
for (AMapNaviTrafficStatus *status in aRoute.routeTrafficStatuses) {
UIImage *img = [self defaultTextureImageForRouteStatus:status.status isSelected:NO];
UIImage *selImg = [self defaultTextureImageForRouteStatus:status.status isSelected:YES];
if (img && selImg) {
[textureImagesArrayNormal addObject:img];
[textureImagesArraySelected addObject:selImg];
}
}
MultiDriveRoutePolyline *mulPolyline = [MultiDriveRoutePolyline polylineWithCoordinates:coords count:count drawStyleIndexes:aRoute.drawStyleIndexes];
mulPolyline.overlay = mulPolyline;
mulPolyline.polylineTextureImages = textureImagesArrayNormal;
mulPolyline.polylineTextureImagesSeleted = textureImagesArraySelected;
mulPolyline.routeID = aRouteID.integerValue;
mulPolyline.routeIDNumber = aRouteID;
[self.mapView addOverlay:mulPolyline];
free(coords);
//更新CollectonView的信息
self.detailDataLabel.text = [NSString stringWithFormat:@"长度:%ld米 | 预估时间:%ld秒 | 分段数:%ld", (long)aRoute.routeLength, (long)aRoute.routeTime, (long)aRoute.routeSegments.count];
}
[self.mapView showAnnotations:self.mapView.annotations animated:NO];
if ([[AMapNaviDriveManager sharedInstance].naviRoutes allKeys].count > 0) {
NSNumber *aRouteID = [[[AMapNaviDriveManager sharedInstance].naviRoutes allKeys] firstObject];
[self selectNaviRouteWithID:[aRouteID integerValue]];
} else {
[self selectNaviRouteWithID:0];
}
}
//根据交通状态获得纹理图片
- (UIImage *)defaultTextureImageForRouteStatus:(AMapNaviRouteStatus)routeStatus isSelected:(BOOL)isSelected {
NSString *imageName = nil;
if (routeStatus == AMapNaviRouteStatusSmooth) {
imageName = @"custtexture_green";
} else if (routeStatus == AMapNaviRouteStatusSlow) {
imageName = @"custtexture_slow";
} else if (routeStatus == AMapNaviRouteStatusJam) {
imageName = @"custtexture_bad";
} else if (routeStatus == AMapNaviRouteStatusSeriousJam) {
imageName = @"custtexture_serious";
} else {
imageName = @"custtexture_no";
}
if (!isSelected) {
imageName = [NSString stringWithFormat:@"%@_unselected",imageName];
}
return [UIImage imageNamed:imageName];
}
//开始导航前进行路径选择
- (void)selectNaviRouteWithID:(NSInteger)routeID {
//在开始导航前进行路径选择
if ([[AMapNaviDriveManager sharedInstance] selectNaviRouteWithRouteID:routeID]) {
[self selecteOverlayWithRouteID:routeID];
} else {
NSLog(@"路径选择失败!");
}
}
- (void)selecteOverlayWithRouteID:(NSInteger)routeID {
NSMutableArray *selectedPolylines = [NSMutableArray array];
CGFloat backupRoutePolylineWidthScale = 0.8; //备选路线是当前路线宽度0.8
[self.mapView.overlays enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id<MAOverlay> overlay, NSUInteger idx, BOOL *stop) {
if ([overlay isKindOfClass:[MultiDriveRoutePolyline class]]) {
MultiDriveRoutePolyline *multiPolyline = overlay;
/* 获取overlay对应的renderer. */
MAMultiTexturePolylineRenderer * overlayRenderer = (MAMultiTexturePolylineRenderer *)[self.mapView rendererForOverlay:multiPolyline];
if ([multiPolyline.routeIDNumber integerValue] == routeID) {
[selectedPolylines addObject:overlay];
} else {
// 修改备选路线的样式
overlayRenderer.lineWidth = AMapNaviRoutePolylineDefaultWidth * backupRoutePolylineWidthScale;
overlayRenderer.strokeTextureImages = multiPolyline.polylineTextureImages;
}
}
}];
[self.mapView removeOverlays:selectedPolylines];
[self.mapView addOverlays:selectedPolylines];
}
6、显示绘制线路纹理
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id<MAOverlay>)overlay {
if ([overlay isKindOfClass:[SelectableOverlay class]]) {
SelectableOverlay * selectableOverlay = (SelectableOverlay *)overlay;
id<MAOverlay> actualOverlay = selectableOverlay.overlay;
MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:actualOverlay];
polylineRenderer.lineWidth = 8.f;
polylineRenderer.strokeColor = selectableOverlay.isSelected ? selectableOverlay.selectedColor : selectableOverlay.regularColor;
return polylineRenderer;
} else if ([overlay isKindOfClass:[MultiDriveRoutePolyline class]]) {
MultiDriveRoutePolyline *mpolyline = (MultiDriveRoutePolyline *)overlay;
MAMultiTexturePolylineRenderer *polylineRenderer = [[MAMultiTexturePolylineRenderer alloc] initWithMultiPolyline:mpolyline];
polylineRenderer.lineWidth = AMapNaviRoutePolylineDefaultWidth;
polylineRenderer.lineJoinType = kMALineJoinRound;
polylineRenderer.strokeTextureImages = mpolyline.polylineTextureImagesSeleted;
return polylineRenderer;
}
return nil;
}
案例demo如下:
https://github.com/Wululu6/MapKitDemo1.git
查看地图更多内容请点击以下链接:
固定在地图中心的大头针,移动地图并显示位置
定位
网友评论