i want display a point to point route inside my mapView, i use this code for create the route:
- (IBAction)backToYourCar {
MKPlacemark *sourcePlacemark = [[MKPlacemark alloc] initWithCoordinate:self.annotationForCar.coordinate addressDictionary:nil];
NSLog(#"coordiante : locationIniziale %f", sourcePlacemark.coordinate.latitude);
MKMapItem *carPosition = [[MKMapItem alloc] initWithPlacemark:sourcePlacemark];
MKMapItem *actualPosition = [MKMapItem mapItemForCurrentLocation];
NSLog(#"coordiante : source %f, ActualPosition %f", carPosition.placemark.coordinate.latitude ,actualPosition.placemark.coordinate.latitude);
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
request.source = actualPosition;
request.destination = carPosition;
request.requestsAlternateRoutes = YES;
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if (error) {
NSLog(#"Error : %#", error);
}
else {
[self showDirections:response]; //response is provided by the CompletionHandler
}
}];
}
and this for show the route on the map:
- (void)showDirections:(MKDirectionsResponse *)response
{
for (MKRoute *route in response.routes) {
[self.mapView addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
}
}
actually this code does nothing.
if i try to print the the distance of route i get the correct value:
route distance: 1910.000000
then the route is right, but i can't understand why it doesn't appear on the map!
Any suggestions?
after a day of research i have solved with this 3 steps:
Set the delegate (self.mapView.delegate = self).
import the MKMapViewDelegate
Implemente the new iOS7 MapView delegate method:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay(id<MKOverlay>)overlay:
this is my implementation:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKPolyline class]]) {
MKPolyline *route = overlay;
MKPolylineRenderer *routeRenderer = [[MKPolylineRenderer alloc] initWithPolyline:route];
routeRenderer.strokeColor = [UIColor blueColor];
return routeRenderer;
}
else return nil;
}
this method is automatically called by the delegate when you add the polyline on the map.
Related
I plot the route between source and destination using the following piece of code. After plotting the route sucessfully, I get a list of coordinates where I wanted to plot another route on top of existing one with different color.
The use case I am trying to code is, we set source and destination, plot the dotted route once, then plot the actual line based on the list of locations
From the code, I can see the dotted line but can not see the another line overlapping on it.
My code is:
-(void) getDirection {
CLLocationCoordinate2D sourceCoords = CLLocationCoordinate2DMake(42.130655, -71.041158);
MKPlacemark *sourcePlacemark = [[MKPlacemark alloc] initWithCoordinate:sourceCoords addressDictionary:nil];
MKMapItem *source = [[MKMapItem alloc] initWithPlacemark:sourcePlacemark];
// Make the destination location
CLLocationCoordinate2D destinationCoords = CLLocationCoordinate2DMake(42.128121, -70.936151); MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:destinationCoords addressDictionary:nil];
MKMapItem *destination = [[MKMapItem alloc] initWithPlacemark:destinationPlacemark];
MKDirectionsRequest *directionsRequest = [MKDirectionsRequest new];
[directionsRequest setSource:source];
[directionsRequest setDestination:destination];
[self sourceMarker:sourcePlacemark];
[self destinationMarker:destinationPlacemark];
//
//routeCoords
NSInteger nuberOfStesps = routeCoords.count;
CLLocationCoordinate2D *pointsCoordinate = (CLLocationCoordinate2D *)malloc(sizeof(CLLocationCoordinate2D) * nuberOfStesps);
for (NSInteger index=0; index < nuberOfStesps; index++) {
CLLocation *location = [routeCoords objectAtIndex:index];
coordinate2 = location.coordinate;
//NSLog(#"Location Latitide : %f", coordinate2.latitude);
//NSLog(#"Location Longitude : %f", coordinate2.longitude);
pointsCoordinate[index] = CLLocationCoordinate2DMake(coordinate2.latitude, coordinate2.longitude);
}
routeLine = [MKPolyline polylineWithCoordinates:pointsCoordinate count:nuberOfStesps];
// free(pointsCoordinate);
routeLine.title = #"New points";
[self.mapView addOverlay:routeLine];
//
MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if (error) {
NSLog(#"There was an error getting your directions");
return;
}else {
[self showRoute:response];
}
}];
}
- (void) showRoute:(MKDirectionsResponse * ) response {
_currentRoute = [response.routes firstObject];
[self.mapView setVisibleMapRect:_currentRoute.polyline.boundingMapRect animated:NO];
[self.mapView removeOverlays:self.mapView.overlays];
[self.mapView addOverlay:_currentRoute.polyline level:MKOverlayLevelAboveRoads];
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
if ([overlay isKindOfClass:[MKPolyline class]]) {
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
[renderer setStrokeColor:[UIColor redColor]];
[renderer setLineWidth:4.0];
[renderer setLineDashPattern:#[#2, #5]];
[renderer setStrokeColor:[UIColor redColor]];
return renderer;
}
return nil;
}
I followed this thread iOS Maps draw route (line) between several points (geopoints)
But it did not work for me. What am I doing wrong?
I want to show two location's distance in mapkit, I have tried my process its not showing the distance between the location. tried below codes its not working, can any one help me in coding.
MKMapView * mapView = [[MKMapView alloc]initWithFrame:CGRectMake(0, 294, 320, 122)];
mapView.showsUserLocation = YES;
mapView.delegate = self;
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
MKPlacemark *placemark1 = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(9.9176458, 78.1228237) addressDictionary:nil];
[request setSource:[[MKMapItem alloc] initWithPlacemark:placemark1]];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(13.0475604, 80.2089535) addressDictionary:nil];
request.destination = [[MKMapItem alloc] initWithPlacemark:placemark];
// [request setDestination:myMapItem];
[request setTransportType:MKDirectionsTransportTypeAutomobile]; // This can be limited to automobile and walking directions.
[request setRequestsAlternateRoutes:YES]; // Gives you several route options.
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if (!error) {
for (MKRoute *route in [response routes]) {
[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.
}
}
}];
[self.view addSubview:mapView];
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay
{
MKPolylineRenderer *renderer =
[[MKPolylineRenderer alloc] initWithOverlay:overlay];
renderer.strokeColor = [UIColor blueColor];
renderer.lineWidth = 5.0;
return renderer;
}
Please any help me .
If you check error in the -calculateDirectionsWithCompletionHandler:
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if (!error) {
for (MKRoute *route in [response routes]) {
[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.
}
}
else {
NSLog(#"%#", error);
}
}];
You will probably see
Error Domain=MKErrorDomain Code=5 "Directions Not Available" UserInfo=0x7fefe3bb5660 {NSLocalizedFailureReason=A route to the nearest road cannot be determined., MKErrorGEOError=-403, MKDirectionsErrorCode=6, NSLocalizedDescription=Directions Not Available}
Which means that it is not possible to calculate directions from given location.
Here is my code; I use CLLocationManager Delegate to compute distance between two location and MKMapView Delegate. here is my code, it may help you.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)location{
float distance = 0.0f;
NSMutableArray *locationArray = [[NSMutableArray alloc] init];
for (CLLocation *newLocation in location) {
[locationArray addObject:newLocation];
}
for (int i = 0 ; i < locationArray.count; i++) {
CLLocation *newLocation = [locationArray objectAtIndex:i];
distance += [newLocation distanceFromLocation:[locationArray objectAtIndex:i+1]];
}
NSLog(#"%f",distance);
CLLocationCoordinate2D cordinates [locationsArray.count];
MKPolyline *userLocationsPolyLine = [MKPolyline polylineWithCoordinates:cordinates count:locationsArray.count];
[userMapView setDelegate:self];
[userMapView addOverlay:userLocationsPolyLine];
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
if ([overlay isKindOfClass:[MKPolyline class]]){
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
renderer.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
renderer.lineWidth = 3;
return renderer;
}
return nil;
}
I am working on one app, I need to show route directions between two coordinates. I have used MKDirections and have passed two coordinates as source and destination, however on mapView its not showing any route or drawing any polyline. Below is my code. In MKDirections its always showing nil. Please let me know what I am doing wrong.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.activityIndicator.hidden = YES;
self.routeDetailsButton.hidden = YES;
self.routeDetailsButton.enabled = NO;
self.mapView.delegate = self;
self.mapView.showsUserLocation = YES;
self.navigationItem.title = #"RouteMaster";
}
#pragma mark - MapKit delegate methods
- (void)mapView:(MKMapView *)aMapView didUpdateUserLocation:(MKUserLocation *)userLocation {
CLLocationCoordinate2D loc = [userLocation.location coordinate];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 1000.0f, 1000.0f);
[self.mapView setRegion:region animated:YES];
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (IBAction)handleRoutePressed:(id)sender {
// We're working
CLLocationCoordinate2D sourceCoords = CLLocationCoordinate2DMake(28.6100, 77.2300);
MKPlacemark *sourcePlacemark = [[MKPlacemark alloc] initWithCoordinate:sourceCoords addressDictionary:nil];
MKMapItem *srcMapItem = [[MKMapItem alloc]initWithPlacemark:sourcePlacemark];
CLLocationCoordinate2D destinationCoords = CLLocationCoordinate2DMake(18.9750, 72.8258);
MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:destinationCoords addressDictionary:nil];
MKMapItem *distMapItem = [[MKMapItem alloc]initWithPlacemark:destinationPlacemark];
MKDirectionsRequest *request = [[MKDirectionsRequest alloc]init];
[request setSource:srcMapItem];
[request setDestination:distMapItem];
MKDirections *direction = [[MKDirections alloc]initWithRequest:request];
[direction calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if (error)
NSLog(#"Error %#", error.description);
else
NSLog(#"response = %#",response);
NSArray *arrRoutes = [response routes];
[arrRoutes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
MKRoute *rout = obj;
MKPolyline *line = [rout polyline];
[self.mapView addOverlay:line];
NSLog(#"Rout Name : %#",rout.name);
NSLog(#"Total Distance (in Meters) :%f",rout.distance);
NSArray *steps = [rout steps];
NSLog(#"Total Steps : %lu",(unsigned long)[steps count]);
[steps enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(#"Rout Instruction : %#",[obj instructions]);
NSLog(#"Rout Distance : %f",[obj distance]);
}];
}];
}];
}
#pragma mark - Utility Methods
- (void)plotRouteOnMap:(MKRoute *)route
{
if(_routeOverlay) {
[self.mapView removeOverlay:_routeOverlay];
}
// Update the ivar
_routeOverlay = route.polyline;
// Add it to the map
[self.mapView addOverlay:_routeOverlay];
}
#pragma mark - MKMapViewDelegate methods
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
renderer.strokeColor = [UIColor redColor];
renderer.lineWidth = 4.0;
return renderer;
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay {
if ([overlay isKindOfClass:[MKPolyline class]]) {
MKPolylineView* aView = [[MKPolylineView alloc]initWithPolyline:(MKPolyline*)overlay] ;
aView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.5];
aView.lineWidth = 10;
return aView;
}
return nil;
}
Mostly this error occur if [_mapView setRegion:region] area and polyline route path are not on same region(both should need to display on same screen).
In my case I was searching for USA route path while my region was India. So it wont call to -(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay; function.
add this method
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
MKPolylineRenderer * routeLineRenderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
routeLineRenderer.strokeColor = [UIColor blueColor];
routeLineRenderer.lineWidth = 4;
return routeLineRenderer;
}
When I initialize the map, it shows both my location and the destination (forward geocoded from a string) but it does not draw directions between them.
Here is my code :
#import "EventDetailMapViewController.h"
#interface EventDetailMapViewController ()
#property (nonatomic,strong) MKMapItem *destination;
#end
#implementation EventDetailMapViewController
CLPlacemark *thePlacemark;
MKRoute *routeDetails;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_mapView.showsUserLocation = YES;
self.navigationController.toolbarHidden = NO;
_mapView.delegate = self;
[self getRoute];
}
- (void)addAnnotation:(CLPlacemark *)placemark {
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = CLLocationCoordinate2DMake(placemark.location.coordinate.latitude, placemark.location.coordinate.longitude);
point.title = [placemark.addressDictionary objectForKey:#"Street"];
point.subtitle = [placemark.addressDictionary objectForKey:#"City"];
[self.mapView addAnnotation:point];
}
-(void)showRoute:(MKDirectionsResponse *)response{
for (MKRoute *route in response.routes)
{
[_mapView
addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
for (MKRouteStep *step in route.steps){
NSLog(#"%#",step.instructions);
}
}
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
// If it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// Handle any custom annotations.
if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
// Try to dequeue an existing pin view first.
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:#"CustomPinAnnotationView"];
if (!pinView)
{
// If an existing pin view was not available, create one.
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomPinAnnotationView"];
pinView.canShowCallout = YES;
} else {
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
-(void)getRoute {
[self getLocationFromString];
MKDirectionsRequest *directionsRequest = [[MKDirectionsRequest alloc] init];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:thePlacemark];
[directionsRequest setSource:[MKMapItem mapItemForCurrentLocation]];
[directionsRequest setDestination:[[MKMapItem alloc] initWithPlacemark:placemark]];
directionsRequest.transportType = MKDirectionsTransportTypeAutomobile;
MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if (error) {
NSLog(#"Error %#", error.description);
} else {
routeDetails = response.routes.lastObject;
[self.mapView addOverlay:routeDetails.polyline];
}
}];
}
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
MKPolylineRenderer * routeLineRenderer = [[MKPolylineRenderer alloc] initWithPolyline:routeDetails.polyline];
routeLineRenderer.strokeColor = [UIColor redColor];
routeLineRenderer.lineWidth = 5;
return routeLineRenderer;
}
- (IBAction)changeMapType:(id)sender {
if (_mapView.mapType == MKMapTypeStandard)
_mapView.mapType = MKMapTypeSatellite;
else
_mapView.mapType = MKMapTypeStandard;
}
-(void)getLocationFromString{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:self.agendaEntry.address completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
NSLog(#"%#", error);
} else {
thePlacemark = [placemarks lastObject];
float spanX = 1.00725;
float spanY = 1.00725;
MKCoordinateRegion region;
region.center.latitude = thePlacemark.location.coordinate.latitude;
region.center.longitude = thePlacemark.location.coordinate.longitude;
region.span = MKCoordinateSpanMake(spanX, spanY);
[self.mapView setRegion:region animated:YES];
[self addAnnotation:thePlacemark];
}
}];
}
#end
I'm relatively new to this so some of this is probably wrong. What I want is when I push a button (in another view) the "agendaEntry" gets passed on the segue. It contains a string with an address, this address gets forward-geocoded and the map displays directions/routes from the user's location to the address in that string.
I don't know how to make it show driving/walking directions or to make it show multiple routes. But for starters, it would be great if it would work.
The reason it doesn't draw directions is because the directions request is being made before the destination placemark (thePlacemark) is actually set by the geocodeAddressString completion handler block.
Note what the documentation says about geocodeAddressString:completionHandler::
This method submits the specified location data to the geocoding server asynchronously and returns.
So even though getLocationFromString (which calls geocodeAddressString) is called before the directions request, execution returns and continues in getRoute immediately after the geocodeAddressString is initiated (but not completed).
Therefore, thePlacemark is still nil when getRoute sets up directionsRequest and you're probably getting an error logged such as "directions not available".
To account for this, you can move the call to the directions-request-set-up code to inside the geocodeAddressString completion handler block (after the add-annotation code).
There are three things to change for this:
In viewDidLoad, do [self getLocationFromString]; instead of [self getRoute];.
In getRoute, remove the call to getLocationFromString.
In getLocationFromString, in the completion handler block, after [self addAnnotation:thePlacemark];, do [self getRoute];.
Regarding showing multiple routes, first you'll need to actually request alternate routes (default is NO):
directionsRequest.requestsAlternateRoutes = YES;
The other part of the problem you may have experienced is due to this line in rendererForOverlay:
MKPolylineRenderer * routeLineRenderer = [[MKPolylineRenderer alloc]
initWithPolyline:routeDetails.polyline];
It's creating a polyline renderer using an external instance variable instead of the overlay parameter provided to the delegate method. This basically means the delegate method will only work for that one specific overlay (routeDetails.polyline) and since there's no control over when exactly the delegate method will be called by the map view, you can't reliably set routeDetails.polyline from outside the delegate method to be sure it points to the right overlay. Each alternate route is a separate polyline and the map view will make separate calls to rendererForOverlay for each one.
Instead, create the polyline renderer using the overlay parameter (and first check if overlay is an MKPolyline):
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
if ([overlay isKindOfClass:[MKPolyline class]])
{
MKPolylineRenderer * routeLineRenderer =
[[MKPolylineRenderer alloc] initWithPolyline:overlay];
routeLineRenderer.strokeColor = [UIColor redColor];
routeLineRenderer.lineWidth = 5;
return routeLineRenderer;
}
return nil;
}
Then in getRoute, instead of this:
routeDetails = response.routes.lastObject;
[self.mapView addOverlay:routeDetails.polyline];
call the showRoute method you already have which adds all the routes:
[self showRoute:response];
I know google maps are known to be the best maps out there, but i dont want to have to download a bunch of extra libraries and all that. I'd prefer to do something quick and simple to get a quick route from point A to B and be done with it. Is there a way to do this with built in functions/libraries? Can somebody point me in the right direction?
EDIT
I'm not trying to get turn by turn directions or anything in my case, i just want to draw a line from start to finish. maybe give options about which routes to take. Is there a way to do it or no?
In iOS 7, you can get and display directions using MKDirectionsRequest.
Here's some sample code for displaying directions from the current location to another map item:
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
[request setSource:[MKMapItem mapItemForCurrentLocation]];
[request setDestination:myMapItem];
[request setTransportType:MKDirectionsTransportTypeAny]; // This can be limited to automobile and walking directions.
[request setRequestsAlternateRoutes:YES]; // Gives you several route options.
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if (!error) {
for (MKRoute *route in [response routes]) {
[myMapView 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.
}
}
}];
If you're new to iOS 7, you'll need to implement the mapView:rendererForOverlay: method for any overlay to appear. Something like:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKPolyline class]]) {
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
[renderer setStrokeColor:[UIColor blueColor]];
[renderer setLineWidth:5.0];
return renderer;
}
return nil;
}
Swift version
let request = MKDirectionsRequest();
request.source = MKMapItem.mapItemForCurrentLocation();
let locationPlacemark = MKPlacemark(coordinate: CLLocationCoordinate2DMake(13.724362, 100.515342), addressDictionary: nil);
request.destination = MKMapItem(placemark: locationPlacemark);
request.transportType = MKDirectionsTransportType.Any;
request.requestsAlternateRoutes = true;
let directions = MKDirections(request: request);
directions.calculateDirectionsWithCompletionHandler ({
(response: MKDirectionsResponse?, error: NSError?) in
print(response?.description)
print(error?.description)
guard let response = response else {
//handle the error here
return;
}
self.myRoute = response.routes[0]
self.mkMapView.addOverlay(self.myRoute!.polyline)
});
and its delegate
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
let myLineRenderer = MKPolylineRenderer(polyline: (self.myRoute?.polyline)!)
myLineRenderer.strokeColor = UIColor.redColor()
myLineRenderer.lineWidth = 3
return myLineRenderer
}
Another possibility is to send the address to the Apple Maps app. I just saw this done in a professional setting and that was the chosen method.
if you want show a Alert Dialog when you tapped in a Pin make this:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
[mapView deselectAnnotation:view.annotation animated:YES];
if ([view.annotation isKindOfClass:[PinOfProject class]])
{
CLLocationCoordinate2D coordinate = [view.annotation coordinate];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:coordinate addressDictionary:nil];
MKMapItem *mapitem = [[MKMapItem alloc] initWithPlacemark:placemark];
self.mapItem = mapitem;
CGPoint pin = [mapView convertCoordinate:view.annotation.coordinate toPointToView:self.view];
CGRect rec = CGRectMake(pin.x-13, pin.y-14,view.frame.size.width,view.frame.size.height);
[self showAlertInformationForTrash:rec];
}
}
-(void)showAlertInformationForTrash:(CGRect)rec{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Show Route?" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:#"Route", #"Cancel", nil];
actionSheet.tag = 1;
[actionSheet showFromRect:rec inView:self.view animated:YES];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
[self showRouteToAnnotation];
}
}
-(void)showRouteToAnnotation{
MKMapItem *myMapItem = self.mapItem;
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
[request setSource:[MKMapItem mapItemForCurrentLocation]];
[request setDestination:myMapItem];
[request setTransportType:MKDirectionsTransportTypeAutomobile]; // This can be limited to automobile and walking directions.
[request setRequestsAlternateRoutes:NO]; // Gives you several route options.
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.
for (int i = 0; i < route.steps.count; i++) {
MKRouteStep *step = [route.steps objectAtIndex:i];
NSString *newStep = step.instructions;
NSLog(#"%#", newStep);
}
}
}
}];
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKPolyline class]]) {
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
[renderer setStrokeColor:[UIColor blueColor]];
[renderer setLineWidth:5.0];
return renderer;
}
return nil;
}
Oh, but note that i make a property in my .h
#property (strong, nonatomic)MKMapItem *mapItem;