0

我正在使用 MKOverlayView 在苹果地图上绘制路径。我想在上面画很多短路径,因为我需要根据其他一些值对轨道进行着色。但是我这样做会得到一些花哨的效果……我的起点和终点也是相连的,但我不知道为什么。放大/缩小后,花式效果图案会发生变化并变大/变小。看来您可以在我的路径上看到苹果地图图块...

这是我的代码,它在我的覆盖视图的 drawMapRect 方法中调用。

for(int i = 0; i < tdpoints.pointCount-1; i++ ){
    CGPoint firstCGPoint = [self pointForMapPoint:tdpoints.points[i]];
    CGPoint secCGPoint = [self pointForMapPoint:tdpoints.points[i+1]];

    if (lineIntersectsRect(tdpoints.points[i], tdpoints.points[i+1], clipRect)){            

        double val1 = (arc4random() % 10) / 10.0f;
        double val2 = (arc4random() % 10) / 10.0f;
        double val3 = (arc4random() % 10) / 10.0f;


        CGContextSetRGBStrokeColor(context, val1 ,val2, val3, 1.0f);
        CGContextSetLineWidth(context, lineWidth);

        CGContextBeginPath(context);
        CGContextMoveToPoint(context,firstCGPoint.x,firstCGPoint.y);

        CGContextAddLineToPoint(context, secCGPoint.x, secCGPoint.y);

        CGContextStrokePath(context);
        CGContextClosePath(context);

    }
}

http://imageshack.us/photo/my-images/560/iossimulatorbildschirmf.jpg/

http://imageshack.us/photo/my-images/819/iossimulatorbildschirmf.jpg/

我正在像这样添加我的 GPS 点。(来自面包屑苹果示例)

CLLocationCoordinate2D coord = {.latitude = 49.1,.longitude =12.1f}; 
[self drawPathWithLocations:coord];

CLLocationCoordinate2D coord1 = {.latitude = 49.2,.longitude =12.2f}; 
[self drawPathWithLocations:coord1];

CLLocationCoordinate2D coord2 = {.latitude = 50.1,.longitude =12.9f}; 
[self drawPathWithLocations:coord2];

这是添加方法:

-(void) drawPathWithLocations:(CLLocationCoordinate2D)coord{
if (!self.crumbs)
{

    // This is the first time we're getting a location update, so create
    // the CrumbPath and add it to the map.
    //
    _crumbs = [[CrumbPath alloc] initWithCenterCoordinate:coord];
    [self.trackDriveMapView addOverlay:self.crumbs];

    // On the first location update only, zoom map to user location
    [_trackDriveMapView setCenterCoordinate:coord zoomLevel:_zoomLevel animated:NO];

}   else
{
    // This is a subsequent location update.
    // If the crumbs MKOverlay model object determines that the current location has moved
    // far enough from the previous location, use the returned updateRect to redraw just
    // the changed area.
    //
    // note: iPhone 3G will locate you using the triangulation of the cell towers.
    // so you may experience spikes in location data (in small time intervals)
    // due to 3G tower triangulation.
    //

    MKMapRect updateRect = [self.crumbs addCoordinate:coord];

    if (!MKMapRectIsNull(updateRect))
    {

        // There is a non null update rect.
        // Compute the currently visible map zoom scale
        MKZoomScale currentZoomScale = (CGFloat)(self.trackDriveMapView.bounds.size.width / self.trackDriveMapView.visibleMapRect.size.width);
        // Find out the line width at this zoom scale and outset the updateRect by that amount
        CGFloat lineWidth = MKRoadWidthAtZoomScale(currentZoomScale);
        updateRect = MKMapRectInset(updateRect, -lineWidth, -lineWidth);
        // Ask the overlay view to update just the changed area.
        [self.crumbView setNeedsDisplayInMapRect:updateRect];
    }
}

这是 addCoordinate 方法:

    - (MKMapRect)addCoordinate:(CLLocationCoordinate2D)coord
{
   pthread_rwlock_wrlock(&rwLock);

    // Convert a CLLocationCoordinate2D to an MKMapPoint
    MKMapPoint newPoint = MKMapPointForCoordinate(coord);
    MKMapPoint prevPoint = points[pointCount - 1];

    // Get the distance between this new point and the previous point.
    CLLocationDistance metersApart = MKMetersBetweenMapPoints(newPoint, prevPoint);

    NSLog(@"PUNKTE SIND %f METER AUSEINANDER ... ", metersApart);

    MKMapRect updateRect = MKMapRectNull;

    if (metersApart > MINIMUM_DELTA_METERS)
    {
        // Grow the points array if necessary
        if (pointSpace == pointCount)
        {
            pointSpace *= 2;
            points = realloc(points, sizeof(MKMapPoint) * pointSpace);
        }    

        // Add the new point to the points array
        points[pointCount] = newPoint;
        pointCount++;

        // Compute MKMapRect bounding prevPoint and newPoint
        double minX = MIN(newPoint.x, prevPoint.x);
        double minY = MIN(newPoint.y, prevPoint.y);
        double maxX = MAX(newPoint.x, prevPoint.x);
        double maxY = MAX(newPoint.y, prevPoint.y);

        updateRect = MKMapRectMake(minX, minY, maxX - minX, maxY - minY);
    }

    pthread_rwlock_unlock(&rwLock);

    return updateRect;
}

暗示

我认为我的刷新算法只刷新屏幕上整个地图的一个图块,因为每次为这个特定区域调用 drawMapRect 方法时,都会生成一个新的随机颜色。(路径的其余部分被剪裁,颜色保持不变......)。

4

3 回答 3

0

您看到的“奇特效果”是 MKMapView 调用 drawMapRect 的方式和您决定每次绘制时使用随机颜色的组合。当用户在 MKMapView 周围平移地图时加快显示速度,会缓存叠加层中的切片。如果一个图块离开屏幕,它可以被丢弃或存储在不同的缓存或其他东西中,但仍在屏幕上的那些只是移动,不需要重绘,这很好,因为绘图可能意味着访问您的数据供应或其他一些长期计算。这就是您调用 的原因setNeedsDisplayInMapRect,它只需要获取这些图块而不是重绘所有内容。

这适用于我见过的所有应用程序,并且总体上是一个很好的系统。除非你画的东西每次都不一样,比如你的随机颜色。如果您真的想为这样的路径着色,那么您应该使用散列或看起来随机但实际上基于可重复的东西的东西。也许点所在的索引,乘以点坐标,MD5ed,然后取第 5 个字符等等。无论它被调用多少次,它必须为同一行生成相同的颜色。就我个人而言,我宁愿这条线是一种颜色,也许是虚线。但那是你和你的用户之间的事。

于 2013-03-25T21:27:28.430 回答
0

因为每当您绘制任何路径时,您都需要关闭它。当您关闭路径时,它会自动在 lastPoint 和 firstPoint 之间画线。

只需删除路径图中的最后一行

CGContextClosePath(context);
于 2013-03-25T15:28:17.343 回答
0

的目的CGContextClosePath是从字面上关闭路径 - 连接起点和终点。你不需要那个,StrokePath已经画好了路径。删除线。也移动CGContextStrokePath到你的循环之外,方法是移动/添加线/移动/添加线......然后描边(你可以在这样做时改变颜色,你就是这样)。

对于“花式效果”(斜线连接),调查可能的CGContextSetLineJoinCGContextSetLineCap调用参数的效果。

于 2013-03-25T15:29:06.393 回答