MapView 叠加图

Posted

技术标签:

【中文标题】MapView 叠加图【英文标题】:MapView Overlay Drawing 【发布时间】:2014-05-23 02:44:11 【问题描述】:

我一直面临 mkoverlay 颜色的问题。当我打开地图视图时,有时它不会绘制步行路径,而是会随着骑自行车活动而着色。我不知道如何解决这个问题。即使我没有做过任何骑自行车活动,但它用蓝色绘制了骑自行车活动。

这里是代码实现。

- (void)showLines 

    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];

    NSArray* coordinate_array = [[NSArray alloc] init];
    int arrayCount = 0;
        // walking
    NSData *data =[def objectForKey:@"walking_coordinate"];
    NSMutableArray *walking_array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    coordinate_array = [NSArray arrayWithArray:walking_array];
    arrayCount = (int)[walking_array count];
    color = 1;
    [self parseArray:coordinate_array withArrayCount:arrayCount];

        // driving
    data =[def objectForKey:@"driving_coordinate"];
    NSMutableArray *driving_array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    coordinate_array = [NSArray arrayWithArray:driving_array];
    arrayCount = (int)[driving_array count];
    color = 2;
    [self parseArray:coordinate_array withArrayCount:arrayCount];

        // biking
    data =[def objectForKey:@"biking_coordinate"];
    NSMutableArray *biking_array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    coordinate_array = [NSArray arrayWithArray:biking_array];
    arrayCount = (int)[biking_array count];
    color = 3;
    [self parseArray:coordinate_array withArrayCount:arrayCount];



- (void) parseArray:(NSArray *) coordinate_array withArrayCount:(int)arrayCount

    NSMutableArray *tempArray = [[NSMutableArray alloc] initWithCapacity:0];

    for (int i = 0; i < arrayCount; i++) 
        CoordinateModel *coord = [coordinate_array objectAtIndex:i];
        [tempArray addObject:coord];

        if ((int)coord.latitude == -1 || (int)coord.longitude == -1 || i == arrayCount-1) 
            // this is end of one segment
            [tempArray removeLastObject];
            CLLocationCoordinate2D *pointsCoordinate = (CLLocationCoordinate2D *)malloc(sizeof(CLLocationCoordinate2D) * [tempArray count]);

            for (int j = 0; j < [tempArray count]; j++) 
                CoordinateModel *point = [tempArray objectAtIndex:j];
                CLLocationCoordinate2D old_coordinate = CLLocationCoordinate2DMake(point.latitude, point.longitude);
                pointsCoordinate[j] = old_coordinate;
            //  NSLog(@"(%f, %f)", old_coordinate.latitude, old_coordinate.longitude);
            
            if ([tempArray count] > 0) 
                int countTemp = (int)[tempArray count];
                MKPolyline *polyline = [MKPolyline polylineWithCoordinates:pointsCoordinate count:countTemp];
                [mapView addOverlay:polyline];
                [tempArray removeAllObjects];
            
        
    



- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay

    if([overlay isKindOfClass:[MKPolyline class]])
    
        MKPolylineView *lineView = [[MKPolylineView alloc] initWithPolyline:overlay];
        lineView.lineWidth = 8;

        if (color == 1) 
            // walking
            lineView.strokeColor = [UIColor greenColor];
            lineView.fillColor = [UIColor greenColor];
        
        else if(color == 2) 
            // driving
            lineView.strokeColor = [UIColor redColor];
            lineView.fillColor = [UIColor redColor];
        
        else if(color == 3) 
            // biking
            lineView.strokeColor = [UIColor blueColor];
            lineView.fillColor = [UIColor blueColor];
        
        else 
            lineView.strokeColor = [UIColor blackColor];
            lineView.fillColor = [UIColor blackColor];
        

        return lineView;
    
    return nil;

【问题讨论】:

【参考方案1】:

viewForOverlay 委托方法中,使用外部变量color 设置覆盖颜色,该变量在为每种覆盖类型调用parseArray 之前设置。

但是,无法保证地图视图何时调用委托方法,并且可能会在您已经添加所有的 之后为同一个叠加层多次调用委托方法叠加层(例如,如果您缩放/平移地图并且叠加层重新出现在视图中)。

由于您设置的最后一个 color 值是 3(用于“骑自行车”),因此在添加叠加层后地图视图对委托方法进行的任何调用最终都将使用自行车颜色绘制叠加层。

要解决此问题,您需要能够使用 overlay 参数的某些属性(而不依赖于某些外部变量)确定在委托方法本身内绘制 overlay 的颜色。

最简单的方法是使用MKPolylinetitle 属性。 请参阅 this answer 和 this answer,它们解释了 MKPolyline 具有 title 属性这一事实。

