How to start a turn by turn navigation to a destination from your Windows Phone app

Sometime it is useful to insert in your WP8 app the capability to start a navigation to a destination that can be derived, for example, from the address of a someone/some place or from the geocoordinate of a point in a map.

There are several ways to do that and in this post I’ll try to describe the following ones:

  1. Coding the navigation functions inside your app (RouteQuery class + GeocodeQuery class) .
  2. Using the MapsDirectionsTask  class.
  3. Launching a navigator app with a Launcher that uses a specific navigation Uri.

NOTE – You can find here a PowerPoint presentation related to this post, where I put also a comprehensive introduction to new Geolocation, Maps namespaces and Tasks for Maps.

========================================================
1) Coding the navigation functions inside your app.

This can be done mainly using  the GeocodeQuery class (to find a possible list of Geocoordinate  from a descriptive search term like an address, a building name, or any other phrase indicating a place on Earth), the RouteQuery class (to get all the route points to reach the destination [according to the required mode of travel and optimizations]) and then the SpeechSynthesizer class to have a text-to-speech reading of each Route turning point [the list of maneuvers associated with each route RouteLeg of every Route.Legs, that is the property  of the legs associated with the route).
All the three mentioned classes are async ones, in order not to stop the user interaction with the UI; in particular, the first two comes from the new Microsoft.Phone.Maps.Services namespace (where there is also the ReverseGeocodeQuery class [given a location, what do I find there?]).

A code example that implements this kind of solution can be found in the Nokia Developer site among the great numer of examples on WP8, in general, and in particular those related to the new WP8 Maps (Zip archive),  based on Nokia technologies. In that site you can find also some Explore projects where there is one related to Map Explorer.
Here you can download the specific project called Map with directions in Windows Phone 8 and you can find also an explanation of the relevant part of its code. If you see the code, you will notice that most of the work needed to have a basic navigator is already done, even thought the text-to-speech of each instruction should be based on the actual position of the user [using the Geolocator class and in particular its GetGeopositionAsync(TimeSpan, TimeSpan) method and a listener to its PositionChanged event].

In the following you can see some screenshots of the Map with directions in Windows Phone 8 example: in particular, you can see a blu circle for the starting point, a red one for the end point and a green one for the actual Route turning point with the maneuver written below (it is the text read by the SpeechSynthesizer).

wp_ss_20130407_0001    wp_ss_20130407_0002

However if you run that example, you will notice that the user experience is not comparable with that provided with commercial navigators and the synthesized voice, that can be acceptable  for an input request, is not appropriate for giving driving instructions.

========================================================
2) Using the MapsDirectionsTask  class.

MapsDirectionsTask is one of the four new Tasks related to Maps in the Microsoft.Phone.Tasks namespace together with:

MapsTask class [launch the Maps application centered at the location specified with the Center property or at the user’s current location if omitted. If SearchTerm is set, locations matching the search term are tagged on the map]

MapDownloaderTask class [allows an application to launch the Maps settings application. Use this to allow users to download map data for offline use]

MapUpdaterTask class [allows an application to launch the Maps settings application. Use this to allow users to update offline map data they have previously downloaded])

In particular, in our case is useful the MapsDirectionsTask  class that is very powerful and allows to launch the Maps application, specifying a starting location or an ending location, or both, for which driving directions are displayed and possibly launch an external navigator app.
Very often the starting position is the user’s current position: in that case the Start property cannot be set because user’s current position is its default value (therefore there is no need to use the Geolocator class and its GetGeopositionAsync(TimeSpan, TimeSpan) method to find out user’s current position, because that Task already does everything for us).

Among the Nokia Developer examples, there is LaunchDirectionsTask (inside a Zip archive) that shows the use of this class. In the following you can see the relevant code that allows to add all the mentioned functionalities, in the case that you have an originMarker MapOverlay as a start point and a destinationMarker one as a destination point:

<br />MapsDirectionsTask mapsDirectionsTask = new MapsDirectionsTask();<br />mapsDirectionsTask.Start = new LabeledMapLocation(OriginTitle.Text, originMarker.GeoCoordinate);<br />mapsDirectionsTask.End = new LabeledMapLocation(DestinationTitle.Text, destinationMarker.GeoCoordinate);<br />mapsDirectionsTask.Show();<br />

In the case you would like do go from your position to a specific geoCoordinate, you only need to write the following code [because (as I already said) the default value of the starting position is the phone’s current position]:

