August 30, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

How to Build a Navigation App for Windows Phone 8

  • February 6, 2013
  • By Vipul Patel
  • Send Email »
  • More Articles »

Introduction

Microsoft introduced the Windows Phone 8 platform in October. Since the announcement, the new Maps have received rave reviews. In this article, we will learn how to build a simple navigation map, which provides directions from the current location.

Navigation Basics

To get directions on Windows Phone, we need to call APIs that can take a varying amount of time to respond. Hence, such calls need to be asynchronous in nature; in our walkthrough, we will make sure we this into consideration.

In this walkthrough, we will build an application, which gets the current location of the device, and ask for directions to the world famous Pike Place Market (85 Pike Street, Seattle, WA).

Hands-On

Create a new Windows Phone app project in Visual Studio 2012 titled WindowsPhoneNavigationDemo.

New Windows Phone App Project
New Windows Phone App Project

When prompted, select the Windows Phone OS 8.0 as the target platform.

Select the Windows Phone Platform
Select the Windows Phone Platform

To ensure that the map and navigation features work, we need to declare the Map and Location capabilities in the WMAppManifest.xml file. Failure to declare these capabilities will result in errors at runtime.

Open WMAppManifest.xml from the Solution Explorer by double-clicking the file name. Select the appropriate capabilities and save the file before closing it.

Select the appropriate capabilities
Select the appropriate capabilities

Next, on the MainPage, we will add the following controls:.

1. A Map Control, which will show the map.

2. 1 textbox to capture the destination address.

3. 1 button control, which will be titled “Get Directions”. When we click the button, the application is supposed to get the directions from the device’s current location.

4. 1 TextBoxControl, which will contain the step-by-step directions to the destination. Initially, this will not be populated.

Here is what our controls look like.

Controls
Controls

And here is the XAML for our controls.

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 
            <maps:Map x:Name="myMap" Margin="0,0,10,0" VerticalAlignment="Top" Height="335"  ZoomLevel="12"  >
               
            </maps:Map>
            <TextBox x:Name="textBoxToAddress" HorizontalAlignment="Left" Height="72" Margin="-10,355,0,0" TextWrapping="Wrap" Text="85 Pike Street, Seattle, WA" VerticalAlignment="Top" Width="286"/>
            <TextBox x:Name="textBoxDirections" HorizontalAlignment="Left" Height="170" Margin="0,427,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="456" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Text="85 Pike Street, Seattle, WA" FontSize="11"/>
            <Button x:Name="buttonDrivingDirections" Content="Get Directions" HorizontalAlignment="Left" Margin="261,357,0,0" VerticalAlignment="Top" Width="193"/>
 
        </Grid>
 

We can see that in my implementation, the instance of the map control is called “myMap”, the textbox containing the endpoint is called “textBoxToAddress” and it has the default text of “85 Pike Street, Seattle, WA”, which is the street address of Pike Place Market. We can also note that our button is called “buttonDrivingDirections”.

Next, in our MainPage.xaml.cs file, we will include a few namespaces.

//MainPage.xaml.cs


using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Navigation;

using Microsoft.Phone.Controls;

using Microsoft.Phone.Shell;

using WindowsPhoneNavigationDemo.Resources;

using Microsoft.Phone.Maps.Services;

using System.Device.Location;

using Windows.Devices.Geolocation;

using Microsoft.Phone.Maps.Controls;

We will then add a few variables, which we need to build out the navigation application.

namespace WindowsPhoneNavigationDemo

{

    public partial class MainPage : PhoneApplicationPage

    {

        List<GeoCoordinate> myRouteCoordinates = new List<GeoCoordinate>();

        RouteQuery myRouteQuery;

        GeocodeQuery mygeocodeQuery;

        Geolocator MyGeolocator;

        Geoposition MyGeoPosition;

 

Next we will implement a function, which retrieves the current location of the device.

Since getting a location is an asynchronous operation, this method will be declared as an “async” method.

private async void GetCurrentLocation()

