Greetings! In the post we’ll cover using the MKDirections class to retrieve direction related information from Apple. We’ll then use those directions to draw a route on the map. The source code can be found on GitHub
First, we need the following namespaces
using MonoTouch.MapKit; using MonoTouch.CoreLocation;
Next, we’ll add an MKMapView instance variable, and a MPMapViewDelegate.
private MKMapView _map; private MKMapViewDelegate _mapDelegate;
In the ViewController’s ViewDidLoad method we will initialize the map, the map delegate, and call a method to get directions and create a route.
public override void ViewDidLoad() { base.ViewDidLoad(); //Init Map _map = new MKMapView { MapType = MKMapType.Standard, ShowsUserLocation = true, ZoomEnabled = true, ScrollEnabled = true }; //Create new MapDelegate Instance _mapDelegate = new MapDelegate(); //Add delegate to map _map.Delegate = _mapDelegate; View = _map; //Create Directions CreateRoute(); }
The CreateRoute function is where the magic happens…
We’ll need to crate two MKPlaceMarks, one for the source and one for the destination. These are used to create two MKMapItems that are used when making the directions request.
//Create Origin and Dest Place Marks and Map Items to use for directions //Start at Xamarin SF Office var orignPlaceMark = new MKPlacemark(new CLLocationCoordinate2D(37.797530, -122.402590), null); var sourceItem = new MKMapItem(orignPlaceMark); //End at Xamarin Cambridge Office var destPlaceMark = new MKPlacemark(new CLLocationCoordinate2D(42.374172, -71.120639), null); var destItem = new MKMapItem(destPlaceMark);
Next, we’ll need to create a request for directions using MKDirectionsRequest using the the source and dest items above, and pass these to a new instance of MKDirections.
var request = new MKDirectionsRequest { Source = sourceItem, Destination = destItem, RequestsAlternateRoutes = true }; var directions = new MKDirections(request);
Next, we need to make the call to get the directions. When the directions are returned, we’ll loop through the collections of routes and add the PolyLine from each route to our map overlay collection.
directions.CalculateDirections((response, error) => { if (error != null) { Console.WriteLine(error.LocalizedDescription); } else { //Add each Polyline from route to map as overlay foreach (var route in response.Routes) { _map.AddOverlay(route.Polyline); } } });
Remember the _mapDelegate we create earlier? This is actually a class that inherits from MKMapViewDelegate. We need to override the OverlayRenderer in order to actually draw the route on the map.
class MapDelegate : MKMapViewDelegate { //Override OverLayRenderer to draw Polyline from directions public override MKOverlayRenderer OverlayRenderer(MKMapView mapView, IMKOverlay overlay) { if (overlay is MKPolyline) { var route = (MKPolyline)overlay; var renderer = new MKPolylineRenderer(route) { StrokeColor = UIColor.Blue }; return renderer; } return null; } } }
That’s it! When we put it all together we end up with the map below.
Thanks. Its a nice tutorial.
I am using MKDirectionsRequest in my app to draw route between two points. But i am getting error as a response. Error message : “Directions not available”. I am trying to find route between pune to mumbai.
Do i have to do some initial settings before using MKDirections request ?
Can you please help me regarding the same.
Thanks in advance.
Thanks for the reply. I tried getting directions using Apple’s map program and received the same error. It looks like Apple hasn’t added support for that route just yet. You might try contacting Apple to get an ETA on when they plan to add this in.
Regards,
Blake
David thanks a lot for the reply.
So its like they haven’t added route support for all locations. Can you please tell me which locations are route supported?
How can i support turn by turn navigation in ios7 app?
Himani, althought this post is from last year, it looks like Apple Maps hasn’t added support for India still…
It looks like your best bet is to use google maps.
The easiest way for you to implement true turn-by-turn directions is to launch google maps using an Url scheme.
If displaying the directions within your app is a requirement, I could post an example on retrieving directions/displaying route using google maps directions API, but it would be up to you to figure out the turn-by-turn piece.
-Blake
I am working on Apple map component so i dont want to use Google Map API to display route between two locations.
I have gone through the MKDirections Class documentation ,as per my understanding it is possible to show route and turn by turn navigation with MapKit Framework in ios7.
As it is newly released not much information is available in internet.
Can you please help me out regarding the same.
Can you please help me out regarding the same. If
Could you please show me where in the MKDirections Class documentation it states that Turn-by-turn navigation is available? I’m fairly familiar with the class myself, but only found where you can get directions, not fully functioning turn by turn navigation. As I stated earlier, the directions service is not available for India, so if you’re looking to get your app going soon, google maps appears to be your only option. I apologize that I can’t offer much more help than this.
-Blake
steps property of MKRoute Class would do for turn by turn navigation. Please correct me if i have misunderstood.
Thanks for your time and help.
I apologize. I misunderstood. I thought you were looking for some type of mechanism that handle all of this for you, but if you’re going to implement this yourself, you’re on the right track! Keep checking http://www.apple.com/ios/feature-availability/#maps-directions to see if directions are available for your country. Code on!
-Blake
Hi Blake !
Thanks for the link you shared in your last post. It really helped me.
Looking into the other new features of ios7,i am facing difficulty in implementing 3D view for my map.
I have set the altitude and pitch but still i am unable to implement 3D view.
If you are familiar with this concept can you please help me out.
Himani, you’re very welcome! Larry O’ Brien from Xamarin made a short Blog Post about 3D Map views . This should get you up and going. Please let me know if you would like a more detailed example, and I’ll be glad to post one for you.
-Blake
P.S. It looks like 3D Buildings in Navigation is very limited at this time
http://www.apple.com/ios/feature-availability/#maps-3d-buildings-in-navigation
Blake, Can you please post a detailed example for 3D views.
Sure! Is there something specific that you seem to be having trouble with?
Hi Blake 🙂 !
I followed the Larry O’ Brien post for 3D view, but it was not working. I don’t know what is the problem. I can’t see the 3D buildings as it was shown in the screenshot ( Larry’s Post ).
What are the coordinates you are testing with?
Same coordinates which was given in the Larry O’ Brien post.
Himani, Sorry for taking so long to get back to you. I was out of town for the weekend. I tested the code below, and it appears to dispaly 3D maps, however it only works on an actual device!
public class MyViewController : UIViewController
{
private MKMapView _mapView;
public MyViewController()
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
_mapView = new MKMapView(View.Bounds);
var target = new CLLocationCoordinate2D(37.7952, -122.4028);
var viewPoint = new CLLocationCoordinate2D(37.8009, -122.4100);
//Enable 3D buildings
_mapView.ShowsBuildings = true;
_mapView.PitchEnabled = true;
var camera = MKMapCamera.CameraLookingAtCenterCoordinate(target, viewPoint, 500);
_mapView.Camera = camera;
View = _mapView;
}
}
-Blake
Pingback: Programmatic Apple Maps – Can and Can’ts » Xamarin Developments | Xamarin Developments
Pingback: Programmatic Apple Maps – Cans and Cants » Xamarin Developments | Xamarin Developments
Hi really it wondering.. but when I use your sample I am getting this error
Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[MKDirectionsRequest setRequestsAlternateRoutes:]: unrecognized selector sent to instance 0x16935880
Pleas you help me to solve this.
Venkatesh, first, I would make sure you are targeting iOS 7. What coordinates are you using for the directions?
Blake
Sorry , My target deployment is iOS 6. And I used the same coordinates which you used in you sample.
No problem. The MKDirections API is new in iOS 7. Switching target SDKs should fix your problem.
Blake
Ok Thanks . I have another doubt Davidsonblake. If I use iOS7 in my app and if my user device is lower version mean, how can I handle ?
You’ll want to do a check of the users platform, and handle it appropriately. Depending on your app you might notify the user that the feature is only available for ios7 and later.
Yeah OK Thanks David..
That’s completely up to you and your client to decide. Obviously you don’t want to try and execute iOS 7 only APIs on an iOS 6 device. As I suggested earlier you might display an alert. If the feature is available for both operating systems, but handled a bit differently you can perform your (see screen capture), you can perform your check and execute the correct code accordingly.
Blake
Yes. You are correct. Thanks David.
how to remove the route to create a new route ?
You’ll need to keep track of the overlays in an array. Then you call _map.RemoveOverlays(overlays); to remove them.
-Blake
my problem is solve it!!
thanks for help me !!
have a nice day!!!
I use Obj-C but your post vvvery helpful!!
Thanks a lot.