Map Explorer

Map Explorer is a simple Silverlight application demonstrating how to use the new Windows Phone 8 Maps API replacing the Bing Maps used in Windows Phone 7.

The application's main page contains buttons and sliders to change some properties of the map (cartographic mode, pitch, and heading). More configurable map properties can be found in the application menu. Map related functionality is demonstrated with retrieving and displaying the phone's current location on the map, searching the map for a keyword, and displaying a route and directions from the current location to a destination.

Please see also the related article Guide to the Windows Phone 8 Maps API for additional information.

Getting started

Compatibility

Map Explorer is compatible with Windows Phone 8 devices.

Windows Phone 7 is not supported, because the application is specifically demonstrating the use of the new Windows Phone 8 Map control and services replacing the Bing Maps control used in Windows Phone 7.

Using the prebuilt installation package

Download the XAP file and install it on your device by using the Application Deployment tool that comes with the Windows Phone 8 SDK.

Building the application

Download the application #toc_Downloads and open the MapExplorer.sln file in the Microsoft Visual Studio Express for Windows Phone 8. Start building and running the application by hitting F5 or selecting Start Debugging from the Debug menu.

Design

The application is to be a push-all-buttons example demonstrating the various properties of the new Windows Phone 8 Map control and map-related functionality, like searching for an address, calculating a route to a specific destination, and locating oneself on the map. Keeping all functionality of the application on one main page with the map control enables immediate visual feedback when a property is changed.

When the application is launched, a query is shown whether to allow access to and use of the user's location or not. It is recommended to allow these, since some of the application functionality depends on the user's location. Query will not be shown again after access to the location has been allowed.

Figure 1.

Upon responding to the query the main page of the application is shown. Main page is filled with a Map control with overlays for direct manipulation of the map properties cartography mode (road, aerial, hybrid, terrain), pitch (from which angle to look at the map), and heading (turning the map to change the directional heading that is pointing up). Center and zoom level properties can be changed directly by dragging and pinching the map control.

Access to the map-related functionality of Windows Phone 8 is available through buttons in the application menu bar. Search button initiates search functionality requiring input for a search term. If one or more hits are found for a given search term, the map is animated to the location of the first hit.

Route button initiates a route functionality requiring input for the destination. If one or more hits are found for a given destination, a route from current location to the destination is shown on the map. Written directions can be enabled by opening the menu and selecting "Directions On" menu item, and travel mode can then be selected between Driving and Walking.

Locate Me button initiates a search for current location. When the current location has been retrieved, the map animates to the current location. If the location usage was disallowed when the application was launched, the query is shown again. Allowing the use of the user's location initiates location search.

Additional map properties can be set in the application menu. It contains menu items for switching on and off properties like landmarks, pedestrian features, and directions. Map color mode can also be selected between light and dark.

Architecture overview

Architecture breakdown

User Interface

User interface of the application consists of MainPage and informational AboutPage , both derived from PhoneApplicationPage . MainPage contains the map and all the map related functionality of this example application.

Windows Phone Location API

Windows Phone Location APIs under the namespace Windows.Devices.Geolocation are used to determine the phone’s current location. To be able to use location services the application must have ID_CAP_LOCATION capability specified in WMAppManifest.xml file.

Maps API

New Windows Phone 8 Maps APIs offer the actual map control ( Microsoft.Phone.Maps.Controls ) and map related services ( Microsoft.Phone.Maps.Services ). To be able to use the Maps APIs the application must have ID_CAP_MAP capability specified in WMAppManifest.xml file.

Direct manipulation of Map properties

Direct manipulation of various properties of the Map control is simple as demonstrated by the following example. A slider for controlling the pitch of the map is declared in the MainPage.xaml file.

<Slider x:Name="PitchSlider" ... Minimum="0" Maximum="70" Value="0" ValueChanged="PitchValueChanged"/>

The event handler for ValueChanged event of the slider is then implemented in MainPage.xaml.cs file.

using Microsoft.Phone.Maps.Controls;
...

public partial class MainPage : PhoneApplicationPage
{
    ...

    private void PitchValueChanged(object sender, EventArgs e)
    {
        if (PitchSlider != null)
        {
            MyMap.Pitch = PitchSlider.Value;
        }
    }

    ...
}

Retrieving current location

It is straightforward to obtain device's current location asynchronously using Geolocator. The location might not be right on the spot, and this approximation can be visualised in user interface. In Map Explorer a semi-transparent circle with a radius depending on the _accuracy of the location is painted on top of the map.

using System.Device.Location;
using Windows.Devices.Geolocation;

public partial class MainPage : PhoneApplicationPage
{
    ...

    private GeoCoordinate MyCoordinate = null;
    private double _accuracy = 0.0;

    ...

    private async void GetCurrentCoordinate()
    {
        ...

        Geolocator geolocator = new Geolocator();
        geolocator.DesiredAccuracy = PositionAccuracy.High;

        try
        {
            Geoposition currentPosition = await geolocator.GetGeopositionAsync(TimeSpan.FromMinutes(1), 
                                                                               TimeSpan.FromSeconds(10));
            _accuracy = currentPosition.Coordinate.Accuracy;

            ...

            Dispatcher.BeginInvoke(() =>
            {
                MyCoordinate = new GeoCoordinate(currentPosition.Coordinate.Latitude, currentPosition.Coordinate.Longitude);

                ...
            });
        }
        catch (Exception ex)
        {
            // Couldn't get current location - location might be disabled in settings
            MessageBox.Show("Current location cannot be obtained. Check that location service is turned on in phone settings.");
        }

        ...
    }

    ...
}

Retrieving information on specific location

