简体   繁体   English

MapKit上绘制路径的问题

[英]Issue with drawing path over MapKit

I have created an application that constantly reads the current user coordinates and store them in a SQLite database. 我创建了一个应用程序,该应用程序不断读取当前用户坐标并将其存储在SQLite数据库中。
I have a map that is displayed over the whole screen. 我有一个显示在整个屏幕上的地图。
And now I want to draw a line over the map while the user moves. 现在,我想在用户移动时在地图上画一条线。
I already created all this. 我已经创建了所有这些。
The problem is that I can't make it to be a 'live'. 问题是我无法使其成为“生活”。 The Overlay is not updating. 叠加层未更新。
This is the logic: 这是逻辑:
In ViewDidLoad I have 在ViewDidLoad中,我有

...
if (nil != self.routeLine) {
        [self.mapView addOverlay:self.routeLine];
    }

In a function that handle each new coordinates I have: 在处理每个新坐标的函数中,我有:

...
NSString* coordinate = [NSString stringWithFormat:@"%f,%f", thisLocation.longitude, thisLocation.latitude];
            [self.paths addObject:coordinate];

MKMapPoint northEastPoint;
    MKMapPoint southWestPoint;

    // create a c 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);

This is viewForOverlay delegate function: 这是viewForOverlay委托函数:

- (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;
}

In viewDidLoad , the code calls addOverlay with self.routeLine which I assume is initially set to the previously-saved coordinates. viewDidLoad ,代码调用addOverlayself.routeLine我假设初始设置为以前保存的坐标。

The map view adds the MKPoyline that routeLine points to into its internal list of overlays and draws the overlay. 地图视图将routeLine指向的MKPoyline添加到其内部叠加层列表中并绘制叠加层。

Then, in the "function that handles each new coordinate", self.routeLine is changed to point to a new MKPolyline . 然后,在“处理每个新坐标的函数”中,将self.routeLine更改为指向新的 MKPolyline

The reason the overlay view is not updated by the map is because the map view is still using the original MKPolyline that was passed to it when addOverlay was called. 覆盖的观点并没有被更新地图的原因是因为地图视图仍然使用原来MKPolyline传递给它的时候addOverlay被调用。


Since MKPolyline itself is not mutable (it does not allow one to change the list of points/coordinates after creation), there are two main options: 由于MKPolyline本身是不可变的(创建后不允许更改点/坐标列表),因此有两个主要选项:

  • Remove the existing overlay and add a new one with the updated coordinates. 删除现有的叠加层,并使用更新后的坐标添加一个新的叠加层。 This is the simplest option. 这是最简单的选择。 After setting self.routeLine to a new MKPolyline , do the following ( for example ): self.routeLine设置为新的MKPolyline ,执行以下操作( 例如 ):

     [self.mapView removeOverlays:mapView.overlays]; self.routeLineView = nil; [self.mapView addOverlay:self.routeLine]; 

    The main drawback to this simple approach is that the overlay will seem to flicker if the updates are done frequently or if the overlay is large or complex. 这种简单方法的主要缺点是,如果频繁进行更新,或者覆盖很大或很复杂,则覆盖似乎会闪烁。

  • The alternative is to create a custom overlay and overlay view that are mutable and enabling you to dynamically refresh the overlay more quickly and smoothly. 另一种方法是创建一个可变的自定义叠加层和叠加层视图,并使您能够更快,更流畅地动态刷新叠加层。
    Fortunately, Apple has provided a sample app called Breadcrumb which does exactly that. 幸运的是, Apple提供了一个名为Breadcrumb的示例应用程序 ,该应用程序正是这样做的。

Maybe you just forgot to call [self.view setNeedsDisplay] ? 也许您只是忘了打电话给[self.view setNeedsDisplay]

UIView docs UIView文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM