iOS開發(fā)之高德地圖的應(yīng)用與開發(fā)之三:線路規(guī)劃繪制并添加紋理

應(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)容請點擊以下鏈接:
固定在地圖中心的大頭針,移動地圖并顯示位置
定位

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容