        {

            MyGeolocator = new Geolocator();

            MyGeolocator.DesiredAccuracyInMeters = 20;

            MyGeoPosition = await MyGeolocator.GetGeopositionAsync(TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(10));

            myRouteCoordinates.Add(new GeoCoordinate(MyGeoPosition.Coordinate.Latitude, MyGeoPosition.Coordinate.Longitude));

            myMap.Center = new GeoCoordinate(MyGeoPosition.Coordinate.Latitude, MyGeoPosition.Coordinate.Longitude);

 

        }

In the above method, we instantiate a new instance of the GeoLocator and call the GetGeoPositionAsync method to get the GeoPosition.

Now, we will make a call to this method in the constructor of the page, so that as soon as the application comes up, the location of the device is retrieved.

public MainPage()

        {

            InitializeComponent();

            

            this.GetCurrentLocation();

            

            // Sample code to localize the ApplicationBar

            //BuildLocalizedApplicationBar();

        }

Next, we implement the click event on the buttonDrivingDirections. In the implementation, we will create a new GeocodeQuery and pass in the destination address. Note that the query operation is asynchronous and hence we have to define an event handler, which will be called when the query is completed.

private void buttonDrivingDirections_Click(object sender, RoutedEventArgs e)

        {

 

            mygeocodeQuery = new GeocodeQuery();

            mygeocodeQuery.GeoCoordinate = new GeoCoordinate(MyGeoPosition.Coordinate.Latitude, MyGeoPosition.Coordinate.Longitude);

            mygeocodeQuery.SearchTerm = textBoxToAddress.Text;

            mygeocodeQuery.QueryCompleted += mygeocodeQuery_QueryCompleted;

            mygeocodeQuery.QueryAsync();

        }

Next, we will implement the event handler, which is called when the GeoCode Query is completed.

In this event handler we will create a RouteQuery object, which is what is used to compose a route to the destination when we call the QueryAsync() method.

        void mygeocodeQuery_QueryCompleted(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)

        {

            if (e.Error == null)

            {

                myRouteQuery = new RouteQuery();

                myRouteCoordinates.Add(e.Result[0].GeoCoordinate);

                myRouteQuery.Waypoints = myRouteCoordinates;

                myRouteQuery.QueryCompleted += myRouteQuery_QueryCompleted;

                myRouteQuery.QueryAsync();

                mygeocodeQuery.Dispose();

            }

        }

Once again, the Route queries are async, so we need to implement an event handler when the query is completed and process the QueryCompletedEventArgs object.

        void myRouteQuery_QueryCompleted(object sender, QueryCompletedEventArgs<Route> e)

        {

            if (e.Error == null)

            {

                Route MyRoute = e.Result;

                MapRoute MyMapRoute = new MapRoute(MyRoute);

                myMap.AddRoute(MyMapRoute);

                foreach (RouteLeg leg in MyRoute.Legs)

                {

                    foreach (RouteManeuver maneuver in leg.Maneuvers)

                    {

                        textBoxDirections.Text += maneuver.InstructionText + Environment.NewLine;

                    }

                }

                myRouteQuery.Dispose();

            }

        }

In the above implementation, once we have the information for each route leg, we add it to the textboxDirections, which shows to the user the complete detailed driving instructions.

When we run the application (you can run this in the emulator also), the start screen will look like the screenshot below.

Start Screen
Start Screen

The default destination address is set to 85 Pike Street, Seattle, WA. You can change the destination address if you want to.

Once you have typed the address, and click “Get Directions”, the application will return the directions in a few moments and your application will look like the screenshot below.

The application will return the directions in a few moments
The application will return the directions in a few moments

Note that if you type in another address, you will get different directions.

If you type in another address, you will get different directions
If you type in another address, you will get different directions

If you have trouble following along, you can download the sample code of this walkthrough from here.

Summary

In this article, we learned how to build a navigation app for Windows Phone 8 and use the navigation APIs to provide driving directions. I hope you have found this information useful.

WindowsPhoneNavigationDemo

About the author

Vipul Patel is a Program Manager currently working at Amazon Corporation. He has formerly worked at Microsoft in the Lync team and in the .NET team (in the Base Class libraries and the Debugging and Profiling team). He can be reached at vipul.patel@hotmail.com


Tags: navigation, maps, Windows Phone 8, Maps API




Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel