Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

GPS and Location-Based Services in Resco.Location Library

6 Apr 2011 1  
The article discusses how to capture location information on a mobile device and how to use this information for location-based services such as getting driving directions, create custom maps etc. The article also presents Resco.Location library that provides respective high-level .NET classes for W

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

The article discusses how to capture location information on a mobile device and how to use this information for location-based services such as getting driving directions, create custom maps etc. The article also presents Resco.Location library that provides respective high-level .Net classes for Windows Mobile and Windows Phone 7 platforms.

Introduction

GPS applications in mobile devices are becoming popular nowadays and have a wide range of applicability. Examples of popular utilization of mobile GPS services include for instance:

  • Logistics - tracking of drivers, trucks and shipments
  • Touristics - customer navigation to hotels, tourists can track most popular attractions
  • Fleet location - tracking of ships, calculating the estimated time of arrival etc.
  • Person tracking - tracking of location of salespeople in the field etc.

Modern mobile devices are often location-aware. For example all Windows Phone 7 phones contain a GPS receiver. On the other hand there exist location-based services – web services that can convert raw GPS information into useful content such as maps, addresses, driving directions etc. All these services together are usually denoted as map services.

There exist various implementations of map services. Perhaps the best known examples represent Google Maps and Bing Maps. Map services are rather complex and their use is highly non-trivial.

The article starts from explaining location basics - GPS coordinates and their relation to geographical maps. In the next part we’ll discuss Google Maps vs. Bing Maps – both the possibilities and limitations. In the final part we’ll present Resco.Location library that provides high-level interface for using GPS data and location-based services.

The library is part of Resco MobileForms Toolkit and is currently supported on two platforms – Windows Mobile and Windows Phone 7.

Prerequisites

The target audience is a C# .NET programmer. Knowledge of Silverlight is not required.

Low Level GPS Data

Geographic coordinate System

Geographic coordinates describe every location on the earth by two numbers:

  • Latitude measures the angle from the equator towards the North or the South Pole. (Equator latitude is zero.)
  • Longitude represents the angle in the east-west direction from the reference meridian (Prime meridian) passing near Greenwich.

In the following we'll use the term GPS coordinates instead of longer latitude/longitude coordinate system. Following picture (taken from Wikipedia) shows GPS coordinates.

image1.png

Getting GPS Coordinates

The Global Positioning System (GPS) is a global navigation satellite system that provides reliable location and time information. It is maintained by the United States government and is freely accessible by anyone with a GPS receiver.

GPS receiver calculates its position from the signals sent by GPS satellites. (Four or more satellites are used to compute the location.) GPS receiver reports also altitude, i.e. elevation above the see level.

Except positional data, low-level GPS software in mobile phones can deliver additional information such as

  • Course (WP7 uses internal compass for this purpose)
  • Speed (Computed from the received GPS data)
  • Time stamp of the generated information

Availability of the GPS information on the phone

WP7 has built-in GPS receiver. The system API (GeoCoordinateWatcher class) lets you optionally select low-precision data, in which case the signals coming from the cellular network are used instead of GPS receiver.

This method provides less accurate results, but is more energy-efficient.

GPS and Resco.Location Library

GpsDevice class provides the main interface for receiving GPS information. You can start/stop data receiving and react on the PositionChanged event. WP7 users will find this interface remarkably similar to the built-in GeoCoordinateWatcher class. Indeed, it is. The purpose of this class is the unification of the code base across different platforms.

GpsTracking class can be used to obtain smoothed polyline that describes your movement during the period when the tracking was activated.
Receiving GPS signals is not enough. You have to present it to the user somehow, i.e. show it on the map or describe it in understandable form. This can be done by using Geo services supported by Resco.Location library as discussed in the rest of this article.

Location-based services

GPS coordinates and maps

The surface of the earth is approximately an ellipsoid. Maps, as we all know them, represent planar projection of the earth surface. Maps commonly use UTM (Universal Transverse Mercator) coordinate system. UTM is not a single map projection but a series of projections, each one valid for a local zone. There are sixty such zones and these zones partially overlap.