You can query for location information on specific geocoordinate using ReverseGeocodeQuery . In Map Explorer a ReverseGeocodeQuery is initiated when a tap is made on map marker. Geocoordinate of each marker is stored in Tag property of Polygon when a marker is created.

using using Microsoft.Phone.Maps.Services;

public partial class MainPage : PhoneApplicationPage
{
    ...

    private ReverseGeocodeQuery MyReverseGeocodeQuery = null;

    ...

    private void Marker_Click(object sender, EventArgs e)
    {
        Polygon p = (Polygon)sender;
        GeoCoordinate geoCoordinate = (GeoCoordinate)p.Tag;
        MyReverseGeocodeQuery = new ReverseGeocodeQuery();
        MyReverseGeocodeQuery.GeoCoordinate = new GeoCoordinate(geoCoordinate.Latitude, geoCoordinate.Longitude);
        MyReverseGeocodeQuery.QueryCompleted += ReverseGeocodeQuery_QueryCompleted;
        MyReverseGeocodeQuery.QueryAsync();
    }

    private void ReverseGeocodeQuery_QueryCompleted(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
    {
        if (e.Error == null)
        {
            if (e.Result.Count > 0)
            {
                MapAddress address = e.Result[0].Information.Address;
                String msgBoxText = "";

                ...

                if (address.Country.Length > 0) msgBoxText += "\n" + address.Country;
                MessageBox.Show(msgBoxText, AppResources.ApplicationTitle, MessageBoxButton.OK);
            }

            ...
        }
    }

    ...
}

Searching the map for a keyword

GeocodeQuery can be used to search location for a given search term, for example a town name or street address. The event handler GeocodeQuery_QueryCompleted is called both when searching map for keyword and when searching for route. The route specific part is explained later on. The result of the GeocodeQuery is a list of MapLocations representing the hits matching the SearchTerm of the query. Each MapLocation has a GeoCoordinate for positioning the location on the map, as well as detailed LocationInformation with name, description and MapAddress of the location.

using Microsoft.Phone.Maps.Services;

public partial class MainPage : PhoneApplicationPage
{
    ...

    private GeoCoordinate MyCoordinate = null;
    private List<GeoCoordinate> MyCoordinates = new List<GeoCoordinate>();
    private GeocodeQuery MyGeocodeQuery = null;

    private bool _isRouteSearch = false; // True when route is being searched, otherwise false

    ...

    private void SearchForTerm(String searchTerm)
    {
        ...
        MyGeocodeQuery = new GeocodeQuery();
        MyGeocodeQuery.SearchTerm = searchTerm;
        MyGeocodeQuery.GeoCoordinate = MyCoordinate == null ? new GeoCoordinate(0, 0) : MyCoordinate;
        MyGeocodeQuery.QueryCompleted += GeocodeQuery_QueryCompleted;
        MyGeocodeQuery.QueryAsync();
    }

    private void GeocodeQuery_QueryCompleted(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
    {
        ...

        if (e.Error == null)
        {
            if (e.Result.Count > 0)
            {
                if (_isRouteSearch) // Query is made to locate the destination of a route
                {
                    ...
                }
                else // Query is made to search the map for a keyword
                {
                    // Add all results to MyCoordinates for drawing the map markers.
                    for (int i = 0; i < e.Result.Count; i++)
                    {
                        MyCoordinates.Add(e.Result[i].GeoCoordinate);
                    }

                    ...
                }
            }
            else
            {
                MessageBox.Show("No match found. Narrow your search e.g. Seattle WA.");
            }
        }

        ...
    }

Displaying a route from current location to destination

RouteQuery can be used to obtain a route from one geographic point to another. Route query is launched from the GeocodeQuery_QueryCompleted event handler while searching for route. This example uses only two way points for a route, beginning and destination. The result of the RouteQuery is a Route . MapRoute is a visual representation of the Route that can be readily applied to the Map control. Route is divided to RouteLegs between two way points. Each RouteLeg has a collection of RouteManeuvers representing the actions to be taken along the path of a route leg.

using Microsoft.Phone.Maps.Services;

public partial class MainPage : PhoneApplicationPage
{
    ...

    private GeoCoordinate MyCoordinate = null;
    private List<GeoCoordinate> MyCoordinates = new List<GeoCoordinate>();
    private GeocodeQuery MyGeocodeQuery = null;

    private bool _isRouteSearch = false; // True when route is being searched, otherwise false

    ...

    private void SearchForTerm(String searchTerm)
    {
        ...
        MyGeocodeQuery = new GeocodeQuery();
        MyGeocodeQuery.SearchTerm = searchTerm;
        MyGeocodeQuery.GeoCoordinate = MyCoordinate == null ? new GeoCoordinate(0, 0) : MyCoordinate;
        MyGeocodeQuery.QueryCompleted += GeocodeQuery_QueryCompleted;
        MyGeocodeQuery.QueryAsync();
    }

    private void GeocodeQuery_QueryCompleted(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
    {
        ...

        if (e.Error == null)
        {
            if (e.Result.Count > 0)
            {
                if (_isRouteSearch) // Query is made to locate the destination of a route
                {
                    ...
                }
                else // Query is made to search the map for a keyword
                {
                    // Add all results to MyCoordinates for drawing the map markers.
                    for (int i = 0; i < e.Result.Count; i++)
                    {
                        MyCoordinates.Add(e.Result[i].GeoCoordinate);
                    }

                    ...
                }
            }
            else
            {
                MessageBox.Show("No match found. Narrow your search e.g. Seattle WA.");
            }
        }

        ...
    }
      

Downloads

This example application is hosted in https://github.com/nokia-developer/map-explorer, where you can check the latest activities, report issues, browse source, ask questions or even contribute yourself to the project.



Last updated 25 June 2014

Back to top

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×