This is driving me nuts. I've been through all the posts on stackoveflow, but nothing fits the bill. I am trying to add a simple polyline (i.e. not a custom overlay) as an overlay to my MKMapView
. The viewForOverlay
method on the delegate never gets called. The map delegate is correctly called for every other delegate function. Here is the code from the viewForOverlay
method:
//maanges the overlay
- (MKOverlayView *)mapView:(MKMapView *)map viewForOverlay:(id <MKOverlay>)overlay{
NSLog(@"does it ask for the overlay view?");
MKOverlayView *overlayView = nil;
return overlayView;
}
Here is the code where I construct the polyline and add it to the map:
MKPolyline *thePolyline = [MKPolyline polylineWithPoints:pts count:[arrOfPoints count]];
[thePolyline setTitle:@"line"];
[mapView addOverlay:thePolyline];
The polyline does in fact have my collection of points (about 1000), so I don't think the issue is there. Am I missing some required property or some other implementation on the map view?
EDIT Shows the code for polyline MKMapPoint
generation:
I use an xml file with about 1100 points to generate the polyline as part of an appConfig process. I read and parse the file with NSXMLParser
and NSXMLParserDelegate
respectively. Here is the code that generates the points (from the foundCharacters
method in the NSXMLParserDelegate
protocol):
//NSXMLParserDelegate methods...
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if(POINT){
NSArray *arr = [string componentsSeparatedByString:@","];
MKMapPoint pt = MKMapPointMake([[arr objectAtIndex:1]doubleValue], [[arr objectAtIndex:0]doubleValue]);
MapPointObject *thePoint = [[MapPointObject alloc] init];
thePoint.mapPoint = pt;
//gives the mkmappoint to the array of points.
[arrOfPoints addObject:thePoint];
[thePoint release];
}
}
and here is the where the points actually generate the MKPolyline
and gives it to the mapView
(from the didEndElement
method on the NSXMLParserDelegate
protocol):
if([elementName isEqualToString:@"appConfig"]){
MKMapPoint *pts = malloc([arrOfPoints count] * sizeof(MKMapPoint));
for(int i = 0; i <= [arrOfPoints count] - 1; i++){
MapPointObject *pointObject = [arrOfPoints objectAtIndex:i];
pts[i] = pointObject.mapPoint;
}
MKPolyline *thePolyline = [MKPolyline polylineWithPoints:pts count:[arrOfPoints count]];
[thePolyline setTitle:@"line"];
//adding the polyline to the model's mapview
Model *theModel = [Model sharedModel];
[theModel.mapView setVisibleMapRect:thePolyline.boundingMapRect animated:YES];
[theModel.mapView addOverlay:thePolyline];
free(pts);
}
The point count property on the MKPolyline
does in fact say that there are 1100 points in it.
EDIT: sample XML values:
<appConfig>
<point>-94.847587,38.977967</point>
<point>-94.844111,38.977978</point>
<point>-94.844108,38.977369</point>
<point>-94.844003,38.977369</point>
<point>-94.843955,38.974886</point>
The xml file contains coordinates (latitude and longitude) values. These coordinate values are not the same thing as MKMapPoint
values (which are the map view's x,y projection of the lat/long onto the flat map).
You should be storing coordinates and not MKMapPoint
values (which you are).
So instead of using MKMapPoint
and polylineWithPoints
, use CLLocationCoordinate2D
and polylineWithCoordinates
.
In the xml parser method, create and store a CLLocationCoordinate2D
using CLLocationCoordinate2DMake
.
The pts
array should be of type CLLocationCoordinate2D *
and when doing the malloc
, use sizeof(CLLocationCoordinate2D)
.
Then call polylineWithCoordinates
instead of polylineWithPoints
.
By the way, you'll also need to actually return a non-nil overlay view in viewForOverlay
after making the above changes otherwise you still won't see the line:
MKPolylineView *polylineView = [[[MKPolylineView alloc] initWithPolyline:overlay] autorelease];
polylineView.strokeColor = [UIColor redColor];
polylineView.lineWidth = 2.0;
return polylineView;