Conversions between GPS and UTM coordinates are only approximate and the error increases towards the zone boundaries. Different UTM zones use different GPS/UTM conversion formulas.

The lesson to be taken:

You cannot precisely show GPS point on the map without knowing how the map was constructed. (I.e. to which UTM zone it belongs to.)

The author made a personal experience in trying to construct GPS tracking system - displaying GPS coordinates of a moving car on a city map. With wrong UTM formulas the cars were moving parallel to the roads, whereby the errors were much larger than the GPS receiver accuracy.

Google and Bing map services discussed later offer a partial solution: They not only offer the map, but also draw the points of interest on this map. In other words, they solve the complex UTM/GPS conversions for you.

This is enough for applications such as route planning or even GPS tracking with low refresh rate. However, if you need real-time GPS tracking or you need to minimize net traffic (maps are images), you have no other choice but to delve into complex UTM topics.

Web map services

These services deliver maps and related data (such as GIS data, f.e. hydrological data, land evaluation...) over the web.

You should be aware of the disadvantages/problems related to web maps:

  • Reliability of the internet and web servers.
  • Web maps need relatively high bandwidth.
  • Limited screen space
  • Many web maps are of poor quality (region-dependent)
  • Copyright and privacy issues

There are many web map services often providing rather different services; a nice comparison can be found here: http://en.wikipedia.org/wiki/Comparison_of_web_map_services.

Web map services supported by Resco.Location Library

At present Resco.Location library supports Bing maps and Google maps services. Alternative providers such as Yahoo or OpenStreetMap may be added later.

You have to select the provider (Google or Bing) and then start to use high-level .Net classes. Apart from minor differences both providers offer identical services.

As far as the maps are concerned Resco.Location provides only static maps. These maps are delivered as raster images (png/jpg/gif) and they can be combined with additional information - markers (the figure below shows a marker positioned at four locations) or highlighted route.

image2.png

Besides their core functionality (maps), Google and Bing provide additional services. Two of these services are supported by Resco.Location library:

  1. Routing determines a route between given locations. Routing is done for driving/walking/bicycling and can be optimized to minimize cost/traffic/distance. You can optionally provide locations to be visited during the route - so called way points. Routing can be provided in textual form (as a series of instructions such as "turn left") or in visual form (showing the route on the map).
  2. Geocoding is the process of converting between civic addresses such as "221B Baker Street, London" (yes, Sherlock Holmes) and geographic coordinates, such as in this case
       Latitude: 51.523700; Longitude: -0.158600

While civic addresses are better suited for reports, GPS points can be easily shown on the map by placing a marker, for example.

Do not try manipulate the maps yourself (for example by drawing a marker) - you would encounter all kinds of problems:

  • Reliability of the map information
  • GPS/UTM conversion errors
  • Legal problems

The maps API is quite powerful and can do many things for you. (Even if things such as fast interactive GPS tracking are not among them.)

Conditions for using Maps API

Even if the services are free at the first sight, it is not quite true. Both Google and Microsoft impose limitations, conditions and paid services.

Using Google Maps Web Services

Resco.Location covers 3 services:

  • Google Static Maps API (downloading map images)
  • Google Geocoding API (translation between GPS addresses and civic addresses)
  • Google Directions API (requesting routing directions)

Elevation and places APIs are not covered. Deprecated services are unsupported as well - Google Geocoding V2 API, f.e.
Following restrictions apply (for ordinary users):

  • 1000 unique (different) image requests per viewer per day.
  • Geocoding API: 2500 requests per day
  • Directions API: 2500 requests per day, with up to 8 intermediate waypoints

Additionally:

  • The maps may only be displayed within browser content (Use of static maps outside of the browser is not allowed.)
  • Directions/Geocoding results may only be used to display the results in relation to a Google map; unrelated uses are prohibited.
  • Directions API generates copyrights which must be displayed to the user in some fashion.

There is another formal criterion:

