Windows Support Number

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Tuesday, 27 September 2011

Geo-location on WP7 - don't trust the first value returned

Posted on 13:28 by Unknown
Rich & I have been working on app which makes heavy use of geo-location information provided by the GeoCoordinateWatcher class on the WP7 platform. As the documentation on MSDN states this class exposes the Windows Phone location services. The GeoCoordinateWatcher class implements the INotifyPropertyChanged interface and all the events generated will be fired on the UI thread allowing you to easily bind the class to the UI, but as we already knew this is not always a good idea - for a detailed reason why this can be a bad idea check out this post by Jaime Rodriguez.

What we also discovered is that you can't always trust the first position event generated by this class.

We have a requirement to get the current location when a user clicks a button, the user could do this at any time when using the application - they could click once, a dozen times or not at all. Every time they click the button we need to get an accurate single value. The accuracy of the value depend on both the actual value and the age of the value. Every value generated by the GeoCoordinateWatcher class is published by via the PositionChanged event and this is made up of 2 components - the location value and the timestamp when the location value was generated, this is exposed as the GeoPosition<T> class.

The PositionChanged event is defined as follows. I've included the StatusChanged event to show all the event signatures for the class:

public class GeoCoordinateWatcher : IDisposable, INotifyPropertyChanged, IGeoPositionWatcher<GeoCoordinate>
{
public event EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>> PositionChanged;
public event EventHandler<GeoPositionStatusChangedEventArgs> StatusChanged;

...
}

The point of interest is the type used with the event handler. The GeoPositionChangedEventArgs class has the following definition.The Position property exposing the GeoPosition<T> value, this has the time stamp value.

public class GeoPositionChangedEventArgs<T> : EventArgs
{
public GeoPositionChangedEventArgs(GeoPosition<T> position);
public GeoPosition<T> Position { get; }
}
public class GeoPosition<T>
{
    public GeoPosition();
public GeoPosition(DateTimeOffset timestamp, T position);
public T Location { get; set; }
public DateTimeOffset Timestamp { get; set; }
}

We use the following code to return a single geo-location value when the button is clicked. It uses Rx (reactive extensions) to wrap up the call to the GeoCoordinateWatcher class. We don't just use the 'FromEventPattern' Rx method because we don't want the instance of the GeoCoordinateWatcher running riot and generating a gazillion location results and killing the UI thread!


The highlighted areas show how I am using the time offset to determine the validity of the location published by the GeoCoordinateWatcher class. In this demo instance I am saying - 'if the position timestamp is greater than 20 seconds ago then ignore the value...'. When valid the new location is published using the Rx method 'OnNext' on the returned Subject<T>. We also call the Rx 'OnCompleted' method to make the 'Finally' method execute and shut down the watcher by calling 'watcher.Stop()'.



Note: We also do the 'Start' of the GeoCoordinateWatcher  on a background thread to prevent blocking of the current thread - in this case the UI thread.

This class is the used in the page class as follows:

When run for the first time (on the emulator) I get the following in the output window of visual studio:


When this is run for subsequent times the debug statements in the output window of visual studio depend on how long the interval between clicking the button.

The following shows 2 values because the time interval between clicks is greater than 20 seconds. The first value generated by the instance of the GeoCoordinateWatcher class is ignored.


To show this is not an attribute of the currently executing application session, I've added an explicit finalise to the main page as well as a debug statement in the constructor. This shows that once the location services are initialised on the phone and the current location is requested then the last value is always stored by the device and published as the first event when the GeoCoordinateWatcher is started.


The above screen shot shows 3 distinct activations of the application after tomb-stoning the device twice.

As you can see the first run shows the last geo-location generated by the device was 4 hours prior, then we tomb-stoned the app for 30 seconds, then re-activated the app with a back press. Again because the previous geo-location was generated greater than 20 seconds ago it is ignored. Finally the last activation after tomb stoning was not greater than 20 seconds so it was not ignored.