<br />MapsDirectionsTask mapsDirectionsTask = new MapsDirectionsTask();<br />mapsDirectionsTask.End = new LabeledMapLocation("Home", new GeoCoordinate(45.098614934831858, 7.6977774314582348));<br />mapsDirectionsTask.Show();<br />

Moreover, if you have to go to a location that you want to find by name, you can do as follows:

<br />MapsDirectionsTask mapsDirectionsTask = new MapsDirectionsTask();<br />mapsDirectionsTask.End = new LabeledMapLocation("Space Needle", null);<br />mapsDirectionsTask.Show();<br />

Next screenshots show the UI that will be available in your app, writing only that few lines of code! Note that the first time you use the application, there is already the request of user’s consent that must be provided to have the app published in the Store.

Request of user's consent

Request of user’s consent

Getting directions

Getting directions

Directions found (emulator)

Directions found (emulator)

Set directions for pedestrian

Set directions for pedestrian

After click on the map

After click on the map

Toolbar &amp; menu (1)

Toolbar & menu (1)

Toolbar & menu (2)

Toolbar & menu (2)

If you click on “directions” toolbar button (“indicazioni stradali” in italian), you go back to the “Get direction” page, to allow a insert a new destination, and not to a navigation app.
But if you use a real phone and not the emulator, you can see, in the “Direction found” page, a “by car“/”by foot” toolbar button (“In macchina“/”a piedi” in italian) [depending if it was chosen the car or the pedestrian view], that allows the user to launch, just from here, an external navigation app toward the chosen destination.
I really don’t know why “by car” toolbar button is not shown when I use the emulator, perhaps because no navigation apps are installed in it, while in my phone there are two apps that offer that kind of service (remind that Store apps can’t be installed  in the emulator).

The following screenshots shows both the case of car and pedestian selection and the related list of the installed apps that expose the specific protocol.

wp_ss_20130407_0005    wp_ss_20130407_0004 

wp_ss_20130330_0005

If you click on the toolbar button providing navigation feature, all the enable apps installed on your phone are listed allowing you to choose the desired one.
Note that Windows Phone logic is different from the Windows 8 one, where there is the concept of a default app associated to each service.

wp_ss_20130405_0003 wp_ss_20130405_0004 wp_ss_20130405_0005

When the external navigator program is closed, your app comes again in foreground.
Note that, if is your app is registered to run in background (because most if not all the navigator programs do the same and WP8 allows only one app to run in background), the background functions of your app stop until the navigator is closed and your app is again in foreground: once again, when it will go in background (for example because you answer a phone call or you use the browser to search something) the background execution will be activated.

Navigation functions provided by the MapsDirectionsTask are in some way similar to the ones provided by the embedded Bing search  (see next screenshots). In the following you can see some screenshot of the procedure that can be used to start a navigation app from a browser search.
When you go to the local results and click on the desired location, an Info page appears where you can start an external navigator with “drive -use an app” (“percorri – usa un’app” in italian).

However the logic of launching a navigation app from the MapsDirectionTask is different from the one used within the Bing search.
In Bing Search “directions” toolbar button (“indicazioni stradali” in italian) starts the navigation app, while  using MapsDirectionTask the toolbar button of the same name “directions” let the user go back to a previous page for a new input of start – end points, while the launch of a navigator app is done by a different named toolbar button (“by car”) in that previous page.
Moreover in Bing Search, if there is not any app installed able to start a navigation (case you can test using the emulator) clicking “directions” toolbar button let go to the store, showing all the appropriate apps that satisfy that requested protocol, while in the MapsDirectionTask the “byCar” toolbar button is not shown in that case, disabling any way to start a navigator app.
I think that it is not nice to give a different user experience: if you agree you can vote here.

Moreover note that in the italian version there is not the “scout” tollbar button because this service is not (yet) available in my country 😦

wp_ss_20130330_0001  wp_ss_20130330_0002  wp_ss_20130330_0003

after clicking on an item of the list

after clicking on an item of the list

after clicking on a pushpin (ita)

after clicking on a pushpin (ita)

after clicking on a pushpin (eng)

after clicking on a pushpin (eng)

ask for app in the store

ask for app in the store

compatible app list

compatible app list

========================================================
3) Launching a navigator app with a Launcher that uses a specific navigation Uri.

Sometime you need to start a professional navigator as soon as possible and the method described before can be useful only when probably it’s enough for the user to have the route shown as a layer on the map and only sometimes he will need to ask for a turn-by-turn navigation.

