2013-03-25 2 views
0

Я использую MKOverlayView для рисования пути на карты яблок. Я хотел бы нарисовать на нем много коротких путей, потому что мне нужно раскрасить дорожку в зависимости от некоторых других значений. Но я получаю некоторые причудливые эффекты, делая это таким образом ... также мои начальные и конечные точки связаны, но я не знаю почему. После увеличения/уменьшения изменения fancy-effect-pattern и увеличения/уменьшения. Кажется, что вы можете увидеть плитки ячеек на моем пути ...Необычные эффекты на MKMapOverlay CGPath

Это мой код, вызываемый внутри метода 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-очки, как это. (Из хлебных крошек компании Apple примера)

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 для этой конкретной области, генерируется новый случайный цвет. (Остальная часть пути обрезана, а другой цвет остается ...).

ответ

0

«Причудливые эффекты», которые вы видите, представляют собой комбинацию того, как MKMapView вызывает drawMapRect и ваше решение использовать случайные цвета каждый раз, когда он выполняется. Чтобы ускорить отображение, когда пользователь накладывает карту вокруг MKMapView, кэширует фрагменты из вашего наложения. Если одна плитка выходит из экрана, ее можно выбросить или сохранить в другом кеше или что-то в этом роде, но все, что осталось на экране, просто перемещено и не нужно перерисовывать, что хорошо, потому что рисование может означать поездку на ваши данные поставки или некоторых других длительных вычислений. Вот почему вы вызываете setNeedsDisplayInMapRect, вам нужно только получить эти фрагменты и не перерисовывать все.

Это работает во всех приложениях, которые я видел, и является хорошей системой в целом.Кроме того, когда вы рисуете то, что не будет одинаковым каждый раз, как ваши случайные цвета. Если вы действительно хотите пометить путь таким образом, вы должны использовать хэш или что-то, что кажется случайным, но на самом деле основано на чем-то повторяемом. Может быть, индекс находится в точке, умноженной на координату точки, MD5ed, а затем взять 5-й символ и т. Д. И т. Д. Что бы это ни было, он должен генерировать один и тот же цвет для одной и той же строки, независимо от того, сколько раз он вызывается. Лично я предпочел бы, чтобы линия была одного цвета, может быть, разбита. Но это между вами и вашими пользователями.

+0

Привет, спасибо за объяснение :) Я не буду использовать случайные цвета позже, поэтому проблема будет решена. Но повторять все мои пункты каждый раз, когда нарисован прямоугольник карты. Я должен найти некоторую логику, чтобы избежать этого ... – user2135074

+0

Есть ли причина, по которой вы не создаете MKPolyline и не позволяете просматривать карту? – Craig

+0

Я буду читать о MKPolylines, может быть, это было бы лучшим решением ... но я еще не знаю разницы между модой и CGPath. В любом случае, спасибо :) – user2135074

0

потому что всякий раз, когда вы рисуете любой путь, вам нужно его закрыть. и по мере того как вы закрываете путь, он автоматически рисует линию между lastPoint и firstPoint.

просто удалить последнюю строку в пути рисования

CGContextClosePath(context); 
+0

Из-за этого я добавил строку CGContextClosePath, которая вызывается для каждого небольшого «сегмента» пути. – user2135074

+0

вам не нужно это делать, добавьте все точки один bye один, и пусть ваш путь открыт, не закрывайте его каждый раз. как я думаю. если вы можете разместить свой массив точек здесь, я могу проверить его с моим проектом. –

+0

Я обновлю свое основное сообщение, просто подождите минуту :) – user2135074

0

Целью CGContextClosePath является в буквальном смысле закрыть путь - подключить начальную и конечную точки. Вам это не нужно, StrokePath уже нарисовал путь. Удалите строку. Также перемещайте CGContextStrokePath за пределы своей петли, подход заключается в перемещении/добавлении линии/перемещении/добавлении линии ... и затем обводке (вы можете менять цвета по мере того, как вы это делаете).

Для «причудливых эффектов» (привязка наклонной линии) исследуйте эффекты возможных параметров вызова CGContextSetLineJoin и CGContextSetLineCap.

+0

Эй, я удалил строку CGContextClosePath, но ни одна из моих двух проблем не была решена. В любом случае, спасибо :) – user2135074

+0

И вы также использовали CGContextSetLineJoin? –

+0

Я попробую :) Один момент ... спасибо за ваш ответ. – user2135074