This code has been incorporated into the WP7Contrib as the LocationService. It has method for getting the geo-location using time & distance thresholds as well. It also has provides the GeoCoordinateWatcher  Status event as an observable method.

The code is available in this change-set or will be part of the 1.4 release due at the end of the month.





Email ThisBlogThis!Share to XShare to FacebookShare to Pinterest
Posted in WP7Contrib WP7 Geo-Location development C# | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • Unit testing Rx methods Timeout & Retry with moq
    Earlier this week I was trying to unit test an asynchronous service (Foo) which used another asynchronous service (Bar) internally and ran i...
  • Understanding RefCount in Reactive Extensions
    A couple of weeks ago  @LordHanson  & I ran into an issue converting a stateless async service exposed as an Rx cold observable to a  co...
  • StructureMap: ILifecycle
    The other day I wanted to control the scope of a service inside a web based app with semantics which didn't fit either 'HttpContextS...
  • MVVM anti-pattern: Injecting the IoC container into a View Model
    This is another anti-pattern I've seen a lot recently, the dynamic use of the IoC container inside a view model to resolve child view mo...
  • How many pins can Bing Maps handle in a WP7 app - part 1
    part2 -  http://awkwardcoder.blogspot.com/2011/10/how-many-pins-can-bing-maps-handle-in.html part3 -  http://awkwardcoder.blogspot.com/2011/...
  • Bad developers love 'The Daily WTF'
    When 'The Daily WTF' started up back in 2003/2004 it was a great laugh looking at shocking code other developers wrote, but after a ...
  • Using CompositeDisposable in base classes
    To help make an object eligible for collection by the GC (garbage collector) one would implement the IDisposable interface. Executing the di...
  • Implementing a busy indicator using a visual overlay in MVVM
    This is a technique we use at work to lock the UI whilst some long running process is happening - preventing the user clicking on stuff whil...
  • Daily Dilbert Service - the most important service I've ever written...
    NuGet package available here ... First off a big shout to  @hamish  &  @leeoades  on this one - I'm just blogging about it. At work ...
  • Comparing performance of .Net 4.5 to .Net 4.0 for WPF
    Currently I'm working on a .Net 4.0 WPF app and we've had some discussion about moving to .Net 4.5, we don't get to make the dec...