Requests (maps/geocode/georoute) are encoded into an URL that is sent to respective web service. These URLs are restricted to 2048 characters in size (before URL encoding). You may easily violate this limit when requesting too many markers, for example.

Google Maps API Premier

You can purchase Google Maps API Premier with several advantages:

  • Service Level Agreement provides 99.9% uptime guarantee
  • Price is based on the number of map views and starts at $10/year.
  • Https support (unsupported by Resco.Location)

Premier API limitations (Higher limits can be purchased.):

  • Geocoding API: 100,000 requests per day
  • Directions API: 100,000 requests per day and a maximum of 23 waypoints per request
  • Maps: Image display outside viewer allowed.

After you purchase Google Maps API Premier, you’ll receive Google API key that need to be used with all requests. (See ServiceSettings class.)

Using Bing Maps Web Services

Bing Maps API represents numerous interfaces. One of them - Bing Maps REST Services - is used in Resco.Location library. (Another interesting example is Bing Maps Silverlight Control available f.e. on Windows Phone 7.)

You must have a Bing Maps Developer Account to get a Bing Maps Key for your application. This key is included in every location/route/mapping request and is used by Microsoft to count the transactions. (See ServiceSettings class.)

Microsoft imposes rather liberal limits on the free transactions, i.e.

  • 50,000 transactions per day
  • 500,000 transactions per year

Additionally:

  • You have to display Bing logo and copyrights.
  • “Real-time” navigation is forbidden
  • You may not integrate Bing maps with other map platforms (i.e. use either Bing or Google, but not both)

