Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can not stroke path on mapkit overlay view

Tags:

ios

I am using mapkit on iPhone with iOS 4. I am using a custom overlay and a custom overlay view, to draw shapes on the map. At the moment, shapes are just rectangles, but I am planning something more sophisticated. This is why I am not using the MKPolygon overlay type. This is the code for my overlay view drawing method:

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
    // Clip context to bounding rectangle
    MKMapRect boundingMapRect = [[self overlay] boundingMapRect];
    CGRect boundingRect = [self rectForMapRect:boundingMapRect];
    CGContextAddRect(context, boundingRect);
    CGContextClip(context);

    // Define shape
    CGRect shapeRect = CGRectMake(0.5f, 0.5f, boundingRect.size.width - 1.0f, boundingRect.size.height - 1.0f);

    // Fill
    CGContextSetRGBFillColor(context, 0.5f, 0.5f, 0.5f, 0.5f);
    CGContextFillRect(context, shapeRect);

    // Stroke
    CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.75f);
    CGContextSetLineWidth(context, 1.0f);
    CGContextStrokeRect(context, shapeRect);
}

The problem is that rectangles get correctly filled (so it appears their bounding rect is correctly set), but they don't get stroked. Can anyone help? Thanks!

like image 790
Giorgio Barchiesi Avatar asked Nov 05 '22 10:11

Giorgio Barchiesi


1 Answers

As reported in some previous comments, the problem is with line width. More generally, all drawing is automatically scaled to follow the map zooming, so if you want some of your drawing metrics to be zoom-independent, you have to divide it by zoomScale.

Here is the new code, that works correctly on my iPhone 4:

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
    // Clip context to bounding rectangle
    MKMapRect boundingMapRect = [[self overlay] boundingMapRect];
    CGRect boundingRect = [self rectForMapRect:boundingMapRect];
    CGContextAddRect(context, boundingRect);
    CGContextClip(context);

    // Define shape
    CGRect shapeRect = CGRectInset(boundingRect, 2.0f / zoomScale, 2.0f / zoomScale);

    // Fill
    CGContextSetRGBFillColor(context, 0.5f, 0.5f, 0.5f, 0.5f);
    CGContextFillRect(context, shapeRect);

    // Stroke
    CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.75f);
    CGContextSetLineWidth(context, 4.0f / zoomScale);
    CGContextStrokeRect(context, shapeRect);
}

I will also report the code I am using in the overlay to calculate and return the bounding rectangle, because I think it can help:

-(MKMapRect)boundingMapRect
{
    // Overlay bounds
    CLLocationCoordinate2D topLeftcoordinate = <the top-left coordinate of overlay>;
    CLLocationCoordinate2D bottomRightCoordinate = <the bottom-right coordinate of overlay>;

    // Convert them to map points
    MKMapPoint topLeftPoint = MKMapPointForCoordinate(topLeftcoordinate);
    MKMapPoint bottomRightPoint = MKMapPointForCoordinate(bottomRightCoordinate);

    // Calculate map rect
    return MKMapRectMake(topLeftPoint.x, topLeftPoint.y, bottomRightPoint.x - topLeftPoint.x, topLeftPoint.y - bottomRightPoint.y);
}

Thank you all for your comments and suggestions.

like image 108
Giorgio Barchiesi Avatar answered Nov 12 '22 23:11

Giorgio Barchiesi