So if you want to directly lauch an other app that offer a navigation service, an app-to-app communication can be used.
In fact a protocol association allows to automatically launch an app when an other launches a special URI (where the protocol is the first part and the following allows to possibly pass data [ex. myProtocol:ShowSomething?CategoryID=123]).
Like in Windows 8, WP8 uses Launcher.LaunchFileAsync(IStorageFile) to launch a file and Laucher.LaunchUriAsync(URI) to lauch an URI. However Windows 8 has a default store app for a file type or URI, so that one is launched. On the contrary, WP8, if on the phone are installed several Store apps that can handle that particular file or protocol association, the user have to select one from a list.

If you knows the protocol name and the way the possible parameters are passed, you can directly call a specific store app. For example, Nokia Maps can be launched as follows (at least now):

<br /> private async void LaunchNokiaApi() { /*00*/<br />            //http://stackoverflow.com/questions/13387265/launch-nokia-maps-in-windows-phone-8<br />            string launchNokiaMaps = "explore-maps://v1.0/?latlon=45.098541,7.697704&amp;zoom=16";<br />            await Windows.System.Launcher.LaunchUriAsync(new Uri(launchNokiaMaps));<br />        }<br />

However, as stated here,  NOKIA said that  the “explore-maps://v1.0/…” app2app custom protocol is NOT SUPPORTED for 3rd party apps. Therefore they will be potentially breaking it soon and all apps that use it will flat out stop working. They suggest not use the before mentioned protocol in your apps and to use the new MapTasks or “ms-*” app2app custom protocols instead.
I think it’s a pitty that specific app protocols are not supported for 3rd party apps, anyway …

So, there is an MSDN sample, Navigation URI scheme sample, that shows how the use of the navigation protocol and the ms-drive-to and ms-walk-to URI schemes. It shows how you can use the navigation protocol both to write an app that requests driving or walking directions, and to write an other app that provides driving or walking directions.
Note that I had to change the destination coordinates (originally in Seattle) to make the navigator find a road to go there … without taking a airplane 🙂 !

<br />            // Test both navigation Uri schemes.<br />            private const string DRIVING_PROTOCOL = "ms-drive-to";<br />            private const string WALKING_PROTOCOL = "ms-walk-to";<br /><br />            // Use Seattle as the default destination.<br />            private const string DESTINATION_LATITUDE = "45.098614934831858";<br />            private const string DESTINATION_LONGITUDE = "7.6977774314582348";<br />            private const string DESTINATION_NAME = "Casa, TO";<br /><br /> // Single event handler for both driving and walking directions.<br />            private void GetDirections(object sender, EventArgs e) {<br />                string uriProtocol = null;<br />                string uri;<br /><br />                // Driving or walking directions?<br />                string buttonClicked = ((Button)sender).Name;<br />                switch(buttonClicked) {<br />                    case "btnGetDrivingDirections":<br />                        uriProtocol = DRIVING_PROTOCOL;<br />                        break;<br />                    case "btnGetWalkingDirections":<br />                        uriProtocol = WALKING_PROTOCOL;<br />                        break;<br />                    default:<br />                        uriProtocol = DRIVING_PROTOCOL;<br />                        break;<br />                }<br /><br />                // Assemble the Uri for the request.<br />                uri = uriProtocol + ":?" +<br />                    "destination.latitude=" + DESTINATION_LATITUDE + "&amp;" +<br />                    "destination.longitude=" + DESTINATION_LONGITUDE + "&amp;" +<br />                    "destination.name=" + DESTINATION_NAME;<br /><br />                // Display the Uri.<br />                tbShowRequestUri.Text = AppResources.UriDisplayPrefix + ":\n" + uri;<br /><br />                // Make the request.<br />                RequestDirections(uri);<br />            }<br /><br />            async void RequestDirections(string uri) {<br />                try {<br />                    // Make the request.<br />                    var success = await Windows.System.Launcher.LaunchUriAsync(new Uri(uri));<br />                    if(success) {<br />                        // Request succeeded.<br />                    } else {<br />                        // Request failed.<br />                        MessageBox.Show("Request failed");<br />                    }<br />                } catch(Exception ex) {<br />                    MessageBox.Show("Exception: " + ex.Message);<br />                }<br />            }<br />

Informazioni su Enzo Contini

Electronic engineer
Questa voce è stata pubblicata in Smartphone OS. Contrassegna il permalink.

2 risposte a How to start a turn by turn navigation to a destination from your Windows Phone app

  1. Enzo Contini ha detto:

    Today Nokia did a very useful webinar on this topic, explaining also the new Here API. Have a look to the following links:

    https://projects.developer.nokia.com/here_launchers

    "Mi piace"

Lascia un Commento/Leave a comment

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.