Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MKPolylineRenderer produces jagged, unequal paths

I am using the iOS 7 MapKit APIs to produce 3D camera movements on a map that displays an MKDirectionsRequest-produced path. The path is rendered by MKOverlayRenderer like so:

-(void)showRoute:(MKDirectionsResponse *)response
{
for (MKRoute *route in response.routes)
 {
    [self.map
     addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
 }
}

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay
{
 MKPolylineRenderer *renderer =
 [[MKPolylineRenderer alloc] initWithOverlay:overlay];
UIColor *mapOverlayColor = [UIColor colorWithRed:((float)22 / 255.0f) green:((float)126 / 255.0f) blue:((float)251 / 255.0f) alpha:0.8];
 renderer.strokeColor = mapOverlayColor;
 renderer.lineWidth = 13.0;
 return renderer;
}

It's working well except for one issue. When I zoom or pan around the path with MKMapCameras (and without them, if I simply do so as the user), the path is jagged as shown in this screenshot:

screen shot

I tested to see if switching to MKOverlayLevelAboveLabels makes a difference but sadly the outcome was the same.

Does anyone have suggestions as to how to improve the rendering? Does switching to a geodesic path make a difference and if so, how would I implement this here?

like image 848
Alex Fringes Avatar asked Dec 16 '13 00:12

Alex Fringes


1 Answers

Subclass MKPolylineRenderer and override applyStrokePropertiesToContext:atZoomScale: so that it ignores the scale, and draws lines at constant width:

@interface ConstantWidthPolylineRenderer : MKPolylineRenderer
@end

@implementation ConstantWidthPolylineRenderer

- (void)applyStrokePropertiesToContext:(CGContextRef)context
                           atZoomScale:(MKZoomScale)zoomScale
{
    [super applyStrokePropertiesToContext:context atZoomScale:zoomScale];
    CGContextSetLineWidth(context, self.lineWidth);
}

@end

Now use it and admire its smooth rendering:

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
    MKPolyline *polyline = (MKPolyline *)overlay;
    ConstantWidthPolylineRenderer *renderer = [[ConstantWidthPolylineRenderer alloc] initWithPolyline:polyline];
    renderer.strokeColor = [UIColor redColor];
    renderer.lineWidth = 40;
    return renderer;
}
like image 187
Gwendal Roué Avatar answered Nov 12 '22 11:11

Gwendal Roué