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
的颜色。
最简单的方法是使用MKPolyline
的title
属性。
请参阅 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 叠加图的主要内容,如果未能解决你的问题,请参考以下文章
ViewController 作为 Swift 中 MapView 的叠加层(如 Google 地图应用程序用户界面)