Windows Phone geocoding with Rx

INTRODUCTION

I had heard lot about Reactive Extensions (Rx) in the past but never got a chance to play with it until recently one of my project requirements were idle to make use of this great library.In this post I share my experience on how I used this library. Before we jump into code I would like to summarize the definition of Rx for the readers who haven’t known about it.

WHAT IS RX

Up till now we had heard that computers came up with multiprocessors and gigabytes of memory but now we are hearing the same for even mobile devices. The new models do come with dual core processers and enough memory. As a developer you need to adopt some special programming techniques to unleash this power. You must write concurrent and asynchronous code to scale up to the hardware. When we talk about the asynchronous programming lot of caution needs to be taken for threading and deadlock issues. Fortunately Rx.NET does all this heavy lifting for you and gives you a fluent api for Async programming with LINQ flavour.Rx.NET is developed at Microsoft Labs and comes for full .net Framework, Silverlight, Windows Phone and JavaScript.
Rx is based on the Observer pattern from the world of object oriented programming. This pattern is based on the Observable collection, known as a Subject. You register or subscribe as an Observer for this Subject and you get notified whenever there is a change in the collection. Let me explain you this with example code.

var numbers = Observable.Range(1,50);
numbers.Subscribe(x =>
textBlock1.Text += String.Format(" OnNext: {0}", x),
ex => textBlock1.Text += String.Format(" OnError: {0}", ex.Message),
() => textBlock1.Text += " OnCompleted");

In the above example the numbers collection is between 1 to 50. I subscribe to this collection for getting notifications. This is achieved by specifying the first argument of the subscribe method which is OnNext action method. The second argument is OnError , which is again the action method, you can handle the errors here and finally the OnCompleted, where you can do the cleanup if required or do the final processing.
Rx is entirely based on the LINQ and support all its extension methods like Where,Take,Skip etc. LINQ works with collections that implement IEnumerable,which are known as enumerable collections. Rx works with collections that implement an extension to IEnumerable, IQueryable, which is refer to as observable collections. Hope you must have got the fair idea of Rx by now for further study I would redirect you to Rx official site where there are great tutorials and samples to get you started.

USING Rx IN WINDOWS PHONE FOR GEOCODING

As mentioned above Rx library is available for Windows Phone 7 also, It is part of the SDK itself and you don’t need a separate download. All you need to add reference to your project two assemblies.
1)Microsoft.Phone.Reactive
2)System.Observable
In the sample application we display the GPS status and its coordinates coming from the location emulator. The user clicks on the Start button and then clicks on the location emulator to see the coordinates getting changed in the phone emulator. See the screenshot below for more clarity.

GeoCodewithRxDemo

To capture the latitude and longitudes you need to handle the PositionChanged event of GeoCoordinateWatcher class. The eventargs of this event is of prime importance to us as we will be using it to get the positions. See the code below.

var positions = Observable.FromEvent>(watcher, "PositionChanged").Where(g => !Double.IsNaN(g.EventArgs.Position.Location.Latitude) && !Double.IsNaN(g.EventArgs.Position.Location.Longitude));


positions.ObserveOnDispatcher().Subscribe(geo =>
{
this.txtPositon.Text = string.Format("{0:###.0000N;###.0000S;0}, {1:###.0000E;###.0000W;0}"
, geo.EventArgs.Position.Location.Latitude
, geo.EventArgs.Position.Location.Longitude
);

});

In the above code one thing to look is the Observable.FromEvent(watcher, “StatusChanged”). I am telling the Rx to Capture all the values coming from the observable collection of GeoPositionChangedEventArgs on the watcher object which is of type GeoCoordinate and the event name is PostionChanged. This will dump all the values of incoming coordinates in the positions variable. And then further I am interested in this collection so I will subscribe to it and will be notified whenever this collection gets changed. If you remember on the top I mentioned that Rx goes hand in hand with Linq and supports all its extension methods. Here in the above code I using Where to get only valid lats and longs which is having proper double values rest will be discarded. On receiving the notification that is onNext Action method ,I simply update my TextBlock Text in proper format of gps position.To avoid the cross thread issues I am using the ObserveOnDispatcher extension method.

CONCLUSION

I have barely scratched the surface of Rx there is a lot to it. I strongly recommend that all devs should acquire its knowledge and used it in their projects.Rx makes Async programming breeze which makes it as an idle choice to work with webservices.
Download the sample code of this post from here.

Cheers :)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s