tags:

views:

62

answers:

1

Hello,

I'm trying to mark a starting pin and ending pin on my map with different colours. Maybe the starting pin in green and the ending pin in red.

My code below, reads the latitude / longitude coordinates from core data and loops around placing a red pin for each object found in core data.

MapPin.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>

@interface MapPin : NSObject <MKAnnotation>{

    CLLocationCoordinate2D coordinate;
}

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

-(id)initwithCoordinates:(CLLocationCoordinate2D)location;

@end

MapPin.m

#import "MapPin.h"


@implementation MapPin

@synthesize coordinate;

-(id)initwithCoordinates:(CLLocationCoordinate2D)location
{
    self = [super init];
    if (self != nil) {
        coordinate = location;
    }
    return self;
}

-(void)dealloc{
[super dealloc];
}
@end

MapViewController.m

-(void)addAnnotations 
{   
    if (![sharedMapID isEqualToString:@""]){
        NSFetchRequest *request = [[NSFetchRequest alloc] init];

        NSEntityDescription *entity = [NSEntityDescription entityForName:@"WayPoint" inManagedObjectContext:managedObjectContext];
        [request setEntity:entity];

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"waypoint_map_id contains[cd] %@", sharedMapID];
        [request setPredicate:predicate];

        NSError *error = nil;
        NSArray *results = [managedObjectContext executeFetchRequest:request error:&error];

        // Check for errors from the FetchRequest
        if (nil == results || nil != error)
            NSLog(@"Error getting results : %@", error);

        listArray = [results mutableCopy];
        [request release];

        // Loop through the array, get the coordinates and display on the map.
        for (int i = 0; i < [listArray count]; i++)
        {       
            NSString *strXCoordinate = [[listArray objectAtIndex: i] valueForKey:@"waypoint_x"];
            NSString *strYCoordinate = [[listArray objectAtIndex: i] valueForKey:@"waypoint_y"];

            double dblXCoordinate = [strXCoordinate doubleValue];
            double dblYCoordinate = [strYCoordinate doubleValue];

            CLLocationCoordinate2D coordinate = {dblYCoordinate, dblXCoordinate};
            MapPin *pin = [[MapPin alloc]initwithCoordinates:coordinate];
            [self.mapView addAnnotation:pin];
            [pin release];
        }

        [listArray release];
    }
}

From what I've read and some examples I found when googling the following code is called for each pin on the map. Its not placing any green pins on my map. Maybe I should passing coordinates to this method and allowing it to place the pin on the map instead of the code above.

    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
    {   
        MKPinAnnotationView *annView = nil;
        annView.pinColor = MKPinAnnotationColorGreen;
        annView.animatesDrop = TRUE;
        annView.canShowCallout = YES;
        annView.calloutOffset = CGPointMake(-5, 5);
        return annView; 
}

Any help or a push in the right direction (excuse the pun) is very much appreciated.

Regards, Stephen

A: 
MKPinAnnotationView *annView = nil;
...

You do not create annotation view here, just operate with nil object (that works fine but does nothing) and return nil - so naturally pin is not display (as it does not exists).

Correct method will look like:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{   
    MKPinAnnotationView *annView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"SomeID"];
    if (!annView){
        annView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"SomeID"] autorelease];
        annView.pinColor = MKPinAnnotationColorGreen;
        annView.animatesDrop = TRUE;
        annView.canShowCallout = YES;
        annView.calloutOffset = CGPointMake(-5, 5);
    }
    annView.annotation = annotation;
    return annView; 
}

Here you try to reuse annotation view if possible (similar way you do with cells in table view), create and setup new one if not

Vladimir
Vladimir, thanks for the reply. I just a little confused as what the should be in place of @"SomeID". I'm reading the Apple documentation for dequeueReusableAnnotationViewWithIdentifier but still a little confused.
Stephen
You can use any string for that - just make sure that you dequeue the view with the same id it was created. You can also use different IDs to create and dequeue different kinds of annotation views (for example you have views for metro stations and bus stops - you can create and dequeue them with different ids and then just set an appropriate annotation to it)
Vladimir