應(yīng)用場景
當我們進行逆地理位置后就能確定我們自己所在的位置(起點:經(jīng)度和緯度),然后搜索我們所要到達的目的地(終點:經(jīng)度和緯度)的時候就需要通過地圖的導(dǎo)航功能規(guī)劃一條路線,然后根據(jù)導(dǎo)航到達目的地。
實現(xiàn)思路
1、找到當前自己所在的起點位置經(jīng)緯度;
2、找到到達終點的目的地位置經(jīng)緯度;
3、進行路徑規(guī)劃并繪制線路;
4、根據(jù)道路信息進行路況分析;
5、為路徑添加紋理;
根據(jù)以上步驟,本文只展示實現(xiàn)過程中的核心代碼,其余代碼請查看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、初始化導(dǎo)航管理器
- (void)initDriveManager {
//請在 dealloc 函數(shù)中執(zhí)行 [AMapNaviDriveManager destroyInstance] 來銷毀單例
[[AMapNaviDriveManager sharedInstance] setDelegate:self];
}
3、確認導(dǎo)航的起始點與終點位置(AMapNaviPoint)
- (void)initProperties {
//為了方便展示駕車多路徑規(guī)劃,選擇了固定的起終點
self.startPoint = [AMapNaviPoint locationWithLatitude:39.993135 longitude:116.474175];
self.endPoint = [AMapNaviPoint locationWithLatitude:39.908791 longitude:116.321257];
}
4、進行單(多)線路規(guī)劃
#pragma mark - Button Action單路徑規(guī)劃
- (void)singleRoutePlanAction:(id)sender {
//進行單路徑規(guī)劃
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、進行路徑規(guī)劃并繪制線路,并根據(jù)道路信息進行路況分析
駕車路徑規(guī)劃成功后的回調(diào)函數(shù)(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米 | 預(yù)估時間:%ld秒 | 分段數(shù):%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];
}
}
//根據(jù)交通狀態(tài)獲得紋理圖片
- (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];
}
//開始導(dǎo)航前進行路徑選擇
- (void)selectNaviRouteWithID:(NSInteger)routeID {
//在開始導(dǎo)航前進行路徑選擇
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對應(yīng)的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
查看地圖更多內(nèi)容請點擊以下鏈接:
固定在地圖中心的大頭針,移動地圖并顯示位置
定位