Categories

  • .Net
  • .Net 4.5
  • Abstractions
  • Advertising
  • Agile
  • Agile Courage
  • AOP
  • Async
  • automated testing
  • Azure
  • Azure IIS RESTful development
  • BDD
  • Bing Maps
  • Bounded Context
  • C#
  • C# 5.0
  • Caching
  • Chocolatey
  • CLoud
  • CodePlex
  • Coding
  • Coding Building CI Testing
  • Coding C#
  • coding C# IoC StructureMap
  • Coding Functional-Programming
  • Coding REST Knowledge
  • Coding Services
  • Coding TDD Refactoring Agile
  • Command
  • continuous testing
  • coupling
  • CultureInfo
  • DAL
  • databases
  • DDD
  • DDD Coaching
  • DDD Domain Events Auditing nHibernate
  • DDD Entities Value Objects
  • Debugging
  • Design Patterns
  • Design Patterns Databases Auditing
  • Developement
  • Development
  • Development Coding
  • Development Process
  • Development unit testing
  • Development VS 2011
  • Diagnostics
  • Disposable
  • Exceptions
  • FINDaPAD
  • FindaPad Property Rental Windows Phone 7 Mobile Devices
  • Fun Coding Duct-Tape
  • Hotfixes
  • integration testing
  • IoC
  • jasmine
  • javascript
  • Jobs Development
  • LINQ
  • marketplace
  • Mobile Devices
  • Mocking
  • MSDN Coding
  • MSpec
  • Multilingual
  • MVC
  • MVVM
  • nCrunch
  • nHbiernate Repository Pattern Criteria
  • nHibernate Auditing Design Fluent
  • nHibnerate Entities Events Listeners
  • node.js
  • nodes.js
  • Nokia
  • NoSQL RavenDB Azure Development
  • Observations
  • OO
  • ORM
  • Performance
  • Portable Class Library
  • Portable Library
  • PostSharp
  • Process
  • Rants
  • RavenDB IIS 7.5 Development
  • Reactive
  • Reactive Extension
  • Reactive Extensions
  • ReadOnlyCollections
  • Resharper
  • REST Distributed-Systems
  • REST HTTP
  • rest web
  • RESTful
  • Rx
  • Serialization
  • Silverlight
  • Silverlight Installation
  • Task
  • TDD
  • TDD IoC DI
  • TDD Mocking
  • TDD Team Observation
  • Telerik
  • testing
  • threading
  • TPL
  • UI
  • Undo-Redo
  • unit testing
  • ViewModels
  • VS 2012
  • wcf
  • web api
  • Web Services
  • web services mobile devices data
  • WebAPI
  • Windows
  • Windows 8
  • windows phone
  • Windows Phone 7
  • WP7
  • WP7 Bing Maps Development Network HTTP
  • WP7 Bing Maps Development UK Crime
  • WP7 Bing Maps Development UK Crime Clustering
  • WP7 Bing Maps Development UK Polygons Clustering Performance
  • WP7 cryptography bouncy castle
  • WP7 Cultures C#
  • WP7 feedback development app store
  • WP7 Javascript web browser
  • WP7 MSBuild
  • WP7 ORM Databases performance
  • WP7 Serialisation
  • WP7 SilverlightSerializer C#
  • WP7 sqlite performance development
  • WP7 WP7Contrib Bing Maps Development
  • WP7 WP7Contrib Bing Maps Polygon Development
  • WP7 WP7Contrib CodePlex
  • WP7 WP7Contrib CodePlex Bing Maps Development
  • WP7 WP7Contrib CodePlex ObservableCollection
  • WP7 WP7Contrib ILMerge .Net
  • WP7 WP7Contrib Phone Maps
  • WP7 WP7Contrib SilverlightSerializer C#
  • WP7Contrib
  • WP7Contrib Bing Maps WP7
  • WP7Contrib WP7 Geo-Location development C#
  • WP7Contrib WP7 HTTP Compression
  • WP7Contrib WP7 Url Development Rx
  • WP7Dev
  • WPF
  • WPF Cultures
  • WuApi
  • XAML

Blog Archive

  • ►  2013 (16)
    • ►  November (5)
    • ►  September (3)
    • ►  August (1)
    • ►  July (1)
    • ►  June (3)
    • ►  May (2)
    • ►  January (1)
  • ►  2012 (44)
    • ►  November (2)
    • ►  October (8)
    • ►  September (5)
    • ►  August (2)
    • ►  July (4)
    • ►  June (3)
    • ►  May (1)
    • ►  April (2)
    • ►  March (13)
    • ►  February (4)
  • ▼  2011 (52)
    • ►  December (3)
    • ►  November (5)
    • ►  October (7)
    • ▼  September (7)
      • WP7Contrib: Criterion Factory - calculating a Route
      • Geo-location on WP7 - don't trust the first value ...
      • How many pins can Bing Maps handle in a WP7 app - ...
      • Attaching multiple sqlite databases in WP7
      • Using a simple ORM with sqlite on WP7
      • Supported cultures in Windows Phone 7 and showing ...
      • WP7Contrib: Criterion Factory - Location by address
    • ►  August (11)
    • ►  July (4)
    • ►  May (2)
    • ►  April (1)
    • ►  March (5)
    • ►  February (3)
    • ►  January (4)
  • ►  2010 (1)
    • ►  August (1)
  • ►  2009 (32)
    • ►  December (3)
    • ►  November (7)
    • ►  October (6)
    • ►  September (11)
    • ►  April (1)
    • ►  March (4)
Powered by Blogger.

About Me

Unknown
View my complete profile