2

I'm trying to display a polyline on my map, but the line doesn't show up. I tried a lot of things, but noting seems to work.

I checked the Core Data functions, and it is returning data, so that is not the problem. It must me somewhere in the mappoint creation or the dwawing on the map (I guess). I'm sure it must be a little mistake somewhere, but I can't find it.

My code:

- (void)viewDidLoad
{
    [super viewDidLoad];

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    mapView.delegate = self;
}

- (void)createLine
{
    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];

    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Logs" inManagedObjectContext:context];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDescription];

    NSError *error;
    NSArray *logs = [context executeFetchRequest:request error:&error];

    int logsCount = [logs count];
    MKMapPoint points[logsCount];

    // loop logs
    for (int i = 0; i < logsCount; i++)
    {
        MKMapPoint point;
        point = MKMapPointMake([[[logs objectAtIndex:i] valueForKey:@"lat"] doubleValue], [[[logs objectAtIndex:i] valueForKey:@"lng"] doubleValue]);

        points[i] = point;
    }

    MKPolyline *routeLine = [MKPolyline polylineWithPoints:points count:logsCount];
    [mapView addOverlay:routeLine];
}

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
    MKOverlayView *mapOverlayView = [[MKOverlayView alloc] initWithOverlay:overlay];
    return mapOverlayView;
}
George Boot
  • 585
  • 2
  • 8
  • 17
  • What does your `mapView:viewForOverlay:` method look like? – Ric Perrott May 30 '13 at 14:21
  • Also note the code is assigning a lat/long to an MKMapPoint. An MKMapPoint is _not_ a latitude/longitude. Use CLLocationCoordinate2D instead of MKMapPoint, CLLocationCoordinate2DMake instead of MKMapPointMake and polylineWithCoordinates instead of polylineWithPoints. –  May 30 '13 at 14:34
  • I changed it to MKMapPoint because i thought that that was the problem. I'll set it back to CLLocationCoordinate2D. I also added my mapView:viewForOverlay. – George Boot May 30 '13 at 14:39

1 Answers1

2

There are two issues with the code shown:

  1. The polyline is being created using MKMapPoints which are incorrectly set to latitude/longitude values. An MKMapPoint is not degrees of latitude/longitude. It is an x/y transformation of a lat/long on the flat map projection. Either convert the latitude/longitude values to MKMapPoints using MKMapPointForCoordinate or just use CLLocationCoordinate2D instead. Just using CLLocationCoordinate2D when you have the lat/long is much easier to code and understand.
  2. In viewForOverlay, the code is creating an empty MKOverlayView which is invisible. Create an MKPolylineView instead (a subclass of MKOverlayView that draws MKPolylines) and set its strokeColor.


For the first issue, use:

  • CLLocationCoordinate2D instead of MKMapPoint,
  • CLLocationCoordinate2DMake instead of MKMapPointMake,
  • and polylineWithCoordinates instead of polylineWithPoints


For the second issue, here's an example:

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
    if ([overlay isKindOfClass:[MKPolyline class]])
    {
        MKPolylineView *mapOverlayView = [[MKPolylineView alloc] initWithPolyline:overlay];
        //add autorelease if not using ARC
        mapOverlayView.strokeColor = [UIColor redColor];
        mapOverlayView.lineWidth = 2;
        return mapOverlayView;
    }

    return nil;
}


A couple of other things:

  • Instead of valueForKey:@"lat", I would use objectForKey:@"lat" (same for @"lng").
  • Make sure the map view's delegate is set otherwise the viewForOverlay delegate method will not get called even with all the other changes.
  • Thank you for the very extensive answer! It is working now :-) One note: the objectForKey:@"" is not working (got an error saying there is no such selector on the object), so I'm using valueForKey:@"". Why should one use objectForKey instead of valueForKey? – George Boot May 30 '13 at 20:48
  • I thought you were calling it on an NSDictionary. See http://stackoverflow.com/questions/1062183/difference-between-objectforkey-and-valueforkey. –  May 30 '13 at 21:44