通过MapKit绘制path问题
我创build了一个不断读取当前用户坐标并将其存储在SQLite数据库中的应用程序。
我有一个显示在整个屏幕上的地图。
现在我想在用户移动时在地图上划一条线。
我已经创造了这一切。
问题是,我不能让它成为一个“活”。 覆盖未更新。
这是逻辑:
在ViewDidLoad我有
... if (nil != self.routeLine) { [self.mapView addOverlay:self.routeLine]; }
在处理每个新坐标的函数中,我有:
... NSString* coordinate = [NSString stringWithFormat:@"%f,%f", thisLocation.longitude, thisLocation.latitude]; [self.paths addObject:coordinate]; MKMapPoint northEastPoint; MKMapPoint southWestPoint; // create ac array of points. MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * self.paths.count); for(int idx = 0; idx < self.paths.count; idx++) { // break the string down even further to latitude and longitude fields. NSString* currentPointString = [self.paths objectAtIndex:idx]; NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]]; CLLocationDegrees latitude = [[latLonArr objectAtIndex:1] doubleValue]; CLLocationDegrees longitude = [[latLonArr objectAtIndex:0] doubleValue]; // create our coordinate and add it to the correct spot in the array CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude); MKMapPoint point = MKMapPointForCoordinate(coordinate); // adjust the bounding box // if it is the first point, just use them, since we have nothing to compare to yet. if (idx == 0) { northEastPoint = point; southWestPoint = point; } else { if (point.x > northEastPoint.x) northEastPoint.x = point.x; if(point.y > northEastPoint.y) northEastPoint.y = point.y; if (point.x < southWestPoint.x) southWestPoint.x = point.x; if (point.y < southWestPoint.y) southWestPoint.y = point.y; } pointArr[idx] = point; } // create the polyline based on the array of points. self.routeLine = [MKPolyline polylineWithPoints:pointArr count:self.paths.count]; _routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x - southWestPoint.x, northEastPoint.y - southWestPoint.y); // clear the memory allocated earlier for the points free(pointArr);
这是viewForOverlay委托function:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay { MKOverlayView* overlayView = nil; if(overlay == self.routeLine) { //if we have not yet created an overlay view for this overlay, create it now. if(nil == self.routeLineView) { self.routeLineView = [[MKPolylineView alloc] initWithPolyline:self.routeLine]; self.routeLineView.fillColor = [UIColor blueColor]; self.routeLineView.strokeColor = [UIColor blueColor]; self.routeLineView.lineWidth = 5; } overlayView = self.routeLineView; } return overlayView; }
在viewDidLoad
,代码调用addOverlay
与self.routeLine
,我假设最初设置为以前保存的坐标。
地图视图将routeLine
指向的MKPoyline
添加到其覆盖图的内部列表中,并绘制覆盖图。
然后,在“处理每个新坐标的函数”中, self.routeLine
被更改为指向一个新的 MKPolyline
。
覆盖视图未被地图更新的原因是因为地图视图仍然使用在MKPolyline
时传递给它的原始 MKPolyline
。
由于MKPolyline
本身不可变(它不允许在创build后更改点/坐标列表),因此有两个主要选项:
-
删除现有的覆盖,并添加一个新的坐标更新。 这是最简单的select。 将
self.routeLine
设置为新的MKPolyline
,执行以下操作( 例如 ):[self.mapView removeOverlays:mapView.overlays]; self.routeLineView = nil; [self.mapView addOverlay:self.routeLine];
这种简单方法的主要缺点是,如果更新频繁进行,或者覆盖层太大或太复杂,覆盖层就会闪烁。
-
另一种方法是创build一个可变的自定义覆盖和覆盖视图,并使您能够更快速和平滑地dynamic刷新覆盖。
幸运的是, 苹果已经提供了一个名为Breadcrumb的示例应用程序 。
也许你忘了调用[self.view setNeedsDisplay]
?
UIView文档