所以你可以在你的情况下做的是:

    color 设为您传递给parseArray 方法的参数。

    parseArray方法中,创建polyline后,将其title设置为颜色:

    polyline.title = [NSString stringWithFormat:@"%d", color];
    

    viewForOverlay 中,检查覆盖的title 属性并相应地设置颜色。请参阅different coloured polygon overlays 中的特定示例(它显示了多边形,但折线也可以这样做)。

【讨论】:

非常感谢 Anna,一如既往地提供非常详细的答案。 如果你有时间帮我解决我最近发布的另一个问题***.com/questions/23820252/…,我会很高兴 安娜,如果你能看看我的问题,我会很高兴与你的专业知识有关。 ***.com/questions/23833758/gps-coordinate-accuracy【参考方案2】:

这是基于 Anna 答案的答案,以帮助任何想在代码中看到的人。

 - (void)showLines2 


        NSUserDefaults *def = [NSUserDefaults standardUserDefaults];

        NSArray* coordinate_array = [[NSArray alloc] init];
        int arrayCount = 0;
            // walking
        NSData *data =[def objectForKey:@"walking_coordinate"];
        NSMutableArray *walking_array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
        coordinate_array = [NSArray arrayWithArray:walking_array];
        arrayCount = (int)[walking_array count];
        color = 1;
        [self parseArray:coordinate_array withArrayCount:arrayCount withColor:color];

            // driving
        data =[def objectForKey:@"driving_coordinate"];
        NSMutableArray *driving_array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
        coordinate_array = [NSArray arrayWithArray:driving_array];
        arrayCount = (int)[driving_array count];
        color = 2;
        [self parseArray:coordinate_array withArrayCount:arrayCount withColor:color];

            // biking
        data =[def objectForKey:@"biking_coordinate"];
        NSMutableArray *biking_array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
        coordinate_array = [NSArray arrayWithArray:biking_array];
        arrayCount = (int)[biking_array count];
        color = 3;
        [self parseArray:coordinate_array withArrayCount:arrayCount withColor:color];

    


- (void) parseArray:(NSArray *) coordinate_array withArrayCount:(int)arrayCount withColor:(int)polyColor

    NSMutableArray *tempArray = [[NSMutableArray alloc] initWithCapacity:0];

    for (int i = 0; i < arrayCount; i++) 
        CoordinateModel *coord = [coordinate_array objectAtIndex:i];
        [tempArray addObject:coord];

        if ((int)coord.latitude == -1 || (int)coord.longitude == -1 || i == arrayCount-1) 
            // this is end of one segment
            [tempArray removeLastObject];
            CLLocationCoordinate2D *pointsCoordinate = (CLLocationCoordinate2D *)malloc(sizeof(CLLocationCoordinate2D) * [tempArray count]);

            for (int j = 0; j < [tempArray count]; j++) 
                CoordinateModel *point = [tempArray objectAtIndex:j];
                CLLocationCoordinate2D old_coordinate = CLLocationCoordinate2DMake(point.latitude, point.longitude);
                pointsCoordinate[j] = old_coordinate;
            //  NSLog(@"(%f, %f)", old_coordinate.latitude, old_coordinate.longitude);
            
            if ([tempArray count] > 0) 
                int countTemp = (int)[tempArray count];
                MKPolyline *polyline = [MKPolyline polylineWithCoordinates:pointsCoordinate count:countTemp];
                polyline.title = [NSString stringWithFormat:@"%d", color];
                [mapView addOverlay:polyline];
                [tempArray removeAllObjects];
            
        
    



    - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
    
        if([overlay isKindOfClass:[MKPolyline class]])
        
            MKPolylineView *lineView = [[MKPolylineView alloc] initWithPolyline:overlay];
            lineView.lineWidth = 8;

    //      ActivityType currentActivityType = [DataManager sharedInstance].activityType;
            if ([overlay.title isEqualToString:@"1"]) 
                // walking
                lineView.strokeColor = [UIColor greenColor];
                lineView.fillColor = [UIColor greenColor];
            
            else if([overlay.title isEqualToString:@"2"]) 
                // driving
                lineView.strokeColor = [UIColor redColor];
                lineView.fillColor = [UIColor redColor];
            
            else if([overlay.title isEqualToString:@"3"]) 
                // biking
                lineView.strokeColor = [UIColor blueColor];
                lineView.fillColor = [UIColor blueColor];
            
            else 
                lineView.strokeColor = [UIColor blackColor];
                lineView.fillColor = [UIColor blackColor];
            

            return lineView;
        
        return nil;
    

【讨论】:

以上是关于MapView 叠加图的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MapView 上集成雷达叠加?

在 osmdroid 中将叠加添加到 MapView

需要在 IOS 的 mapview 上添加一个固定的叠加层

ViewController 作为 Swift 中 MapView 的叠加层(如 Google 地图应用程序用户界面)

来自 MapView Annotation-iOS 的缩略图

Android MapView - 没有使用调试 API 密钥加载图块