Question

I have created a map that has an MKPointAnnotation which is the single point on the map (besides the users location). I am trying to work out how to amend some existing code I have to get the Driving directions to this point.

This is the code that I use early in the application. At this earlier point in the application I have the following which gives me a CLPlaceMark.

[geocoder geocodeAddressString:location
             completionHandler:^(NSArray* placemarks, NSError* error){
                 if (placemarks && placemarks.count > 0) {
                     CLPlacemark *topResult = [placemarks objectAtIndex:0];

Collecting directions:

MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
                         [request setSource:[MKMapItem mapItemForCurrentLocation]];
                         MKPlacemark *mkDest = [[MKPlacemark alloc] initWithPlacemark:topResult];
                         [request setDestination:[[MKMapItem alloc] initWithPlacemark:mkDest]];
                         [request setTransportType:MKDirectionsTransportTypeWalking]; // This can be limited to automobile and walking directions.
                         [request setRequestsAlternateRoutes:NO]; 
                         MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
                         [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
                             if (!error) {
                                 for (MKRoute *route in [response routes]) {
                                     [self.mapView addOverlay:[route polyline] level:MKOverlayLevelAboveRoads]; // Draws the route above roads, but below labels.
                                     // You can also get turn-by-turn steps, distance, advisory notices, ETA, etc by accessing various route properties.
                                 }
                             }
                         }];

Issue
The issue is that later on I seem to only be able to access the self.mapView.annotations. So I have access to the MKPointAnnotation, but I need access to a CLPlacemark for the setDestination on the MKDirectionsRequest.

So the question is how do I get a CLPacemark from a MKPointAnnotation, or is there a different approach to getting directions to a single point without that requirement? Thanks

Was it helpful?

Solution

For the directions request, the MKMapItem needs an MKPlacemark (not a CLPlacemark).

You can create an MKPlacemark directly from coordinates using its initWithCoordinate:addressDictionary: method.

For example:

MKPlacemark *mkDest = [[MKPlacemark alloc] 
                          initWithCoordinate:pointAnnotation.coordinate 
                           addressDictionary:nil];

[request setDestination:[[MKMapItem alloc] initWithPlacemark:mkDest]];

OTHER TIPS

MKPointAnnotation will give you the coordinate, which you can put into CLPlacemark's location.coordinate. I don't think there will be any other readily-available information within an MKPointAnnotation that would be usable in a CLPlacemark.

MKPointAnnotation *annotation = ...;
CLPlacemark *placemark = ...;

placemark.location.coordinate = annotation.coordinate;

Edit: Apologies, I didn't realize that CLPlacemarks are largely read-only. That being said, you can use a reverse-geocode on the coordinate of your MKPointAnnotation in order to get a CLPlacemark. This link has information on how to reverse-geocode to get your CLPlacemark from a CLLocation (populate the location.coordinate with your annotation.coordinate) to look up directions.

You need to use the coordinate property of the MKPointAnnotation and then get the CLPlacemark via CLGeocoder using reverse geocode.

EDIT: Some sample code.

CLLocation *location = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];

CLGeocoder *geocoder = [CLGeocoder new];

[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemark, NSError *error){
    // Grab the placemark   
}];

Otherwise you need to cache the CLPlacemark which you can do on your annotation datasource if you like (remember MKAnnotation is a protocol, there is nothing saying you can't add a property to the backing model).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top