(Full Terms of use for Bing Maps (http://www.microsoft.com/maps/product/terms.html) are too complex to be reproduced here.)
Higher limits and more liberal conditions can be negotiated.

Resco.Location Library

In the following we’ll present main classes implemented in Resco.Location library. Class descriptions provided are rather schematic — written so that you can easily get an idea what is offered. All unneeded information is stripped off. (For example the keyword public is omitted, properties are listed by name only etc.)

Service implementation scheme

All service classes (GeoCode, GeoRoute, GeoMap) follow the same scheme:

  • They let the user setup the request
  • The request is translated into an URL
  • The URL is sent to the respective web service
  • The service response is parsed and translated into user-understandable form

All service classes implement event-based asynchronous pattern with multiple concurrent calls allowed. Synchronous pattern is implemented for WM platform only.

Here is the pattern used for all service classes:

class SomeService
{
	// 1. Members defining the request are service-dependent
	...
 
	// 2. Async request; parameters are service-dependent
    	void GetXXXAsync( ...parameters..., object userState)
 
	// 3. Event signaling request completion (success or failure)
    	event EventHandler<GetXXXCompletedEventArgs> GetXXXCompleted;
 
	// Synchronous interface is supported on WM platform only
	#if !SILVERLIGHT
		GeoPoint GetXXX(...parameters...)
	#endif
}
 
class GetXXXCompletedEventArgs : AsyncCompletedEventArgs
{
	// Definition of the properties containing the result (Address, Route...)
	// Note you cannot access results when Error!=null (an exception is thrown)
	....
 
	// Getters inherited from System.ComponentModel.AsyncCompletedEventArgs
	bool Cancelled			// Returns false (Cancel unsupported)
	Exception Error			// Error information; null on successful termination
	Object UserState		// Object passed to the async call
}

Namespace Resco.Location

The namespace contains basic classes used by other more specialized namespaces.

// Helper class providing distance conversions
struct GeoDistance
{
    GeoDistance(double meters)
 
    double Meters, Kilometers, Feet, Yards, Miles, NauticalMiles	// Conversion properties
    operators <, <=, >, >=, ==, !=, +, -, *, /
    string ToString()		// Uses format from ServiceSettings.DefaultUnitSystem
}
 
// GPS point with string conversions and distance computation
class GeoPoint
{
    GeoPoint(GeoPoint p)
    GeoPoint(double lat, lon)
 
    double Latitude, Longitude		// point coordinates
 
    GeoPoint Move(lat, lon)			// this += [lon,lat]
    GeoDistance GetDistanceTo(GeoPoint other)	// (Approximate) distance between GPS points
 
    // String conversions support common formats such as 40:26:46.302N, 
    // 40°26'21"N, 79d 58' 36" W, 40.446195N
    GeoPoint(string str)
    GeoPoint(string lat, string lon)
    string ToString( eGPSFormat fmt, string delimiter)	// a number of formats available
}
 
// GPS rectangle
class GeoArea
{
    GeoArea( GeoPoint southWest, northEast)		// More constructors available
 
    GeoPoint SouthWest, NorthEast
    GeoDistance Width/Height				// Average dimensions
    GeoPoint CenterPoint
 
    bool IsEnclosing( point | area)			// Tests
    void EnlargeArea( point | area)			// Enlarge area by including point
                                                         // or another area
    void InflateArea( ... )				// various arguments
}
 
// Polyline supporting string conversions (string format is used in web requests)
class GeoPolyline
{
    GeoPolyline( string polyline )
    GeoPolyline( IEnumerable points )
 
    string Polyline			// encoded polyline
    List<GeoPoint> Points		// polyline
    GeoDistance Length		// polyline length
}

Namespace Resco.Location.GPS

The namespace provides classes working with GPS receiver. The API is modeled by GPS classes built-in in Windows Phone 7.

// GPS point
// (WP7 equivalent: GeoPosition<GeoCoordinate>)
class GeoPosition : GeoPoint
{
    DateTime TimeStamp					// local device time
    double Altitude, Course, Speed, HorizontalAccuracy, VerticalAccuracy
}
 
// API for working with GPS receiver
// (WP7 equivalent: GeoCoordinateWatcher)
class GpsDevice : IDisposable
{
    // Getters:
    GeoPosition Position				// The most recent position
    GeoPositionStatus Status		// Service status: Disabled/Ready/Initializing/NoData
 
    // Events:
    PositionChanged			// delivers GeoPosition
    StatusChanged			// delivers GeoPositionStatus
 
    static GpsDevice Create()	// Constructor
 
    // WP7 only: Constructor reusing existing GeoCoordinateWatcher
    static GpsDevice Create(GeoCoordinateWatcher watcher, bool dispose)
 
    bool Start();
    void Stop();
 
    bool WaitForLocation(int timeout)	// Synchronous wait for new position
}
 
// Implements GPS position tracking, i.e. remembers smoothed polyline describing
// your movement during the time the tracking was active.
class GpsTracking : IDisposable
{
    // Constructor can reuse existing device or create a new one
    GpsTracking()
    GpsTracking(GpsDevice device, bool dispose)
 
    // Setup conditions for remembering points
    TimeSpan MinimalTimeDifference	// Min. time period between remembered points; Default = 10 sec
    GeoDistance MinimalDistance	// Min. distance between remembered points; Default = 50m
    double RouteAccuracy		// 0..1; default=0.98; hustota zapamatanych bodov
 
    bool Start()
    void Stop()
 
    // Remembered points (getters)
    List<GeoPosition> TrackList	// Source points
    GeoPolyline Polyline		// Constructs polyline from current TrackList
 
    // Events
    TrackListChanged		// Occurs when the TrackList changes
    StatusChanged			// Occurs when service status changes
}

Namespace Resco.Services

Namespace contains service-oriented classes used by individual services.

enum eServiceProvider			// Default, Google, Bing
 
// Class describing civic address
class Address
{
    Address(string country, string city, string street, string streetNum)
    string StreetNumber, Street, City, Region, Country, CountryCode, PostalCode
    string ToString()		// "Dunajska 12, Bratislava[, region], Slovakia"
}
 
// Basic exception type used for all service-oriented classes. 
// It has public members at present.
class ServiceRequestException : Exception
 
// Global settings for all service-oriented classes.
// Implements Singleton pattern; i.e. only one global instance of ServiceSettings exists.
class ServiceSettings
{
    static ServiceSettings Instance 	     // Use to set global settings
 
    // API keys used in service requests
    string BingApiKeyl		     // Condition for using Bing Maps
    string GoogleApiKeyl		     // Set if you have Google Maps API Premier
 
    // Other global settings. 
    // Provider and units be overriden by individual service classes. 
    // (Wheerever it makes sense.)
    eServiceProvider DefaultProvider	      // Default=Bing.
    eUnitSystems DefaultUnitSystem	     // Default=Metric. Used also by GeoDistance.ToString().
    string Language
}

Namespace Resco.Services.GeoCode

Class GeoCode provides the translation between GPS locations and civic addresses. Each translation direction represents a separate request.

class GeoCode
{
    // 1) Request setup
    eServiceProvider ServiceProvider	// Default: ServiceSettings.DefaultProvider
 
    // 2a) Request for translation GeoPoint -> Address
    void GetAddressAsync(GeoPoint location, object userState)
 
    // 3a) Wait for completion event
    event EventHandler<GetAddressCompletedEventArgs> GetAddressCompleted;
 
    // 4a) Results are provides by GetLocationCompletedEventArgs object with these getters:
        GeoPoint Location			// Translation result
        GeoArea ViewPoint			// Optional: null if Location describes the
                                                // result sufficiently
        eGeoPrecision LocationPrecision	// Unknown, Precise, Interpolated, GeoCenter, Aproximated
 
    // 2b) Request for opposite translation Address -> GeoPoint
    void GetLocationAsync(Address address, object userState)
 
    // 3b) Wait for completion event
    event EventHandler<GetLocationCompletedEventArgs> GetLocationCompleted;
 
    // 4b) Results are provided by GetAddressCompletedEventArgs object with these getters:
         Address Address			// Translation result
         eGeoPrecision LocationPrecision	// Unknown, Precise, Interpolated, GeoCenter, Aproximated
         GeoArea ViewPoint			// Optional: Used when the address represents areal object 
         string FormattedAddress		// Optional: Formatted address provided by the web service
         string EntityType			// address, route, street
 
    // Synchronous interface (WM platform only) provides only partial results:
    Address GetAddress(GeoPoint location)
    GeoPoint GetLocation(Address address)
}

Namespace Resco.Services.GeoRoute

Class GeoRoute provides high-level API for routing service. The remaining classes are used to describe routing result.

enum eTravelModes		// Driving, Walking, Bicycling
 
// Result of the routing request
class GeoRouteResult
{
    List<GeoRouteLeg> RouteLegs
    string Copyrights		// Copyright information; need to be presented!
}
 
// GeoRouteResult consists of GeoRouteLeg's representing portion of
// a route between two waypoints.
class GeoRouteLeg
{
    string StartAddress, EndAddress
    GeoRouteSummary Summary
    GeoPoint EndLocation
    GeoPolyline Polyline
    List<ItineraryItem> ItineraryItems
}
 
// GeoRouteLeg consists of ItineraryItem's representing one step of a route.
class ItineraryItem
{
    eCompassDirection Direction	// Unknown(-1), East(0), SouthEast(45), South ... NorthEast(315)
    eTravelModes TravelMode
    eIconType IconType		// None, Airline, Auto, Bus, Ferry, Train, Walk, Other 
    GeoRouteSummary Summary
    GeoPolyline Polyline
    string Instructions
}
 
// Summary information for ItineraryItem, such as total distance and time
class GeoRouteSummary
{
    GeoPoint StartLocation
    GeoDistance Distance
    TimeSpan Duration
    GeoArea Bounds
}
 
class GeoRoute
{
    // 1) Request setup
    RouteOptions
    {
    eWayType AvoidWayType			// Ignore (default), AvoidTolls, AvoidHighways
	eTravelModes TravelMode		// Default = eTravelModes.Driving
	eUnitSystems Units			// Default = GeoDistance.DefaultUnitSystem
	eRouteOptimization Optimization	// MinimizeTime (default), MinimizeDistance…
 
	// Bing only:
	// Set to include GPS coordinates into the result. Needed to display GeoRouteResult on a map.
	bool RequirePathPoints			// Default=false
    }
    eServiceProvider ServiceProvider;
 
    // 2) Request for routing between src and dst locations with optional way points
    void GetRouteAsync( Address src, Address dst, object userState, params Address[] waypoints)
    void GetRouteAsync( GeoPoint src, GeoPoint dst, object userState, params GeoPoint[] waypoints)
 
    // 3) Wait for completion event
    event EventHandler<GetRouteCompletedEventArgs> GetRouteCompleted
 
    // 4) The results are provided by GetRouteCompletedEventArgs object with a single getter:
	GeoRouteResult Route
 
    // Synchronous interface (WM platform only):
    GeoRouteResult GetRoute(Address src, Address dst, params Address[] waypoints)
    GeoRouteResult GetRoute(GeoPoint src, GeoPoint dst, params GeoPoint[] waypoints)
}

Namespace Resco.Services.Map

Class GeoMap provides high-level API for downloading static map images. The remaining classes are used to describe supplementary map content.

Note that there are substantial differences between the setup of Google and Bing maps.

// Represents highlighted line on a map.
// One of the most common applications is to highlight the routing result.
class GeoMapPath
{
    // Construct path from a result of a routing request (can be used for both Google/Bing)
    GeoMapPath(GeoRouteResult route)
 
    // Google can highlight any polyline and offers additional setup parameters:
    Color  RouteColor			// Route color either as a 24-bit or 32-bit alpha value
    Color  MapFill				// Used to fill polygonal area
    int    RouteWeight			// Path thickness in pixels; Default=3
 
    GeoMapPath(GeoPolyline polyline)
}
 
// Marker is a graphical symbol that is placed at given locations.
class GeoMapMarkers
{
    // Create Google markers
    // Label = 1 character string
    // Size = one enum values Default/Mid (Can contain label), Small/Tiny (ignore label)
    // Locations = Address or GeoPoint instances
    GeoMapMarkers( Color col, size, label, params locations[] )
    string IconUrl				// Optional URL of the custom icon (png/jpg/gif)
 
    // Create Bing markers
    // Label = string with at most 2 characters
    // MarkerType = one of 36 icons available (http://msdn.microsoft.com/en-us/library/ff701719.aspx") (default=1)
    // Locations = Address or GeoPoint instances
    GeoMapMarkers( int markerType, label, params locations[] )
}
 
class GeoMap
{
    // 1) Request setup
    eServiceProvider ServiceProvider
    List<GeoMapMarkers>  Markers		// Optional markers shown on the map
    GeoMapPath Path			// Optional highlighted path
 
    Options				// Specify either Center+Zoom or ViewPoint area
    {
        Size ImageSize		// [pix]; Bing max. 800x834, Google max. 640x640; Default = screen size
        eImgFormat Format			// enum: Png, Png32, Gif, Jpg; Default=Png
        eMapType MapType			// enum: Roadmap, Satellite, Hybrid, Terrain; Default=Roadmap
        object Center				// GeoPoint or Address object
        int Zoom				// 1-22 for Bing, 0-21 for Google; default=12
        GeoArea ViewPoint			// Area shown on the map
    }
 
    // 2) Request for static image
    void DownloadMapAsync(object userState)
 
    // 3) Wait for completion event
    event EventHandler<DownloadMapCompletedEventArgs> DownloadMapCompleted;
 
    // 4) The results are provided by DownloadMapCompletedEventArgs object with these getters:
    	Stream ImageStream
    	ImageSource Image		// WP7 only
    	Bitmap Image			// WM only
 
    // Extra services
    string URL			// Translates current setup into an URL that can
                                      // be passed to the browser
    void ShowInBrowser()		// Calls system browser to display URL property
 
    // Synchronous interface (WM platform only):
    Stream DownloadMap()
}

How to implement GPS tracking – Sample Code

Below we’ll demonstrate how to build a WP7 application that track your movement and shows the tracked route on the map. The code is simplistic, i.e. all checks etc. were stripped off.

Minimalistic MainPage.xaml contains

  • TextBlocks GPS status and last received position
  • Button for showing the tracked route on the map
<phone:PhoneApplicationPage>
    <StackPanel Margin="12,0,12,0">
        <TextBlock x:Name="statusText" />
        <TextBlock x:Name="positionText" />
        <Button Content="Show Map" Click="btnShowMap"/>
    </StackPanel>
</phone:PhoneApplicationPage>

What is included in the MainPage.cs code:

  • Setup of the GPS provider. We select Google because we want to show tracking result (i.e. a general polyline) on the map. Bing can’t do that.
  • Setup of the GpsTracking object
  • GPS tracking starts when the page is loaded and stops when the page unloads
  • Status and position changes are shown in the UI
  • The map showing tracked route is shown when the [Show Map] button is pressed.
public partial class MainPage : PhoneApplicationPage
{
    GpsTracking gpsTracking = new GpsTracking()
    {
        // We consider 1 signal per second and ignore positions within 10m accuracy.
        MinimalDistance = new GeoDistance(10),
        MinimalTimeDifference = new TimeSpan(0, 0, 1)
    };
 
    // Constructor
    public MainPage()
    {
        ServiceSettings.Instance.DefaultProvider = eServiceProvider.Google;
        //ServiceSettings.Instance.GoogleApiKey = "???";	// If you purchased Google Maps API Premier
 
        InitializeComponent();
 
        // Start/stop tracking when the page loads/unloads
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        this.Unloaded += new RoutedEventHandler(MainPage_Unloaded);
 
        // Define event handlers
        gpsTracking.StatusChanged += new EventHandler<StatusChangedEventArgs>(gpsTracking_StatusChanged);
        gpsTracking.TrackListChanged += new EventHandler(gpsTracking_TrackListChanged);
    }
 
    void MainPage_Unloaded(object sender, RoutedEventArgs e)
    {
        gpsTracking.Start();
    }
 
    void MainPage_Unloaded(object sender, RoutedEventArgs e)
    {
        gpsTracking.Stop();
        gpsTracking.Dispose();
    }
 
    // Update position TextBlock when Position arrives
    void gpsTracking_TrackListChanged(object sender, EventArgs e)
    {
        var list = gpsTracking.TrackList;
        string txt = list.Count > 0 ? list[list.Count - 1].ToString() : "NoData";
        positionText.Text = txt;        // WP7: GPS events are fired on the UI thread
    }
 
    // Update status TextBlock when status changes
    void gpsTracking_StatusChanged(object sender, StatusChangedEventArgs e)
    {
        statusText.Text = e.Status.ToString();
    }
 
    // Show the tracking results on the map
    private void btnShowMap(object sender, RoutedEventArgs e)
    {
        gpsTracking.Stop();
        var map = new GeoMap() { Path = new GeoMapPath(gpsTracking.Polyline) };
        map.ShowInBrowser();
    }
}

About Resco.Location Library

The library is part of Resco MobileForms Toolkit that can be downloaded from http://www.resco.net/developer/mobileformstoolkit. Sample code can be downloaded from the same location.

The Toolkit is provided for four platforms - Windows Phone 7, Windows Mobile, Android and iOS. At the time of this writing the Location library was available for Windows Phone 7 and Windows Mobile platforms.

About the Author

Jan Slodicka. Programming for over 30 years. Covered several desktop platforms and programming languages. Since 2003 working for Resco on mobile technologies – Palm OS, Windows Mobile, now Windows Phone 7.

You can contact me at jano at resco.net or through Resco forums.

Resco MobileForms Toolkit - Windows Phone 7 Edition can be downloaded from http://www.resco.net/developer/mobilelighttoolkit. The Toolkit contains a set of useful controls that simplify Windows Phone 7 programming. Besides WP7, there is also Windows Mobile, Android and iOS edition.

Resco is a company with a long tradition of mobile programming covering many platforms and both end-user applications and developer tools.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here