5

I am trying to draw a straight line between two points in overlay view. In MKOverlayView method, I think I am doing correctly but I don't understand why it's not drawing any lines...

Does anyone know why?

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale
          inContext:(CGContextRef)context
{
    UIGraphicsPushContext(context);

    MKMapRect theMapRect = [[self overlay] boundingMapRect];
    CGRect theRect = [self rectForMapRect:theMapRect];

    // Clip the context to the bounding rectangle.
    CGContextAddRect(context, theRect);
    CGContextClip(context);

    CGPoint startP = {theMapRect.origin.x, theMapRect.origin.y};
    CGPoint endP = {theMapRect.origin.x + theMapRect.size.width,
        theMapRect.origin.y + theMapRect.size.height};

    CGContextSetLineWidth(context, 3.0);
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);

    CGContextBeginPath(context);
    CGContextMoveToPoint(context, startP.x, startP.y);
    CGContextAddLineToPoint(context, endP.x, endP.y);
    CGContextStrokePath(context);

    UIGraphicsPopContext();
}

Thank you for your help.

in His Steps
  • 3,075
  • 6
  • 30
  • 38

1 Answers1

3

The line is being drawn using startP and endP which are CGPoint values but they are initialized using theMapRect which contains MKMapPoint values.

Instead, initialize them using theRect which you are converting from theMapRect using rectForMapRect.

Also, for the line width, you may want to scale it using the MKRoadWidthAtZoomScale function. Otherwise, a fixed line width of 3.0 will not be visible unless you are zoomed in very close.

The changed code would look like this:

CGPoint startP = {theRect.origin.x, theRect.origin.y};
CGPoint endP = {theRect.origin.x + theRect.size.width,
    theRect.origin.y + theRect.size.height};

CGContextSetLineWidth(context, 3.0 * MKRoadWidthAtZoomScale(zoomScale));


Finally, instead of a custom MKOverlayView, why not use a MKPolylineView to avoid drawing lines manually?

  • Hi, I have one more question... If I am to initialize CGPoint from boundingMapRect, how should I do???? – in His Steps May 23 '12 at 03:06
  • oh.. and the reason I am not using MkPolylineView is I need to draw an arrow not just straight line.... – in His Steps May 23 '12 at 03:15
  • Not sure what "initialize CGPoint from boundingMapRect" means. Isn't that what you're already doing? What kind of backing MKOverlay are you using -- custom or something like MKPolyline/MKPolygon? ie. What kind of class is `[self overlay]`? Not sure why you would use the boundingMapRect to construct the lines anyway. The MKOverlay should define the location/orientation of the arrow and the view should draw it. Eg. If the overlay contains coordinates, you could convert them to MKMapPoints using `MKMapPointForCoordinate` and then to a CGPoint using `pointForMapPoint:`. –  May 23 '12 at 12:46
  • Another alternative is to create an MKPolygon that has the exact outline of the arrow (calculated with either MKMapPoints or CLLocationCoordinate2Ds) and create a MKPolygonView for it (no custom classes or drawing needed). Another alternative (if you want the arrow to remain a constant size regardless of zoom) is to use an annotation instead of an overlay and use an arrow image. –  May 23 '12 at 12:49
  • The code above is just for testing to see if I can draw custom lines on the map. They don't have any special purposes. But I didn't know that MKPolygonView can do arrow shape.... Thank you very much for your help! – in His Steps May 23 '12 at 16:29