<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="www.w3.org/2005/Atom" xmlns:sy="purl.org/rss/1.0/modules/syndication/" xmlns:dc="purl.org/dc/elements/1.1/" xmlns:content="purl.org/rss/1.0/modules/content/" xmlns:wfw="wellformedweb.org/CommentAPI/" xmlns:slash="purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Dragos Manolescu's (work) blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/dragoman/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/dragoman/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 05:03:40 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Moved to a new home</title>
      <link>https://docs.microsoft.com/archive/blogs/dragoman/moved-to-a-new-home</link>
      <pubDate>Fri, 03 Aug 2012 07:14:02 GMT</pubDate>
      <dc:creator><![CDATA[Dragos Manolescu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dragoman/2012/08/03/moved-to-a-new-home/</guid>
      <description><![CDATA[You're looking at dead content. I am no longer updating this blog and have relocated to my personal...]]></description>
      <content:encoded><![CDATA[<p>You're looking at dead content. I am no longer updating this blog and have relocated to my <a href="micro-workflow.com">personal web site</a>. See you there ;)</p>]]></content:encoded>
    </item>
    <item>
      <title>WP7 Code: Mocking Event Streams with IEnumerable</title>
      <link>https://docs.microsoft.com/archive/blogs/dragoman/wp7-code-mocking-event-streams-with-ienumerable</link>
      <pubDate>Sun, 12 Dec 2010 22:40:45 GMT</pubDate>
      <dc:creator><![CDATA[Dragos Manolescu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dragoman/2010/12/12/wp7-code-mocking-event-streams-with-ienumerable/</guid>
      <description><![CDATA[A few weeks ago I showed how to represent computations involving geo locations or accelerometer...]]></description>
      <content:encoded><![CDATA[<p>A few weeks ago I showed how to represent computations involving <a href="https://blogs.msdn.com/b/dragoman/archive/2010/09/21/wp7-code-using-the-geolocation-api.aspx">geo locations</a> or <a href="https://blogs.msdn.com/b/dragoman/archive/2010/11/01/wp7-code-using-the-accelerometer-api.aspx">accelerometer readings</a> as queries over RxLINQ event streams (i.e., IObservable collections). In both instances the event source was one of the sensors that is on board of every Windows Phone 7 device. What happens when applications querying position changed or acceleration reading changed event streams run in the emulator? As there are no physical sensors the events don’t fire. For example, the 2-D bubble level application from my previous post shows a stationary bubble. Does that mean that one cannot write location or accelerometer code and experiment with it in the emulator? Likewise, is testing in the emulator a dead end? In light of the above it would seem so. However, the <a href="headinthebox.posterous.com/subjectobserver-is-dual-to-iterator">duality between&#160; IObservable and IEnumerable</a> provides an elegant way to mock event streams with any IEnumerable source. This blog post shows how to exploit the duality in the context of the 2-D bubble application. With just a few changes you should be able to run and test the application without an actual accelerometer sensor, in the emulator.</p>  <p>To illustrate how trivial the changes are let me start top-down rather than bottom up. Recall that the first query in the 2-D bubble level pulled the accelerometer readings into a local variable named as such; here’s a snippet from that code with the key part highlighted:</p>  <blockquote>   <p><font face="Lucida Sans Typewriter">{</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160; var accelerometerReadings = <font style="background-color: #ffff00">accelerometer.GetAccEventStream();</font></font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160; var x0 = (double)ellipse1.GetValue(Canvas.TopProperty) + ellipse1.Width / 2;        <br />&#160;&#160;&#160; var y0 = (double)ellipse1.GetValue(Canvas.LeftProperty) + ellipse1.Height / 2;</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160; // snip</font></p>    <p><font face="Lucida Sans Typewriter">}</font></p> </blockquote>  <p>The <em>only</em> change in RxLINQ queries entails sourcing the event stream from a different object (an instance of DataLoader). Here’s the modified code; there are no other changes to this class:</p>  <blockquote>   <p><font face="Lucida Sans Typewriter">{        <br />&#160;&#160;&#160;&#160; <font style="background-color: #ffff00">var dl = new DataLoader();</font></font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160;&#160; var accelerometerReadings = <font style="background-color: #ffff00">dl.Readings();</font></font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160;&#160; var x0 = (double)ellipse1.GetValue(Canvas.TopProperty) + ellipse1.Width / 2;        <br />&#160;&#160;&#160;&#160; var y0 = (double)ellipse1.GetValue(Canvas.LeftProperty) + ellipse1.Height / 2;</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160; // snip </font></p>    <p><font face="Lucida Sans Typewriter">}</font></p> </blockquote>  <p>The Readings method of DataLoader provides an IObservable collection. For this example the collection represents actual accelerometer readings that have been saved to isolated storage. However this is not a requirement; the events could also represent synthetic data. As long as the information used by the RxLINQ queries is there (in this case the X and Y accelerations, as well as the timestamps) the events could be synthetic, as well as recordings of sensor readings. Here’s the DataLoader class:</p>  <blockquote>   <p><font face="Lucida Sans Typewriter">public class DataLoader        <br />{         <br />&#160;&#160;&#160; private IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();         <br />&#160;&#160;&#160; private Stream stream;         <br />&#160;&#160;&#160; private StreamReader reader;         <br />&#160;&#160;&#160; private const string FileName = &quot;accelerations.txt&quot;;</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160; public DataLoader()        <br />&#160;&#160;&#160; {         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; stream = App.GetResourceStream(new Uri(FileName, UriKind.Relative)).Stream;         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; reader = new StreamReader(stream);         <br />&#160;&#160;&#160; }</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160; public IObservable&lt;AccelerometerReading&gt; Readings()        <br />&#160;&#160;&#160; {</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Read saved data into a list (IEnumerable)        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var readings = new List&lt;AccelerometerReading&gt;();         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; </font><font style="background-color: #ffc000" face="Lucida Sans Typewriter">for (var line = reader.ReadLine(); line != null; line = reader.ReadLine())        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; readings.Add(new AccelerometerReading(line));</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Convert the IEnumerable into IObservable        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var rs = <font style="background-color: #00ff00">readings.ToObservable</font>(<font style="background-color: #9bbb59">Scheduler.NewThread</font>);</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Sync via Thread.Sleep on a different thread        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return rs.</font><font face="Lucida Sans Typewriter"><font style="background-color: #cccccc">Zip(rs.Skip(1), (l, r) =&gt;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {           <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Thread.Sleep(TimeSpan.FromTicks(r.Timestamp.Ticks - l.Timestamp.Ticks));           <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return r;           <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; })</font>.<font style="background-color: #9c85c0">ObserveOnDispatcher()</font>;         <br />&#160;&#160;&#160; }         <br />}         <br /></font></p> </blockquote>  <p>The Readings() method populates a List&lt;AccelerometerReading&gt; with AccelerometerReading objects which have been <font style="background-color: #ffc000">read from a text file</font>. RxLINQ adds the ToObservable extension method to IEnumerable such that once read, the list of recorded readings <font style="background-color: #00ff00">can be converted into an observable collection</font>. The argument signals that the conversion should take place on a different thread, leaving the main thread for UI updates.</p>  <p>Sensor readings have a temporal element; if the code would blindly dole out readings from the IEnumerable then the query computing the motion (which used time deltas) will produce garbage. Consequently, after emitting an event, the code needs to wait until it is time to emit the next event. RxLINQ comes again to the rescue. First, <font style="background-color: #cccccc">the combination of Zip and Skip allows the code to Sleep between two consecutive events</font>. (As <font style="background-color: #9bbb59">this computation takes place on a different thread</font> the Sleep doesn’t interfere with the UI thread.) Second, <font style="background-color: #9c85c0">ObserveOnDispatcher()</font> brings the (now temporally-spaced) events to the main thread, which is where the accelerometer events show up when using the actual sensor.</p>  <p>AccelerometerReading is a helper class that simplifies storing the accelerometer events by capturing only the X/Y/Z readings and the Timestamp in ticks. Here’s the code:</p>  <blockquote>   <p><font face="Lucida Sans Typewriter">public class AccelerometerReading        <br />&#160;&#160;&#160; {         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public DateTimeOffset Timestamp { get; set; }         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public double X { get; set; }         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public double Y { get; set; }         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public double Z { get; set; }</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160;&#160;&#160;&#160;&#160; public AccelerometerReading()        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160;&#160;&#160;&#160;&#160; public AccelerometerReading(AccelerometerReadingEventArgs ea)        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Timestamp = ea.Timestamp;         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; X = ea.X;         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Y = ea.Y;         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Z = ea.Z;         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</font></p>    <p><font face="Lucida Sans Typewriter">&#160;&#160;&#160;&#160;&#160;&#160;&#160; public AccelerometerReading(string line)        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var elements = line.Split(';');         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (elements.Length == 4)         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Timestamp = new DateTimeOffset(new DateTime(long.Parse(elements[0])));         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; X = Double.Parse(elements[1]);         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Y = Double.Parse(elements[2]);         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Z = Double.Parse(elements[3]);         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }         <br />&#160;&#160;&#160; }</font></p> </blockquote>  <p>For completeness here’s a sample from the contents of the accelerations.txt file:</p>  <blockquote>   <p><font face="Lucida Sans Typewriter">634262369734340000;0.00390625;-0.01171875;-1.02734375        <br />634262369734550000;0.0078125;-0.01171875;-1.04296875         <br />634262369734790000;0.00390625;-0.00390625;-1.03125         <br />634262369735000000;0.00390625;-0.0078125;-1.03125         <br />634262369735210000;-0.00390625;-0.00390625;-1.03125         <br />634262369735440000;0.00390625;-0.0078125;-1.03125         <br />634262369735660000;-0.00390625;-0.00390625;-1.0390625         <br />634262369735870000;0.00390625;0.0078125;-1.03515625         <br />634262369736100000;0.00390625;-0.00390625;-1.03125         <br />634262369736310000;0.00390625;0;-1.02734375         <br />634262369736540000;0;-0.00390625;-1.0390625         <br />634262369736750000;0;0;-1.0390625         <br />634262369736960000;0;0;-1.03125         <br />634262369737170000;-0.00390625;0.00390625;-1.0234375         <br />634262369737380000;-0.00390625;0.00390625;-1.0234375         <br />634262369737610000;0;0.00390625;-1.02734375         <br />634262369737830000;0;-0.00390625;-1.05078125         <br />634262369738040000;-0.00390625;0.00390625;-1.03125         <br />634262369738260000;0.00390625;0.0078125;-1.0234375         <br />634262369738470000;0.00390625;0.0078125;-1.01953125         <br />634262369738680000;0;0.0078125;-1.0234375         <br />634262369738890000;0;0.00390625;-1.03125         <br />634262369739100000;0.00390625;0.0078125;-1.0234375         <br />634262369739310000;0.0078125;0.0078125;-1.0234375</font></p> </blockquote>  <p>In summary, this blog post has shown:</p>  <ul>   <li>How to mock an IObservable (i.e., event stream) with an IEnumerable by leveraging the IObservable/IEnumerable duality, </li>    <li>How to read application data from isolated storage, and </li>    <li>How to reconstruct the temporal dimension of sensory data with RxLINQ combinators. (There are other ways of implementing the temporal spacing; for now the combination of Zip and Skip reinforces a pattern I used in previous posts.) </li> </ul>]]></content:encoded>
    </item>
    <item>
      <title>WP7 Code: Using the Accelerometer API</title>
      <link>https://docs.microsoft.com/archive/blogs/dragoman/wp7-code-using-the-accelerometer-api</link>
      <pubDate>Mon, 01 Nov 2010 22:23:32 GMT</pubDate>
      <dc:creator><![CDATA[Dragos Manolescu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dragoman/2010/11/01/wp7-code-using-the-accelerometer-api/</guid>
      <description><![CDATA[&#160;  My previous&#160; blog posts on WP7 Code covered the GeoLocation API, a surface area that...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>My previous&#160; blog posts on WP7 Code covered the GeoLocation API, a surface area that provides access to the phone’s location based on signals picked up by one of its radios. However location alone is probably not sufficient for mobile applications. This post shows how to take Windows Phone 7 applications beyond location and enable them to use additional data provided by another onboard sensor, the accelerometer.</p>  <p>The accelerometer is exposed in the <a href="https://msdn.microsoft.com/en-us/library/microsoft.devices.sensors(v=VS.92).aspx">Microsoft.Devices.Sensors</a> namespace, and packaged in the DLL with the same name. As in the previous posts a simple application showcases the API, with the emphasis on the phone-specific aspects rather than C#/Silverlight/robustness/etc. This application looks like a bubble level. Just like I said in the past, while this code runs out of the box please don’t build a navigation system on it <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/1031.wlEmoticon-winkingsmile_59F0B7AA.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/1031.wlEmoticon_2D00_winkingsmile_5F00_59F0B7AA.png" /></p>  <p>Start Visual Studio (with the Windows Phone Development Tools installed) and create a new Windows Phone Application called TiltMe. Add references to Microsoft.Devices.Sensors (for the accelerometer API), and to Microsoft.Phone.Reactive and System.Observable (for RxLINQ)—the event-driven code is implemented as Rx queries. In the tradition of a utilitarian UX add the following code (highlighted) to MainPage.xaml:</p>  <blockquote>   <p>&lt;Grid x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&quot;&gt;     <br /><font style="background-color: #ffff00">&#160;&#160;&#160; &lt;Canvas Height=&quot;607&quot; HorizontalAlignment=&quot;Left&quot; Name=&quot;canvas1&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;456&quot;&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Ellipse Height=&quot;40&quot; Width=&quot;40&quot; Name=&quot;ellipse1&quot;&gt;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Ellipse.Fill&gt;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;RadialGradientBrush&gt;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;GradientStop Color=&quot;Black&quot; Offset=&quot;1&quot; /&gt;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;GradientStop Color=&quot;#FFE41717&quot; Offset=&quot;0.169&quot; /&gt;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;GradientStop Color=&quot;#FF851212&quot; Offset=&quot;0.808&quot; /&gt;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/RadialGradientBrush&gt;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/Ellipse.Fill&gt;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/Ellipse&gt;        <br /></font>&#160;&#160;&#160; &lt;/Canvas&gt;      <br />&lt;/Grid&gt;      <br /></p> </blockquote>  <p>The MainPage class holds the accelerometer reference in an instance variable, which gets created in the constructor. Similar to the GeoCoordinateWatcher, the page code starts the accelerometer when the page is navigated to (first override), and stops it when the page is navigated away from (second override). Stopping the sensor when it is not needed reduces the application’s power consumption, an aspect critical to battery-powered code. Don’t forget the using statement for the accelerometer’s namespace.</p>  <blockquote>   <p>public partial class MainPage : PhoneApplicationPage     <br />{      <br />&#160;&#160;&#160; private Accelerometer accelerometer;</p>    <p>&#160;&#160;&#160; // Constructor     <br />&#160;&#160;&#160; public MainPage()      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; InitializeComponent();</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; accelerometer = new Accelerometer();</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.Loaded += new RoutedEventHandler(MainPage_Loaded);     <br />&#160;&#160;&#160; }</p>    <p>&#160;&#160;&#160; protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedTo(e);</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; accelerometer.Start();     <br />&#160;&#160;&#160; }</p>    <p>&#160;&#160;&#160; protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedFrom(e);</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; accelerometer.Stop();     <br />&#160;&#160;&#160; }</p>    <p>&#160;&#160;&#160; // snip     <br />}      <br /></p> </blockquote>  <p>Accelerometer readings surface as <a href="https://msdn.microsoft.com/en-us/library/microsoft.devices.sensors.accelerometer.readingchanged(v=VS.92).aspx">ReadingChanged</a> events. The following extension method exposes AccelerometerReadingEventArgs as an Rx event stream (don’t forget the using statement for the Microsoft.Phone.Reactive namespace):</p>  <blockquote>   <p>public static IObservable&lt;AccelerometerReadingEventArgs&gt; GetAccEventStream(this Accelerometer accelerometer)     <br />{      <br />&#160;&#160;&#160; return Observable.Create&lt;AccelerometerReadingEventArgs&gt;(observer =&gt;      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventHandler&lt;AccelerometerReadingEventArgs&gt; handler = (s, e) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observer.OnNext(e);</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; };     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; accelerometer.ReadingChanged += handler;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { accelerometer.ReadingChanged -= handler; };      <br />&#160;&#160;&#160; });      <br />}      <br /></p> </blockquote>  <p>To illustrate the accelerometer readings the application shows a sphere (i.e., ellipse with gradient fill) that “falls” towards the edge of the canvas, following the phone’s orientation—2D bubble level. To avoid interfering with the startup path (and thus remove the risk of having the application being perceived as non-responsive) the code connecting the accelerometer to the sphere lies in the event handler for the page loaded even rather than the page’s constructor. It begins with a query representing the accelerometer event stream, and computations for the sphere’s initial position (modified code shown highlighted):</p>  <blockquote>   <p>public MainPage()     <br />{      <br />&#160;&#160;&#160; InitializeComponent();</p>    <p>&#160;&#160;&#160; accelerometer = new Accelerometer();</p>    <p>&#160;&#160;&#160; <font style="background-color: #ffff00">this.Loaded += new RoutedEventHandler(MainPage_Loaded);       <br /></font>}</p>    <p>     <br />void MainPage_Loaded(object sender, RoutedEventArgs e)      <br />{</p>    <p>&#160;&#160;&#160; var accelerometerReadings = accelerometer.GetAccEventStream();</p>    <p>&#160;&#160;&#160; var x0 = (double)ellipse1.GetValue(Canvas.TopProperty) + ellipse1.Width / 2;     <br />&#160;&#160;&#160; var y0 = (double)ellipse1.GetValue(Canvas.LeftProperty) + ellipse1.Height / 2;</p>    <p>}     <br /></p> </blockquote>  <p>The sphere’s initial position, accelerometer events (which provide readings in the 3 XYZ dimensions as well as the timestamp) plugged into the laws of motion provide all the ingredients for this simple application. (A physics engine would offer a more realistic interaction; that is left as an exercise to the reader.) Before showing the Rx queries here are a few things that simplify matters. First, an Interval class whose Clip method bounds a value between the interval’s minimum and maximum. Second an extension method that allows the code to position an ellipse by providing its center. Here they are, with the extension method going into the Helpers static class:</p>  <blockquote>   <p>public class Interval     <br />{      <br />&#160;&#160;&#160; public double Min { get; private set; }      <br />&#160;&#160;&#160; public double Max { get; private set; }</p>    <p>&#160;&#160;&#160; public Interval(double min, double max)     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; Min = min;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; Max = max;      <br />&#160;&#160;&#160; }</p>    <p>&#160;&#160;&#160; public double Clip(double value)      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (value &gt;= Max)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Max;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (value &lt;= Min)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Min;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return value;      <br />&#160;&#160;&#160; }      <br />}      <br /></p>    <p>public static void SetCenter(this Ellipse ellipse, Point c)     <br />{      <br />&#160;&#160;&#160; ellipse.SetValue(Canvas.LeftProperty,c.X - ellipse.Width / 2);      <br />&#160;&#160;&#160; ellipse.SetValue(Canvas.TopProperty, c.Y - ellipse.Height / 2);      <br />}      <br /></p> </blockquote>  <p>With the ability to clip (such that the sphere doesn’t go off screen) and position the sphere, Rx queries implement the (simplified) calculation. The first query projects the stream of AccelerometerReadingEventArgs into a stream of objects with X, Y, and Z members having the values provided by the accelerometer, and the dt member representing the delta (in milliseconds) between the last 2 accelerometer readings. This is implemented via the <a href="https://msdn.microsoft.com/en-us/library/ff707814(v=VS.92).aspx">Zip</a> and <a href="https://msdn.microsoft.com/en-us/library/ff707320(v=VS.92).aspx">Skip</a> combinators; <a href="https://msdn.microsoft.com/en-us/library/ff708114(v=VS.92).aspx">ObserveOnDispatcher</a> ensures that further manipulations of the resulting IObservable stream happen on the UI thread.</p>  <blockquote>   <p>var accelerationAndDts = accelerometerReadings.Zip(accelerometerReadings.Skip(1), (p, c) =&gt;     <br />&#160;&#160;&#160; new { X = c.X, Y = - c.Y, Z = c.Z, dt = (c.Timestamp.Subtract(p.Timestamp)).TotalMilliseconds }).ObserveOnDispatcher();</p> </blockquote>  <p>The next query uses the acceleration (X and Y) and dts as well as the sphere’s current coordinates to compute its next position. The <a href="https://msdn.microsoft.com/en-us/library/ff708056(v=VS.92).aspx">Scan</a> combinator injects the initial coordinates into the computation, and then carries it over subsequent events. (In Smalltalk this corresponds to the inject:into: message.)</p>  <blockquote>   <p>var xclip = new Interval(0, canvas1.Width);     <br />var yclip = new Interval(0, canvas1.Height); </p>    <p>var positions = accelerationAndDts.Scan(new Point(x0,y0)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , (pos, acc) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; new Point( xclip.Clip(pos.X + acc.X * 0.5 * acc.dt * acc.dt)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , yclip.Clip(pos.Y + acc.Y * 0.5 * acc.dt * acc.dt)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; )      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );      <br /></p> </blockquote>  <p>The resulting stream of positions is suitable for positioning the sphere; the SetCenter extension method introduced above makes the code pretty compact:</p>  <blockquote>   <p>positions.Subscribe(c =&gt; this.ellipse1.SetCenter(c));</p> </blockquote>  <p>Before showing the code let’s have a look at how the raw data might look like. Here are 256 consecutive readings (X and Y), with the device laying flat on my desk. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/3681.image_396977F8.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/3681.image_5F00_396977F8.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/3187.image_thumb_591851C0.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/3187.image_5F00_thumb_5F00_591851C0.png" width="477" height="288" /></a></p>  <p>With the caveat that this data comes from an engineering prototype rather than a production device, here are a few things to note:</p>  <ul>   <li>First, on this particular device the accelerometer is not calibrated. There are offset errors in both the X and Y dimensions, both of which could be eliminated via calibration.</li>    <li>Second, the raw sensor data has some jitter, which is probably a combination of vibrations picked up by my desk and other types of noise. Depending on your application a smoothing filter could take out the unwanted jitter.</li> </ul>  <p>The full code from MainPage.xaml.cs follows; building and running this application requires the XAML for the UI, and the Interval class shown above.</p>  <blockquote>   <p>namespace TiltMe     <br />{      <br />&#160;&#160;&#160; public partial class MainPage : PhoneApplicationPage      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; private Accelerometer accelerometer;</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Constructor     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public MainPage()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InitializeComponent();</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; accelerometer = new Accelerometer();</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.Loaded += new RoutedEventHandler(MainPage_Loaded);     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedTo(e);</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; accelerometer.Start();     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedFrom(e);</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; accelerometer.Stop();     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; void MainPage_Loaded(object sender, RoutedEventArgs e)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var accelerometerReadings = accelerometer.GetAccEventStream();</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var x0 = (double)ellipse1.GetValue(Canvas.TopProperty) + ellipse1.Width / 2;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var y0 = (double)ellipse1.GetValue(Canvas.LeftProperty) + ellipse1.Height / 2;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var accelerationAndDts = accelerometerReadings.Zip(accelerometerReadings.Skip(1), (p, c) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; new { X = c.X, Y = - c.Y, Z = c.Z, dt = (c.Timestamp.Subtract(p.Timestamp)).TotalMilliseconds }).ObserveOnDispatcher();</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var xclip = new Interval(0, canvas1.Width);     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var yclip = new Interval(0, canvas1.Height);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var positions = accelerationAndDts.Scan(new Point(x0,y0)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , (pos, acc) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; new Point( xclip.Clip(pos.X + acc.X * 0.5 * acc.dt * acc.dt)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , yclip.Clip(pos.Y + acc.Y * 0.5 * acc.dt * acc.dt)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; )      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; positions.Subscribe(c =&gt; this.ellipse1.SetCenter(c));     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160; }</p>    <p>&#160;&#160;&#160; public static class Helpers     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static IObservable&lt;AccelerometerReadingEventArgs&gt; GetAccEventStream(this Accelerometer accelerometer)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Observable.Create&lt;AccelerometerReadingEventArgs&gt;(observer =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventHandler&lt;AccelerometerReadingEventArgs&gt; handler = (s, e) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observer.OnNext(e);</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; accelerometer.ReadingChanged += handler;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { accelerometer.ReadingChanged -= handler; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static void SetCenter(this Ellipse ellipse, Point c)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ellipse.SetValue(Canvas.LeftProperty,c.X - ellipse.Width / 2);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ellipse.SetValue(Canvas.TopProperty, c.Y - ellipse.Height / 2);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160; }</p> </blockquote>  <p>In summary, this blog post has shown:</p>  <ul>   <li>How to get started with the Windows Phone Accelerometer API,</li>    <li>How to bring the accelerometer’s ReadingChanged event into the realm of Rx, and use the corresponding event stream in Rx queries, and</li>    <li>How to drive a canvas element based on accelerometer readings.</li> </ul>  <p>Perhaps a short video showing the application in action would help? Let me know…</p>]]></content:encoded>
    </item>
    <item>
      <title>WP7 Code: Managing Application State</title>
      <link>https://docs.microsoft.com/archive/blogs/dragoman/wp7-code-managing-application-state</link>
      <pubDate>Tue, 26 Oct 2010 23:02:30 GMT</pubDate>
      <dc:creator><![CDATA[Dragos Manolescu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dragoman/2010/10/26/wp7-code-managing-application-state/</guid>
      <description><![CDATA[&#160;  Visual Studio and the Windows Phone Developer Tools make building software for the Windows...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>Visual Studio and the Windows Phone Developer Tools make building software for the Windows Phone similar to building desktop or browser applications. However, beyond these similarities crafting a phone application differs fundamentally from building an application aimed at a device with a keyboard, large screen, running on AC power, and with reliable network connectivity (to name just a few differences). Mobile device users are less likely to tolerate applications that demand too much of their attention, such as taking too much time to display information or to respond to actions. Consequently developers rely on techniques that make their applications provide a good experience. </p>  <p>This post shows how to extend the <a href="https://blogs.msdn.com/b/dragoman/archive/2010/10/13/wp7-code-geofencing-with-the-geolocation-api-and-rx.aspx">GeoFencing application</a> to <a href="https://msdn.microsoft.com/en-us/library/ff967547(v=VS.92).aspx">save and restore application state</a>. Doing so in applications that need time to initialize can lower their launch time, one of the first thing their users will notice. The application state for the GeoFencing application comprises the perimeter’s center and radius. Preserving them across invocations allows the application to display information before acquiring a location fix (which, depending on the environment, could take a while). In addition to improving the perceived responsiveness storing the information about the perimeter also offers a better experience, allowing users to leave the application and then restart it without dropping the data.</p>  <p>Start by adding to the project a class representing the saved perimeter data (make sure you reference the System.Runtime.Serialization.dll which holds the namespace with the same name):</p>  <blockquote>   <p>using System.Device.Location;     <br />using System.Runtime.Serialization; </p>    <p>namespace GeoFencing     <br />{      <br />&#160;&#160;&#160; [DataContract]      <br />&#160;&#160;&#160; public class PersistentRecord      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; [DataMember]      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public GeoCoordinate PerimeterCenter { get; set; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; [DataMember]      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public double PerimeterRadius { get; set; }      <br />&#160;&#160;&#160; }      <br />}</p> </blockquote>  <p>For this example I chose simple XML serialization—probably not a good choice if you’re dealing with lots of data and/or blobs.</p>  <p>Add a static property to the App class for holding the perimeter data. Next extend the Application_Activated, Application_Deactivated, and Application_Closing default implementations (template method) to load from/save to the <a href="https://msdn.microsoft.com/en-us/library/microsoft.phone.shell.phoneapplicationservice(v=VS.92).aspx">PhoneApplicationService</a>’s dictionary (to be picked up by a tombstoned application instance), or save it to the application’s isolated storage (to be picked up by a new application instance). The SavePersistentData method does all the work involving isolated storage.</p>  <blockquote>   <p>// Code to execute when the application is launching (eg, from Start)     <br />// This code will not execute when the application is reactivated      <br />private void Application_Launching(object sender, LaunchingEventArgs e)      <br />{      <br />} </p>    <p>// Code to execute when the application is activated (brought to foreground)     <br />// This code will not execute when the application is first launched      <br />private void Application_Activated(object sender, ActivatedEventArgs e)      <br />{      <br />&#160;&#160;&#160; if (PhoneApplicationService.Current.State.ContainsKey(&quot;GeoFencing&quot;))      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; State = (PersistentRecord)PhoneApplicationService.Current.State[&quot;GeoFencing&quot;];      <br />&#160;&#160;&#160; }      <br />} </p>    <p>// Code to execute when the application is deactivated (sent to background)     <br />// This code will not execute when the application is closing      <br />private void Application_Deactivated(object sender, DeactivatedEventArgs e)      <br />{      <br />&#160;&#160;&#160; if (State != null)      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; PhoneApplicationService.Current.State[&quot;GeoFencing&quot;] = State;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; SavePersistentData();      <br />&#160;&#160;&#160; }      <br />} </p>    <p>// Code to execute when the application is closing (eg, user hit Back)     <br />// This code will not execute when the application is deactivated      <br />private void Application_Closing(object sender, ClosingEventArgs e)      <br />{      <br />&#160;&#160;&#160; if (State != null)      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; SavePersistentData();      <br />&#160;&#160;&#160; }      <br />} </p>    <p>public static PersistentRecord State { get; set; } </p>    <p>private static void SavePersistentData()     <br />{      <br />&#160;&#160;&#160; using (var store = IsolatedStorageFile.GetUserStoreForApplication())      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; using (var stream = store.CreateFile(&quot;center.dat&quot;))      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var serializer = new DataContractSerializer(typeof(PersistentRecord));      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; serializer.WriteObject(stream, State);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160; }      <br />} </p> </blockquote>  <p>Note that the default implementation of Application_Launching stays the same (do nothing). Application_Launching is on the critical path for startup. Consequently file I/O +deserialization (or anything else that has the potential of slowing down launch times) doesn’t belong there. An asynchronous invocation (hint: Rx) from the MainPage ctor is a better alternative. First here’s the method that reads the saved information from isolated storage (App class). While it won’t win any robustness awards (that’s left as an exercise for the reader) it does illustrate the point.</p>  <blockquote>   <p>public static bool TryReadState(out PersistentRecord savedState)     <br />{      <br />&#160;&#160;&#160; using (var store = IsolatedStorageFile.GetUserStoreForApplication())      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; IsolatedStorageFileStream stream = null;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; savedState = default(PersistentRecord);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; try      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (store.FileExists(&quot;center.dat&quot;))      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; using (stream = store.OpenFile(&quot;center.dat&quot;, System.IO.FileMode.Open))      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var serializer = new DataContractSerializer(typeof(PersistentRecord));      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; savedState = (PersistentRecord)serializer.ReadObject(stream);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return (true);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (System.IO.IOException)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // swallow      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (System.IO.IsolatedStorage.IsolatedStorageException)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // swallow      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (SerializationException)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; store.DeleteFile(&quot;center.dat&quot;);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return false;      <br />&#160;&#160;&#160; }      <br />}</p> </blockquote>  <p>The final updates to the MainPage.xaml.cs enable it to read and use the saved perimeter information. The following Rx query (placed after InitializeComponent) surfaces the saved state as an IObservable&lt;PersistentRecord&gt;. The <a href="https://msdn.microsoft.com/en-us/library/ff708144(v=VS.92).aspx">Start</a> method invokes TryReadState asynchronously ,and <a href="https://msdn.microsoft.com/en-us/library/ff708114(v=VS.92).aspx">ObserveOnDispatcher</a> brings the events into the main (UI) thread. As there is at most one persistent record Take(1) drops everything else after that.</p>  <blockquote>   <p>var savedStates = Observable.Start(() =&gt;     <br />{      <br />&#160;&#160;&#160; if (App.State != null)      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return App.State;      <br />&#160;&#160;&#160; }      <br />&#160;&#160;&#160; else      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; PersistentRecord savedState;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var isOk = App.TryReadState(out savedState);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return isOk ? savedState : default(PersistentRecord);      <br />&#160;&#160;&#160; }      <br />}).Where(e =&gt; e != null).ObserveOnDispatcher().Take(1);</p> </blockquote>  <p>The next change entails merging the stream corresponding to the radius position with the restored value provided by the App instance (either from the PhoneApplicationService or isolated storage):</p>  <blockquote>   <p>var radii = this.slider1.GetValueChangedEventStream().Select(e =&gt; e.NewValue).StartWith(50)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .Merge(savedStates.Select(s =&gt; s.PerimeterRadius));</p> </blockquote>  <p>When either the perimeter’s center or radius change (via user input) a new PersistentRecord instance is set on the App object. The <a href="https://msdn.microsoft.com/en-us/library/ff707745(v=VS.92).aspx">CombineLatest</a> combinator provides an elegant solution for this:</p>  <blockquote>   <p>centers.CombineLatest(radii, (l, r) =&gt; new { Center = l, Radius = r }).Subscribe(crs =&gt;     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; App.State = new PersistentRecord { PerimeterCenter = crs.Center      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , PerimeterRadius = crs.Radius      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };      <br />&#160;&#160;&#160; });</p> </blockquote>  <p>The subsequent UI updates and distance computations (Rx queries) must use either the saved value or, upon the arrival of the first reading, the values from the geolocation subsystem. The <a href="https://msdn.microsoft.com/en-us/library/ff708294(v=VS.92).aspx">TakeUntil</a> combinator passes through the saved information until the arrival of the first center setting, extracted via the <a href="https://msdn.microsoft.com/en-us/library/ff707867(v=VS.92).aspx">Select</a> combinator :</p>  <blockquote>   <p>var savedOrAcquiredCenters = centers.Publish(cs =&gt; cs.Merge(savedStates.Select(s =&gt; s.PerimeterCenter).TakeUntil(cs))); </p> </blockquote>  <p>The code for MainPage.xaml.cs follows. Building and running the application requires the XAML for the UI, as well as the App. xaml.cs and the PersistentRecord class.</p>  <blockquote>   <p>public partial class MainPage : PhoneApplicationPage     <br />{      <br />&#160;&#160;&#160; private GeoCoordinateWatcher gcw;      <br />&#160;&#160;&#160; public GeoCoordinateWatcher Gcw      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; get      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (gcw == null)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw = new GeoCoordinateWatcher { MovementThreshold = 0.0 };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return gcw;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160; // Constructor     <br />&#160;&#160;&#160; public MainPage()      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; InitializeComponent();&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; geoFenceButton.IsEnabled = false;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; slider1.IsEnabled = false; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var savedStates = Observable.Start(() =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (App.State != null)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return App.State;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; PersistentRecord savedState;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var isOk = App.TryReadState(out savedState);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return isOk ? savedState : default(PersistentRecord);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }).Where(e =&gt; e != null).ObserveOnDispatcher().Take(1); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var positionUpdates = from sc in Gcw.GetStatusChangedEventStream()     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where sc.Status == GeoPositionStatus.Ready      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from pos in Gcw.GetPositionChangedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; let location = pos.Position.Location      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where (!Double.IsNaN(location.Latitude) &amp;&amp; !Double.IsNaN(location.Longitude) &amp;&amp; location.HorizontalAccuracy &lt;= 100.0)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select location; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; positionUpdates.Take(1).Subscribe(_ =&gt; geoFenceButton.IsEnabled = true); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; positionUpdates.Subscribe(l =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.hereTextBlock.Text = string.Format( &quot;{0:###.00000000N;###.00000000S;0}, {1:###.00000000E;###.00000000W;0}&quot;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , l.Latitude      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , l.Longitude      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var clicks = this.geoFenceButton.GetClickEventStream(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; clicks.Take(1).Subscribe(_ =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.slider1.IsEnabled = true;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var centers = positionUpdates.Publish(updates =&gt; from position in updates     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from click in clicks.Take(1).TakeUntil(updates)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var radii = this.slider1.GetValueChangedEventStream().Select(e =&gt; e.NewValue).StartWith(50)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .Merge(savedStates.Select(s =&gt; s.PerimeterRadius)); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; centers.CombineLatest(radii, (l, r) =&gt; new { Center = l, Radius = r }).Subscribe(crs =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; App.State = new PersistentRecord { PerimeterCenter = crs.Center      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , PerimeterRadius = crs.Radius      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var savedOrAcquiredCenters = centers.Publish(cs =&gt; cs.Merge(savedStates.Select(s =&gt; s.PerimeterCenter).TakeUntil(cs))); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; savedOrAcquiredCenters.Subscribe(center =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; centerTextBlock.Text = string.Format(&quot;{0:###.00000000N;###.00000000S;0}, {1:###.00000000E;###.00000000W;0}&quot;, center.Latitude, center.Longitude);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; radii.Take(2).Subscribe(r =&gt; this.slider1.Value = r); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; radii.Subscribe(radius =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.fenceTextBlock.Text = string.Format(&quot;Perimeter radius {0:####.00}m&quot;,radius);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var distancesFromCenter = positionUpdates.CombineLatest(savedOrAcquiredCenters, (p, c) =&gt; p.GetDistanceTo(c)).DistinctUntilChanged(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var distancesToFence = distancesFromCenter.CombineLatest(this.slider1.GetValueChangedEventStream(), (d, radius) =&gt; radius.NewValue - d);     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; distancesToFence.Subscribe(distanceToFence =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var msg = string.Empty;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (distanceToFence &gt;= 0)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = string.Format(&quot;{0:####.00}m from the fence&quot;, this.slider1.Value - distanceToFence);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; distanceTextBlock.Foreground = new SolidColorBrush(Colors.Green);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = string.Format(&quot;{0:####.00}m outside the fenced perimeter&quot;, Math.Abs(distanceToFence));      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; distanceTextBlock.Foreground = new SolidColorBrush(Colors.Red);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.distanceTextBlock.Text = msg;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });      <br />&#160;&#160;&#160; }</p> </blockquote>  <p>In summary, this post has shown:</p>  <ul>   <li>How to tap into the application’s lifecycle via the methods exposed by the App class </li>    <li>How to use Observable.Start to asynchronously execute an Action, and bring the results to the UI thread with ObserveOnDispatcher</li>    <li>How to leverage Rx to combine events from several event streams</li> </ul>]]></content:encoded>
    </item>
    <item>
      <title>WP7 Code: Geofencing with the GeoLocation API and Rx</title>
      <link>https://docs.microsoft.com/archive/blogs/dragoman/wp7-code-geofencing-with-the-geolocation-api-and-rx</link>
      <pubDate>Wed, 13 Oct 2010 18:48:00 GMT</pubDate>
      <dc:creator><![CDATA[Dragos Manolescu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dragoman/2010/10/13/wp7-code-geofencing-with-the-geolocation-api-and-rx/</guid>
      <description><![CDATA[&#160;  Besides providing geographical coordinates, computing distances, and making reverse...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>Besides <a href="https://blogs.msdn.com/b/dragoman/archive/2010/09/21/wp7-code-using-the-geolocation-api.aspx">providing geographical coordinates</a>, <a href="https://blogs.msdn.com/b/dragoman/archive/2010/09/29/wp7-code-distance-computations-with-the-geolocation-api.aspx">computing distances</a>, and <a href="https://blogs.msdn.com/b/dragoman/archive/2010/10/07/wp7-code-reverse-geocoding-with-the-bing-maps-service.aspx">making reverse geocoding service requests</a> Windows Phone 7 can also signal when it is moved outside of a perimeter. The buzzword for this scenario is <a href="en.wikipedia.org/wiki/Geofencing">Geofencing</a>, and this post shows how to implement it (when the geofence is circular) with the WP7 GeoLocation API and Rx.</p>  <p>An utilitarian UI will do just fine for a first exploration of geofencing. The UI starts from the default Windows Phone Application template and adds 6 textblocks (some of which are static labels), a slider, and a button inside the ContentPanel. The code follows below, with the portion added to the default template in green:</p>  <blockquote>   <p>&lt;Grid x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&quot;&gt;     <br /><font color="#008000">&#160;&#160;&#160; &lt;TextBlock Height=&quot;54&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;14,38,0,0&quot; Name=&quot;textBlock1&quot; Text=&quot;Here&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;426&quot; /&gt;       <br />&#160;&#160;&#160; &lt;TextBlock Height=&quot;54&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;14,98,0,0&quot; Name=&quot;hereTextBlock&quot; Text=&quot;(none)&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;426&quot; /&gt;        <br />&#160;&#160;&#160; &lt;TextBlock Height=&quot;54&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;14,158,0,0&quot; Name=&quot;textBlock3&quot; Text=&quot;Perimeter center&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;426&quot; /&gt;        <br />&#160;&#160;&#160; &lt;TextBlock Height=&quot;54&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;14,218,0,0&quot; Name=&quot;centerTextBlock&quot; Text=&quot;(none)&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;426&quot; /&gt;        <br />&#160;&#160;&#160; &lt;TextBlock Height=&quot;54&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;14,278,0,0&quot; Name=&quot;fenceTextBlock&quot; Text=&quot;Perimeter radius&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;426&quot; /&gt;        <br />&#160;&#160;&#160; &lt;TextBlock Height=&quot;54&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;24,438,0,0&quot; Name=&quot;distanceTextBlock&quot; Text=&quot;(none)&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;426&quot; /&gt;        <br />&#160;&#160;&#160; &lt;Button Content=&quot;Set Center&quot; Height=&quot;90&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;92,515,0,0&quot; Name=&quot;geoFenceButton&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;269&quot; /&gt;        <br />&#160;&#160;&#160; &lt;Slider Height=&quot;101&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;24,308,0,0&quot; Name=&quot;slider1&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;381&quot; Minimum=&quot;10&quot; Maximum=&quot;1000&quot; /&gt;        <br /></font>&lt;/Grid&gt;</p> </blockquote>  <p>Next add references to System.Devices.Sensors (for GeoLocation), and System.Observable and Microsoft.Phone.Reactive (for Rx). I will also be using the GeoLocation library from my previous <a href="https://blogs.msdn.com/b/dragoman/archive/2010/10/07/wp7-code-reverse-geocoding-with-the-bing-maps-service.aspx">post</a> so add a Project reference as well.</p>  <p>For a (slight) change of style I’ll expose the GeoCoordinateWatcher instance as a property of the MainPage class. Here’s the relevant code:</p>  <blockquote>   <p>public partial class MainPage : PhoneApplicationPage     <br />{ </p>    <p><font color="#008000">&#160;&#160;&#160; private GeoCoordinateWatcher gcw;       <br />&#160;&#160;&#160; public GeoCoordinateWatcher Gcw        <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; get        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (gcw == null)        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw = new GeoCoordinateWatcher { MovementThreshold = 10.0 };        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return gcw;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160; }        <br /></font>&#160;&#160;&#160; // snip</p> </blockquote>  <p>The page navigation overrides (To and From) start and stop the geolocation subsystem:</p>  <blockquote>   <p>protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)     <br />{      <br />&#160;&#160;&#160; base.OnNavigatedTo(e); </p>    <p>&#160;&#160;&#160; <font color="#008000">Gcw.Start();       <br /></font>} </p>    <p>protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)     <br />{      <br />&#160;&#160;&#160; base.OnNavigatedFrom(e); </p>    <p>&#160;&#160;&#160; <font color="#008000">Gcw.Stop();       <br /></font>}</p> </blockquote>  <p>The code begins by disabling the button and slider controls. A first Rx query provides a stream of location events by joining the geolocation status changed event stream with the position changed event stream, and filtering out readings with horizaontal accuracy greater than 100m (below). Note that since Rx lazily evaluates the query, building it on the startup critical path (i.e., the MainPage constructor) doesn’t really do anything besides getting the query in place.</p>  <blockquote>   <p>geoFenceButton.IsEnabled = false;     <br />slider1.IsEnabled = false; </p>    <p>var positionUpdates = from sc in Gcw.GetStatusChangedEventStream()     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where sc.Status == GeoPositionStatus.Ready      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from pos in Gcw.GetPositionChangedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; let location = pos.Position.Location      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where (!Double.IsNaN(location.Latitude) &amp;&amp; !Double.IsNaN(location.Longitude) &amp;&amp; location.HorizontalAccuracy &lt;= 100.0)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select location;</p> </blockquote>  <p>As soon as the position updates start trickling in the code enables the button (for the first position update via the Take operator), and displays the current location (lat/long) in the appropriate text box. Here are the subscribers for these event streams:</p>  <blockquote>   <p>positionUpdates.Take(1).Subscribe(_ =&gt; geoFenceButton.IsEnabled = true); </p>    <p>positionUpdates.Subscribe(l =&gt;     <br />{      <br />&#160;&#160;&#160; this.hereTextBlock.Text = string.Format( &quot;{0:###.00000000N;###.00000000S;0}, {1:###.00000000E;###.00000000W;0}&quot;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , l.Latitude      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , l.Longitude      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );      <br />});</p> </blockquote>  <p>Tapping the button causes the application to use the current position as the perimeter’s center—hence enabling the button only after the position becomes available. This requires bringing button Click events into the realm of Rx, and then a query that for each tap pulls the most recent position. The query updates the appropriate text box with the center’s position. The code is below, with the extension method first (put it in a static Helpers class) followed by the event stream code (put it into MainPage). Just like the code above, the first button click event enables additional UI elements—in this case the slider control—and sets their initial value to 50.</p>  <blockquote>   <p>public static IObservable&lt;RoutedEventArgs&gt; GetClickEventStream(this Button button)     <br />{      <br />&#160;&#160;&#160; return Observable.Create&lt;RoutedEventArgs&gt;(observable =&gt;      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; RoutedEventHandler handler = (s, e) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; button.Click += handler;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { button.Click -= handler; };      <br />&#160;&#160;&#160; });      <br />}</p>    <p>var clicks = this.geoFenceButton.GetClickEventStream(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; clicks.Take(1).Subscribe(_ =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.slider1.IsEnabled = true;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.slider1.Value = 50.0;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var centers = positionUpdates.Publish(updates =&gt; from position in updates     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from click in clicks.Take(1).TakeUntil(updates)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; centers.Subscribe(center =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; centerTextBlock.Text = string.Format(&quot;{0:###.00000000N;###.00000000S;0}, {1:###.00000000E;###.00000000W;0}&quot;, center.Latitude, center.Longitude);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );</p> </blockquote>  <p>The slider determines the perimeter’s radius. As with other UI controls such as the button, the events it raises can be used in Rx queries. Here’s the extension method that does the bridging between RoutedPropertyChangedEventArgs&lt;double&gt; and IObservable&lt;RoutedPropertyChangedEventArgs&lt;double&gt;&gt; (and goes in the Helpers class), followed by the code that updates the UI element with the radius selected via the slider (and goes in the MainPage constructor):</p>  <blockquote>   <p>public static IObservable&lt;RoutedPropertyChangedEventArgs&lt;double&gt;&gt; GetValueChangedEventStream(this Slider slider)     <br />{      <br />&#160;&#160;&#160; return Observable.Create&lt;RoutedPropertyChangedEventArgs&lt;double&gt;&gt;(observable =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RoutedPropertyChangedEventHandler&lt;double&gt; handler = (s,e) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; slider.ValueChanged += handler;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { slider.ValueChanged -= handler; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; });      <br />}</p>    <p>var radii = this.slider1.GetValueChangedEventStream(); </p>    <p>radii.Subscribe(radius =&gt;     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.fenceTextBlock.Text = string.Format(&quot;Perimeter radius {0:####.00}m&quot;,radius.NewValue);      <br />&#160;&#160;&#160; });</p> </blockquote>  <p>The last two queries compute the distance from the perimeter’s center, and the distance to the fence. The first query uses the <a href="https://msdn.microsoft.com/en-us/library/ff707745(v=VS.92).aspx">CombineLatest</a> operator to return the (Haversine) distance from the center to the current position. Note that I use the <a href="https://msdn.microsoft.com/en-us/library/system.device.location.geocoordinate.getdistanceto.aspx">GetDistanceTo</a> method rather than the homegrown version shown in the previous posts—thanks for the feedback! The second query computes the distance to the fence by subtracting the latest distance from center from the latest radius value from the slider. The subscriber to this last stream updates the appropriate text box with a message, changing the text color depending on where the current location lies with respect to the fence. Here’s the code:</p>  <blockquote>   <p>var distancesFromCenter = positionUpdates.CombineLatest(centers, (p, c) =&gt; p.GetDistanceTo(c)).DistinctUntilChanged(); </p>    <p>var distancesToFence = distancesFromCenter.CombineLatest(this.slider1.GetValueChangedEventStream(), (d, radius) =&gt; radius.NewValue - d);     <br />distancesToFence.Subscribe(distanceToFence =&gt;      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var msg = string.Empty;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (distanceToFence &gt;= 0)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = string.Format(&quot;{0:####.00}m from the fence&quot;, this.slider1.Value - distanceToFence);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; distanceTextBlock.Foreground = new SolidColorBrush(Colors.Green);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; else      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = string.Format(&quot;{0:####.00}m outside the fenced perimeter&quot;, Math.Abs(distanceToFence));      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; distanceTextBlock.Foreground = new SolidColorBrush(Colors.Red);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.distanceTextBlock.Text = msg;      <br />&#160;&#160;&#160; });</p> </blockquote>  <p>The code for MainPage.xaml.cs follows. To build and run the application you’ll need the XAML as well as the GeoLocation library from my reverse Geocoding post.</p>  <blockquote>   <p>using System;     <br />using System.Windows;      <br />using System.Windows.Controls;      <br />using System.Windows.Media;      <br />using Microsoft.Phone.Controls;      <br />using Microsoft.Phone.Reactive;      <br />using System.Device.Location;      <br />using GeoLocation; </p>    <p>namespace GeoFencing     <br />{      <br />&#160;&#160;&#160; public partial class MainPage : PhoneApplicationPage      <br />&#160;&#160;&#160; { </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; private GeoCoordinateWatcher gcw;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public GeoCoordinateWatcher Gcw      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; get      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (gcw == null)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw = new GeoCoordinateWatcher { MovementThreshold = 10.0 };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return gcw;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; // snip </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Constructor     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public MainPage()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InitializeComponent(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; geoFenceButton.IsEnabled = false;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; slider1.IsEnabled = false; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var positionUpdates = from sc in Gcw.GetStatusChangedEventStream()     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where sc.Status == GeoPositionStatus.Ready      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from pos in Gcw.GetPositionChangedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; let location = pos.Position.Location      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where (!Double.IsNaN(location.Latitude) &amp;&amp; !Double.IsNaN(location.Longitude) &amp;&amp; location.HorizontalAccuracy &lt;= 100.0)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select location; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; positionUpdates.Take(1).Subscribe(_ =&gt; geoFenceButton.IsEnabled = true); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; positionUpdates.Subscribe(l =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.hereTextBlock.Text = string.Format( &quot;{0:###.00000000N;###.00000000S;0}, {1:###.00000000E;###.00000000W;0}&quot;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , l.Latitude      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , l.Longitude      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var clicks = this.geoFenceButton.GetClickEventStream(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; clicks.Take(1).Subscribe(_ =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.slider1.IsEnabled = true;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.slider1.Value = 50.0;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var centers = positionUpdates.Publish(updates =&gt; from position in updates     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from click in clicks.Take(1).TakeUntil(updates)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; centers.Subscribe(center =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; centerTextBlock.Text = string.Format(&quot;{0:###.00000000N;###.00000000S;0}, {1:###.00000000E;###.00000000W;0}&quot;, center.Latitude, center.Longitude);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var radii = this.slider1.GetValueChangedEventStream(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; radii.Subscribe(radius =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.fenceTextBlock.Text = string.Format(&quot;Perimeter radius {0:####.00}m&quot;,radius.NewValue);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var distancesFromCenter = positionUpdates.CombineLatest(centers, (p, c) =&gt; p.GetDistanceTo(c)).DistinctUntilChanged(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var distancesToFence = distancesFromCenter.CombineLatest(this.slider1.GetValueChangedEventStream(), (d, radius) =&gt; radius.NewValue - d);     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; distancesToFence.Subscribe(distanceToFence =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var msg = string.Empty;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (distanceToFence &gt;= 0)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = string.Format(&quot;{0:####.00}m from the fence&quot;, this.slider1.Value - distanceToFence);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; distanceTextBlock.Foreground = new SolidColorBrush(Colors.Green);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = string.Format(&quot;{0:####.00}m outside the fenced perimeter&quot;, Math.Abs(distanceToFence));      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; distanceTextBlock.Foreground = new SolidColorBrush(Colors.Red);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.distanceTextBlock.Text = msg;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedTo(e); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Gcw.Start();     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedFrom(e); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Gcw.Stop();     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>static class Helpers     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static IObservable&lt;RoutedEventArgs&gt; GetClickEventStream(this Button button)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Observable.Create&lt;RoutedEventArgs&gt;(observable =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RoutedEventHandler handler = (s, e) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; button.Click += handler;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { button.Click -= handler; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static IObservable&lt;RoutedPropertyChangedEventArgs&lt;double&gt;&gt; GetValueChangedEventStream(this Slider slider)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Observable.Create&lt;RoutedPropertyChangedEventArgs&lt;double&gt;&gt;(observable =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RoutedPropertyChangedEventHandler&lt;double&gt; handler = (s,e) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; slider.ValueChanged += handler;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { slider.ValueChanged -= handler; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160; }      <br />}</p> </blockquote>  <p>Here’s a screenshot showing the phone within the geofenced perimeter:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/2335.image_6D551064.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/2335.image_5F00_6D551064.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/3718.image_thumb_5A33E3B8.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/3718.image_5F00_thumb_5F00_5A33E3B8.png" width="139" height="240" /></a> </p>  <p>In summary, this post has shown:</p>  <ul>   <li>How to perform computations on two event streams using the CombineLatest operator</li>    <li>How to use Rx with a slider and button control</li>    <li>How to implement geofencing using Windows Phone 7’s geolocation API and Rx queries</li> </ul>]]></content:encoded>
    </item>
    <item>
      <title>WP7 Code: Reverse GeoCoding with the Bing Maps Service</title>
      <link>https://docs.microsoft.com/archive/blogs/dragoman/wp7-code-reverse-geocoding-with-the-bing-maps-service</link>
      <pubDate>Thu, 07 Oct 2010 00:29:33 GMT</pubDate>
      <dc:creator><![CDATA[Dragos Manolescu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dragoman/2010/10/07/wp7-code-reverse-geocoding-with-the-bing-maps-service/</guid>
      <description><![CDATA[&#160;  My previous blog posts showed how to obtain location as an event stream from the Windows...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>My previous blog posts showed how to <a href="https://blogs.msdn.com/b/dragoman/archive/2010/09/21/wp7-code-using-the-geolocation-api.aspx">obtain location as an event stream</a> from the Windows Phone 7 GeoLocation API, and how to <a href="https://blogs.msdn.com/b/dragoman/archive/2010/09/29/wp7-code-distance-computations-with-the-geolocation-api.aspx">translate lat/long position readings into distances.</a> Here I show how to build an application that combines data from the phone’s geolocation subsystem with data from the cloud. In effect it is a data mashup running in your pocket, and powered by a battery :)</p>  <p>I will be (re)using some of the code from the previous applications. As this is their 3rd use it makes sense to pull the common functionality into a class library. Create a new Windows Phone Application project, and then add a Windows Phone Class Library to it. Add the following classes to this library (they require a few additional references that are not included by default):</p>  <blockquote>   <p>using System;      <br />using System.Device.Location;       <br />using Microsoft.Phone.Reactive; </p>    <p>namespace GeoLocation      <br />{       <br />&#160;&#160;&#160; public static class LocationHelpers       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static IObservable&lt;GeoPositionStatusChangedEventArgs&gt; GetStatusChangedEventStream(this GeoCoordinateWatcher watcher)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Observable.Create&lt;GeoPositionStatusChangedEventArgs&gt;(observer =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventHandler&lt;GeoPositionStatusChangedEventArgs&gt; handler = (s, e) =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observer.OnNext(e);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; watcher.StatusChanged += handler;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { watcher.StatusChanged -= handler; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static IObservable&lt;GeoPositionChangedEventArgs&lt;GeoCoordinate&gt;&gt; GetPositionChangedEventStream(this GeoCoordinateWatcher watcher)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Observable.Create&lt;GeoPositionChangedEventArgs&lt;GeoCoordinate&gt;&gt;(observable =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventHandler&lt;GeoPositionChangedEventArgs&lt;GeoCoordinate&gt;&gt; handler = (s, e) =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; watcher.PositionChanged += handler;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { watcher.PositionChanged -= handler; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160; }       <br />}</p> </blockquote>  <p>and</p>  <blockquote>   <p>using System;      <br />using System.Device.Location; </p>    <p>namespace GeoLocation      <br />{       <br />&#160;&#160;&#160; public enum DistanceIn { Miles, Kilometers }; </p>    <p>&#160;&#160;&#160; public static class Haversine      <br />&#160;&#160;&#160; { </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static double Between(this DistanceIn @in, GeoPosition&lt;GeoCoordinate&gt; here, GeoPosition&lt;GeoCoordinate&gt; there)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var r = (@in == DistanceIn.Miles) ? 3960 : 6371;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var dLat = (there.Location.Latitude - here.Location.Latitude).ToRadian();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var dLon = (there.Location.Longitude - here.Location.Longitude).ToRadian();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Math.Cos(here.Location.Latitude.ToRadian()) * Math.Cos(there.Location.Latitude.ToRadian()) *       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Math.Sin(dLon / 2) * Math.Sin(dLon / 2);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var d = r * c;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return d;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; private static double ToRadian(this double val)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return (Math.PI / 180) * val;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160; }       <br />}</p> </blockquote>  <p>Now to the main application code. Just like the previous applications the UI is minimalistic :) Add the following XAML (in green) within the ContentPanel Grid control:</p>  <blockquote>   <p>&lt;!--ContentPanel - place additional content here--&gt;      <br />&lt;Grid x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&quot;&gt;       <br />&#160;&#160;&#160; <font color="#008000">&lt;Button Content=&quot;GeoCode&quot; Height=&quot;72&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;148,519,0,0&quot; Name=&quot;geoCodeButton&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;160&quot; /&gt;        <br />&#160;&#160;&#160; &lt;TextBlock Height=&quot;70&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;46,35,0,0&quot; Name=&quot;textBlock1&quot; Text=&quot;GeoLocation&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;319&quot; Style=&quot;{StaticResource PhoneTextLargeStyle}&quot; /&gt;         <br />&#160;&#160;&#160; &lt;TextBlock Height=&quot;40&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;46,87,0,0&quot; Name=&quot;statusTextBlock&quot; Text=&quot;No data&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;319&quot; /&gt;         <br />&#160;&#160;&#160; &lt;TextBlock Height=&quot;70&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;46,363,0,0&quot; Name=&quot;textBlock3&quot; Style=&quot;{StaticResource PhoneTextLargeStyle}&quot; Text=&quot;Reverse GeoCoding&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;319&quot; /&gt;         <br />&#160;&#160;&#160; &lt;TextBlock Height=&quot;40&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;46,439,0,0&quot; Name=&quot;addressTextBlock&quot; Text=&quot;(none)&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;319&quot; /&gt;         <br />&#160;&#160;&#160; &lt;TextBlock Height=&quot;40&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;46,133,0,0&quot; Name=&quot;locationTextBlock&quot; Text=&quot;(none)&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;319&quot; /&gt;         <br /></font>&lt;/Grid&gt;</p> </blockquote>  <p>The application holds a GeoCoordinateWatcher in an instance variable, and stops it when the user navigates away from the page:</p>  <blockquote>   <p>namespace ReverseGeoCode      <br />{       <br />&#160;&#160;&#160; public partial class MainPage : PhoneApplicationPage       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; private GeoCoordinateWatcher gcw; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public MainPage()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InitializeComponent();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; protected override void&#160; OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedFrom(e); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw.Stop();      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p> </blockquote>  <p>The OnNavigatedTo override starts the geolocation subsystem. It also prepares the UI (disabling the button), and then updates it in response to the events from the GeoLocationWatcher instance. Similar to the previous examples the implementation leverages RxLINQ. Here’s the code:</p>  <blockquote>   <p>protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)      <br />{       <br />&#160;&#160;&#160; base.OnNavigatedTo(e); </p>    <p>&#160;&#160;&#160; if (gcw == null)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw = new GeoCoordinateWatcher { MovementThreshold = 0.0 }; </p>    <p>&#160;&#160;&#160; gcw.Start(); </p>    <p>&#160;&#160;&#160; geoCodeButton.IsEnabled = false; </p>    <p>&#160;&#160;&#160; var statusChanges = gcw.GetStatusChangedEventStream().Select(sc =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var message=string.Empty;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var isReady=false;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; switch (sc.Status)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case GeoPositionStatus.Disabled:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = &quot;Disabled&quot;;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case GeoPositionStatus.Initializing:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = &quot;Initializing&quot;;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case GeoPositionStatus.NoData:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = &quot;No data&quot;;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case GeoPositionStatus.Ready:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = &quot;Ready, waiting for update...&quot;;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; isReady = true;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; default:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return new { isReady, message };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160; statusChanges.Subscribe(sc =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; statusTextBlock.Text = sc.message;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160; var positionUpdates = from sc in statusChanges      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where sc.isReady       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from pos in gcw.GetPositionChangedEventStream()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; let location = pos.Position.Location       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where (!Double.IsNaN(location.Latitude) &amp;&amp; !Double.IsNaN(location.Longitude) &amp;&amp; location.HorizontalAccuracy &lt;= 100.0)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select location; </p>    <p>&#160;&#160;&#160; positionUpdates.Take(1).Subscribe(_ =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; geoCodeButton.IsEnabled = true;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160; positionUpdates.Subscribe(l =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; statusTextBlock.Text = string.Format(&quot;Location acquired (+/-{0}m)&quot;, l.HorizontalAccuracy);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; locationTextBlock.Text = string.Format( &quot;{0:###.0000N;###.0000S;0}, {1:###.0000E;###.0000W;0}&quot;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , l.Latitude       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , l.Longitude       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });       <br />}</p> </blockquote>  <p>The statusChanges query projects the GeoPositionStatusChangedEventArgs event stream into a stream of (bool,string) pairs, with the bool indicating whether the geolocation system is ready (i.e., does it have a locked location), and the string its status in a user-friendly manner.The statusChanges subscriber updates the UI with the appropriate message. (Other resources/blogs show how to update the UI with data binding so I’m not doing it here.)</p>  <p>The positionUpdates query joins the status changes event stream with the location changes event stream, extracts the location from the position (via let), and projects the result into a location event stream. The two <a href="https://msdn.microsoft.com/en-us/library/ff708106(v=VS.92).aspx">where</a> clauses filter out unwanted status changes (e.g., GeoPositionStatus.Initializing) and location readings (e.g., HorizontalAccuracy over 100 meters).</p>  <p>The first event from this event stream enables the geoCodeButton. The <a href="https://msdn.microsoft.com/en-us/library/ff708029(v=VS.92).aspx">Take</a> combinator pulls a specified number of events—in this case just 1.</p>  <p>Finally, the last subscriber to the positionUpdates query updates the UI with the accuracy and lat/long from the location pushed by the phone’s geolocation subsystem.</p>  <p>At this point the application, though not a mashup, works with data provided solely by the device. See the following screenshot for a sample.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/1346.image_6D657F8E.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/1346.image_5F00_6D657F8E.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/3312.image_thumb_1E749462.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/3312.image_5F00_thumb_5F00_1E749462.png" width="150" height="240" /></a> </p>  <p>The last bit to add is a component that pulls data from the cloud. With the location information readily available the <a href="https://msdn.microsoft.com/en-us/library/cc966793.aspx">Bing Maps GeoCode Service</a> provides an easy way to do just that. So let’s extend the code to issue <a href="https://msdn.microsoft.com/en-us/library/cc980817.aspx">ReverseGeocodeRequests</a> and translate the lat/long into street addresses. Note that using Bing Services requires a Bing Maps Key (if you don’t already have one); authoritative information <a href="https://msdn.microsoft.com/en-us/library/ff428642.aspx">here</a>.</p>  <p>To add a GeoCode service client to the project go to the project’s references, right-click, and select Add Service Reference:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/8054.image_32BD1616.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/8054.image_5F00_32BD1616.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/7384.image_thumb_0B320FE0.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/7384.image_5F00_thumb_5F00_0B320FE0.png" width="338" height="127" /></a> </p>  <p>Enter dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc in the Address box (more info <a href="https://msdn.microsoft.com/en-us/library/cc966738.aspx">here</a>), and GeoCodeService as the Namespace:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/4744.image_0ED02ABD.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/4744.image_5F00_0ED02ABD.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/0044.image_thumb_54E0E7D0.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/0044.image_5F00_thumb_5F00_54E0E7D0.png" width="517" height="421" /></a> </p>  <p></p>  <p>This will query the service/wsdl and add the corresponding files to the solution (under the hood VisualStudio does all the code generation):</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/5810.image_0D1F5EE9.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/5810.image_5F00_0D1F5EE9.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/0535.image_thumb_28C3EADF.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/0535.image_5F00_thumb_5F00_28C3EADF.png" width="244" height="116" /></a> </p>  <p>Add using GeoCode.GeoCodeService; to the MainPage.xaml.cs file and the following instance variable and property to the MainPage class:</p>  <blockquote>   <p>private GeocodeServiceClient geoCodeClient;      <br />public GeocodeServiceClient GeoCodeClient       <br />{       <br />&#160;&#160;&#160; get       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (null == geoCodeClient)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; binding.MaxReceivedMessageSize = int.MaxValue;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; binding.MaxBufferSize = int.MaxValue;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var serviceUri = new UriBuilder(@&quot;<a href="dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc&quot;);">dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc&quot;);</a>       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; serviceUri.Scheme = Uri.UriSchemeHttps;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; serviceUri.Port = -1;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; geoCodeClient = new GeocodeServiceClient(binding, new EndpointAddress(serviceUri.Uri));       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return geoCodeClient;       <br />&#160;&#160;&#160; }       <br />}</p> </blockquote>  <p>As this is a cloud service the response arrives asynchronously. Rx allows one to regard this as an event stream, and query it via LINQ. First add the following extension method to the Helpers class. It is the same pattern as with location changed events.</p>  <blockquote>   <p>public static class Helpers      <br />{       <br />&#160;&#160;&#160; public static IObservable&lt;ReverseGeocodeCompletedEventArgs&gt; GetGeocodeCompletedEventStream(this GeocodeServiceClient gcss)       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Observable.Create&lt;ReverseGeocodeCompletedEventArgs&gt;(observable =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventHandler&lt;ReverseGeocodeCompletedEventArgs&gt; handler = (s, e) =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcss.ReverseGeocodeCompleted += handler;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { gcss.ReverseGeocodeCompleted -= handler; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });       <br />&#160;&#160;&#160; }       <br />}</p> </blockquote>  <p>Next add the following method to MainPage.xaml.cs—don’t forget to replace <font color="#ff0000">the uppercase text</font> with your own Bing Maps App Id:</p>  <blockquote>   <p>&#160;&#160;&#160; private void ResolveAddressFor(GeoCoordinate p)      <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; geoCodeButton.IsEnabled = false;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var request = new ReverseGeocodeRequest();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; request.Credentials = new Credentials { ApplicationId = @&quot;<font color="#ff0000">REPLACE WITH YOUR OWN APP ID</font>&quot; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; request.Location = new Location { Latitude = p.Latitude, Longitude = p.Longitude };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; request.ExecutionOptions = new ExecutionOptions { SuppressFaults = true }; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var results = from geoCodeResponse in GeoCodeClient.GetGeocodeCompletedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where geoCodeResponse.Result.ResponseSummary.StatusCode == ResponseStatusCode.Success       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select geoCodeResponse.Result; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; results.Subscribe(result =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var msg = string.Empty;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; switch (result.Results.Count)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 0:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = @&quot;No results&quot;;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 1:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = string.Format(&quot;{0}&quot;, result.Results.First().DisplayName);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; default:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = string.Format(&quot;(1/{0}) {1}&quot;, result.Results.Count, result.Results.First().DisplayName);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; addressTextBlock.Text = msg;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var errors = from geoCodeResponse in GeoCodeClient.GetGeocodeCompletedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where geoCodeResponse.Result.ResponseSummary.StatusCode != ResponseStatusCode.Success       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select geoCodeResponse.Result;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; errors.Subscribe(result =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; addressTextBlock.Text = string.Format(&quot;Error: {0}&quot;, result.ResponseSummary.FaultReason);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.GeoCodeClient.CloseAsync();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; results.Merge(errors).Subscribe(_ =&gt; geoCodeButton.IsEnabled = true); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.GeoCodeClient.ReverseGeocodeAsync(request);      <br />&#160;&#160;&#160; }       <br />}</p> </blockquote>  <p>This method prepares the web service request. The key pieces include the location information provided by the phone’s geolocation subsystem, and the application ID that identifies you to the Bing service. The results&#160; RxLINQ query leverages the extension method that bridges between .NET events and Rx event streams, selecting only successful responses. The results subscriber updates the UI with the first resolved address. Likewise, the errors RxLINQ query selects unsuccessful events, and its subscriber updates the UI with the fault reason. Finally, upon a successful or an error response (via the Rx <a href="https://msdn.microsoft.com/en-us/library/ff707385(v=VS.92).aspx">Merge</a> combinator) the code updates the UI by (re)enabling the&#160; button (which is disabled at the beginning of the method). In effect, the UI signals that Bing maps is servicing the request and prevents the user from triggering a new request during this time. Finally, the method invokes the ReverseGeocodeAsync method on the service client. This is where the code leverages the cloud.</p>  <p>To complete the puzzle, upon each tap of the geoCodeButton the code must take the last location reading, invoke the Bing Map Geocode service passing the location information, and update the UI accordingly. The following extension method (add it to the helpers class) brings the button’s click events into the Rx realm:</p>  <blockquote>   <p>public static IObservable&lt;RoutedEventArgs&gt; GetClickEventStream(this Button button)      <br />{       <br />&#160;&#160;&#160; return Observable.Create&lt;RoutedEventArgs&gt;(observable =&gt;       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; RoutedEventHandler handler = (s, e) =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; button.Click += handler;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { button.Click -= handler; };       <br />&#160;&#160;&#160; });       <br />}</p> </blockquote>  <p>The&#160; Rx <a href="en.wikipedia.org/wiki/Piece_de_resistance">piece de resistance</a> is the query that updates the UI. The tricky bit stems from using the latest location information, which updates as often as the clauses in the positionUpdates query evaluate to true. Initially I stored the latest location into an instance variable, and had button click events update the UI with that information. However my friend, colleague, and Rx founding father <a href="en.wikipedia.org/wiki/Erik_Meijer_(computer_scientist)">Erik Meijer</a> suggested a more elegant approach that accomplishes the same without side-effects. Here are the queries that tie button clicks and location updates—add this snippet at the end of the OnNavigatedTo method:</p>  <blockquote>   <p>var buttonClicks = geoCodeButton.GetClickEventStream(); </p>    <p>var latestLocations = positionUpdates.Publish(updates =&gt; from position in updates      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from click in buttonClicks.Take(1).TakeUntil(updates)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position); </p>    <p>latestLocations.Subscribe(l =&gt;      <br />&#160;&#160;&#160; ResolveAddressFor(l)       <br />&#160;&#160;&#160; );</p> </blockquote>  <p>The <a href="https://msdn.microsoft.com/en-us/library/ff708294(v=VS.92).aspx">TakeUntil</a> combinator synchronizes the button click with the location changed event stream; the <a href="https://msdn.microsoft.com/en-us/library/ff708301(v=VS.92).aspx">Publish</a> operator allows the updates stream to appear in two different places without duplicating the effects of any potential side-effects. In case it’s too hard to put together all the above pieces the complete code for MainPage.xaml.cs follows. To run it you need the XAML as well as the Bing Maps GeoCode service reference (with the appropriate application ID):</p>  <blockquote>   <p>using System;      <br />using System.Linq;       <br />using System.Windows;       <br />using System.Windows.Controls;       <br />using Microsoft.Phone.Controls;       <br />using System.Device.Location;       <br />using Microsoft.Phone.Reactive;       <br />using GeoLocation;       <br />using GeoCode.GeoCodeService;       <br />using System.ServiceModel; </p>    <p>namespace ReverseGeoCode      <br />{       <br />&#160;&#160;&#160; public partial class MainPage : PhoneApplicationPage       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; private GeoCoordinateWatcher gcw; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; private GeocodeServiceClient geoCodeClient;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public GeocodeServiceClient GeoCodeClient       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; get       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (null == geoCodeClient)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; binding.MaxReceivedMessageSize = int.MaxValue;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; binding.MaxBufferSize = int.MaxValue;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var serviceUri = new UriBuilder(@&quot;<a href="dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc&quot;);">dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc&quot;);</a>       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; serviceUri.Scheme = Uri.UriSchemeHttps;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; serviceUri.Port = -1;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; geoCodeClient = new GeocodeServiceClient(binding, new EndpointAddress(serviceUri.Uri));       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return geoCodeClient;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public MainPage()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InitializeComponent();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; protected override void&#160; OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedFrom(e); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw.Stop();      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedTo(e); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (gcw == null)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw = new GeoCoordinateWatcher { MovementThreshold = 0.0 }; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw.Start(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; geoCodeButton.IsEnabled = false; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var statusChanges = gcw.GetStatusChangedEventStream().Select(sc =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var message=string.Empty;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var isReady=false;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; switch (sc.Status)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case GeoPositionStatus.Disabled:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = &quot;Disabled&quot;;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case GeoPositionStatus.Initializing:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = &quot;Initializing&quot;;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case GeoPositionStatus.NoData:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = &quot;No data&quot;;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case GeoPositionStatus.Ready:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = &quot;Ready, waiting for update...&quot;;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; isReady = true;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; default:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return new { isReady, message };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; statusChanges.Subscribe(sc =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; statusTextBlock.Text = sc.message;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var positionUpdates = from sc in statusChanges      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where sc.isReady       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from pos in gcw.GetPositionChangedEventStream()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; let location = pos.Position.Location       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where (!Double.IsNaN(location.Latitude) &amp;&amp; !Double.IsNaN(location.Longitude) &amp;&amp; location.HorizontalAccuracy &lt;= 100.0)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select location; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; positionUpdates.Take(1).Subscribe(_ =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; geoCodeButton.IsEnabled = true;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; positionUpdates.Subscribe(l =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; statusTextBlock.Text = string.Format(&quot;Location acquired (+/-{0}m)&quot;, l.HorizontalAccuracy);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; locationTextBlock.Text = string.Format( &quot;{0:###.0000N;###.0000S;0}, {1:###.0000E;###.0000W;0}&quot;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , l.Latitude       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , l.Longitude       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var buttonClicks = geoCodeButton.GetClickEventStream(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var latestLocations = positionUpdates.Publish(updates =&gt; from position in updates      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from click in buttonClicks.Take(1).TakeUntil(updates)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; latestLocations.Subscribe(l =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ResolveAddressFor(l)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; private void ResolveAddressFor(GeoCoordinate p)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; geoCodeButton.IsEnabled = false;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var request = new ReverseGeocodeRequest();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; request.Credentials = new Credentials { ApplicationId = @&quot;<font color="#ff0000">REPLACE WITH YOUR OWN APP ID</font>&quot; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; request.Location = new Location { Latitude = p.Latitude, Longitude = p.Longitude };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; request.ExecutionOptions = new ExecutionOptions { SuppressFaults = true }; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var results = from geoCodeResponse in GeoCodeClient.GetGeocodeCompletedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where geoCodeResponse.Result.ResponseSummary.StatusCode == ResponseStatusCode.Success       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select geoCodeResponse.Result; </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; results.Subscribe(result =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var msg = string.Empty;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; switch (result.Results.Count)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 0:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = @&quot;No results&quot;;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 1:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = string.Format(&quot;{0}&quot;, result.Results.First().DisplayName);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; default:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg = string.Format(&quot;(1/{0}) {1}&quot;, result.Results.Count, result.Results.First().DisplayName);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; break;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; addressTextBlock.Text = msg;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var errors = from geoCodeResponse in GeoCodeClient.GetGeocodeCompletedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where geoCodeResponse.Result.ResponseSummary.StatusCode != ResponseStatusCode.Success       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select geoCodeResponse.Result;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; errors.Subscribe(result =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; addressTextBlock.Text = string.Format(&quot;Error: {0}&quot;, result.ResponseSummary.FaultReason);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.GeoCodeClient.CloseAsync();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; results.Merge(errors).Subscribe(_ =&gt; geoCodeButton.IsEnabled = true); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.GeoCodeClient.ReverseGeocodeAsync(request);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160; public static class Helpers      <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static IObservable&lt;RoutedEventArgs&gt; GetClickEventStream(this Button button)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Observable.Create&lt;RoutedEventArgs&gt;(observable =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RoutedEventHandler handler = (s, e) =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; button.Click += handler;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { button.Click -= handler; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static IObservable&lt;ReverseGeocodeCompletedEventArgs&gt; GetGeocodeCompletedEventStream(this GeocodeServiceClient gcss)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Observable.Create&lt;ReverseGeocodeCompletedEventArgs&gt;(observable =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventHandler&lt;ReverseGeocodeCompletedEventArgs&gt; handler = (s, e) =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcss.ReverseGeocodeCompleted += handler;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { gcss.ReverseGeocodeCompleted -= handler; };       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160; }       <br />}</p> </blockquote>  <p>Here’s the screenshot with the address information for the coordinates picked up in my office (it looks like not all the address information is available):</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/2335.image_20153A69.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/2335.image_5F00_20153A69.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/5554.image_thumb_5BD4D31C.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/5554.image_5F00_thumb_5F00_5BD4D31C.png" width="149" height="240" /></a> </p>  <p>In summary, this post has shown:</p>  <ul>   <li>How to use RxLINQ queries for UI updates, </li>    <li>How to use RxLINQ queries for cloud services’ results, and </li>    <li>How to mash up Windows Phone 7 GeoLocation data with data provided by Bing Map Geocode service. </li> </ul>]]></content:encoded>
    </item>
    <item>
      <title>WP7 Code: Distance Computations with the GeoLocation API</title>
      <link>https://docs.microsoft.com/archive/blogs/dragoman/wp7-code-distance-computations-with-the-geolocation-api</link>
      <pubDate>Wed, 29 Sep 2010 23:51:05 GMT</pubDate>
      <dc:creator><![CDATA[Dragos Manolescu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dragoman/2010/09/29/wp7-code-distance-computations-with-the-geolocation-api/</guid>
      <description><![CDATA[&#160;  In my previous post I showed the most interesting code fragments for a location-aware...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>In <a href="https://blogs.msdn.com/b/dragoman/archive/2010/09/21/wp7-code-using-the-geolocation-api.aspx">my previous post</a> I showed the most interesting code fragments for a location-aware Windows Phone 7 application. The code generates an event stream corresponding to location readings from the phone’s location subsystem. However, there are many applications that instead of lat/long readings need to compute the traveled distance (for example, when driving, biking, running, or hiking). This post shows how to convert the position readings from the Windows Phone location subsystem into distance measurements.</p>  <p>To begin with remember that motion on earth’s surface occurs on a(n approximate) sphere rather than on a plane. Consequently <a href="en.wikipedia.org/wiki/Euclidian_geometry">Euclidean geometry</a> no longer does it; instead, the <a href="en.wikipedia.org/wiki/Haversine_formula">Haversine formula</a> provides the distance between 2 locations. As implementing Haversine in C# has nothing to do with the phone I will reuse some <a href="megocode3.wordpress.com/2008/02/05/haversine-formula-in-c/">code surfaced by a Web search</a>. The implementation’s use of C# extension methods is in line with what I used to bridge between .NET events and RxLINQ event streams. In addition, they make the code read like English, which is pretty neat. The C# Haversine code follows, with the argument types updated to match those from the WP7 GeoLocation API:</p>  <blockquote>   <p><font size="2" face="Lucida Sans Typewriter">public enum DistanceIn { Miles, Kilometers }; </font></p>    <p><font size="2" face="Lucida Sans Typewriter">public static class Haversine       <br />{ </font></p>    <p><font size="2" face="Lucida Sans Typewriter">&#160;&#160;&#160; public static double Between(this DistanceIn @in, GeoPosition&lt;GeoCoordinate&gt; here, GeoPosition&lt;GeoCoordinate&gt; there)       <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var r = (@in == DistanceIn.Miles) ? 3960 : 6371;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var dLat = (there.Location.Latitude - here.Location.Latitude).ToRadian();        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var dLon = (there.Location.Longitude - here.Location.Longitude).ToRadian();        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Math.Cos(here.Location.Latitude.ToRadian()) * Math.Cos(there.Location.Latitude.ToRadian()) *        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Math.Sin(dLon / 2) * Math.Sin(dLon / 2);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var d = r * c;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return d;        <br />&#160;&#160;&#160; } </font></p>    <p><font size="2" face="Lucida Sans Typewriter">&#160;&#160;&#160; private static double ToRadian(this double val)       <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return (Math.PI / 180) * val;        <br />&#160;&#160;&#160; }        <br />}</font></p> </blockquote>  <p>Start with the application from <a href="https://blogs.msdn.com/b/dragoman/archive/2010/09/21/wp7-code-using-the-geolocation-api.aspx">my previous blog post</a> and change the XAML (MainPage.xaml) to include a text block and a button in the content panel (new code in green):</p>  <blockquote>   <p><font size="2" face="Lucida Sans Typewriter">&lt;Grid x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&quot;&gt;       <br /><font color="#008000">&#160;&#160;&#160; &lt;TextBlock Height=&quot;30&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;36,69,0,0&quot; Name=&quot;textBlock1&quot; Text=&quot;(no reading)&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;392&quot; /&gt;         <br />&#160;&#160;&#160; &lt;Button Content=&quot;Start&quot; Height=&quot;84&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;121,493,0,0&quot; Name=&quot;button1&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;227&quot; /&gt;          <br /></font>&lt;/Grid&gt;</font></p> </blockquote>  <p>Next wire the button such that taps (i.e., Click events) start or stop the GeoLocationWatcher. As clicks are asynchronous events RxLINQ provides an elegant solution to deal with them. First add to the Helpers class an extension method that brings Click events into the realm of Rx:</p>  <blockquote>   <p><font size="2" face="Lucida Sans">public static IObservable&lt;RoutedEventArgs&gt; GetClickEventStream(this Button button)       <br />{        <br />&#160;&#160;&#160; return Observable.Create&lt;RoutedEventArgs&gt;(observable =&gt;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RoutedEventHandler handler = (s, e) =&gt;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; button.Click += handler;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { button.Click -= handler; };        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; });        <br />}</font></p> </blockquote>  <p>Next remove the gcw.Start() from OnNavigatedTo override and add an RxLINQ query and subscriber to the button click event stream (new code in green):</p>  <blockquote>   <p><font size="2" face="Lucida Sans Typewriter">protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)       <br />{        <br />&#160;&#160;&#160; base.OnNavigatedTo(e); </font></p>    <p><font size="2" face="Lucida Sans Typewriter">&#160;&#160;&#160; if (gcw == null)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw = new GeoCoordinateWatcher(); </font></p>    <p><font size="2" face="Lucida Sans Typewriter">&#160;&#160;&#160; ShowGeoLocation();       <br />} </font></p>    <p><font size="2" face="Lucida Sans Typewriter">// snip</font></p>    <p><font size="2" face="Lucida Sans Typewriter">public void ShowGeoLocation()       <br />{        <br />&#160;&#160;&#160; var statusChanges = from statusChanged in gcw.GetStatusChangedEventStream()        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where statusChanged.Status == GeoPositionStatus.Ready        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select statusChanged; </font></p>    <p><font size="2" face="Lucida Sans Typewriter">&#160;&#160;&#160; <font color="#008000">button1.GetClickEventStream().Scan( false         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , (isStarted, _) =&gt;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (isStarted)          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw.Stop();          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw.Start();          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return !isStarted;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }).Subscribe(isStarted =&gt; button1.Content = isStarted ? &quot;Stop&quot; : &quot;Start&quot; );</font></font></p> </blockquote>  <p>The Scan operator allows the query to carry state from one Click event to the other. Each click event starts or stops the GeoLocationWatcher instance depending on the accumulator’s value, and then toggles it. The subscriber updates the button’s content accordingly.</p>  <p>Next the code must ensure that the distance computations takes into account only readings that have different lat/long values. The DistinctUntilChanged RxLINQ operator with a comparator that considers only the Latitude and Longitude values provides an elegant solution to the deduplication problem. Here’s the comparator’s code:</p>  <blockquote>   <p><font size="2" face="Lucida Sans Typewriter">public class PositionComparator : IEqualityComparer&lt;GeoPosition&lt;GeoCoordinate&gt;&gt;       <br />{ </font></p>    <p><font size="2" face="Lucida Sans Typewriter">&#160;&#160;&#160; public bool Equals(GeoPosition&lt;GeoCoordinate&gt; x, GeoPosition&lt;GeoCoordinate&gt; y)       <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return (x.Location.Latitude == y.Location.Latitude &amp;&amp; x.Location.Longitude == y.Location.Longitude);        <br />&#160;&#160;&#160; } </font></p>    <p><font size="2" face="Lucida Sans Typewriter">&#160;&#160;&#160; // snip       <br />}</font></p> </blockquote>  <p>And here’s the updated positions query (new code in green):</p>  <blockquote>   <p><font size="2" face="Lucida Sans Typewriter">var positions = <font color="#008000">(</font>from position in positionChanges        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where position.Location.HorizontalAccuracy &lt;= 100        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position<font color="#008000">).DistinctUntilChanged(new PositionComparator())</font>;</font></p> </blockquote>  <p>Computing distances requires two points. An elegant solution to using the current and previous location events is to combine the location event stream with itself such that every event pair represents the current and previous coordinates. The RxLINQ Zip operator combines the event streams, and the Skip operator provides the shift required for this pairing. Here’s the query that computes the distance in Km (for imperial units replace Kilometers with Miles):</p>  <blockquote>   <p><font size="2" face="Lucida Sans Typewriter">var distances = positions.Zip(positions.Skip(1), (l, r) =&gt; DistanceIn.Kilometers.Between(r, l));</font></p> </blockquote>  <p>Finally, the Scan operator applied to the distances event stream computes the total distance; the accumulator’s initial value is 0.0, and the display shows meters:</p>  <blockquote>   <p><font size="2" face="Lucida Sans Typewriter">var distance = distances.Scan(0.0, (a, e) =&gt; a + e); </font></p>    <p><font size="2" face="Lucida Sans Typewriter">distance.Subscribe(d =&gt; this.textBlock1.Text = string.Format(&quot;Distance so far {0:00.000} m&quot;,d*1000));</font></p> </blockquote>  <p>In summary, this post has shown:</p>  <ul>   <li>How to convert Windows Phone 7 lat/long readings into distances,</li>    <li>How to use RxLINQ queries for UI (button click events), and</li>    <li>How to perform calculations on adjacent elements in an event stream via the Zip and Skip operators.</li> </ul>]]></content:encoded>
    </item>
    <item>
      <title>WP7 Code: Using the GeoLocation API</title>
      <link>https://docs.microsoft.com/archive/blogs/dragoman/wp7-code-using-the-geolocation-api</link>
      <pubDate>Tue, 21 Sep 2010 23:40:31 GMT</pubDate>
      <dc:creator><![CDATA[Dragos Manolescu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dragoman/2010/09/21/wp7-code-using-the-geolocation-api/</guid>
      <description><![CDATA[&#160;  I’m kicking off a series of blog posts focused on writing Windows Phone 7 code with one of...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>I’m kicking off a series of blog posts focused on writing Windows Phone 7 code with one of the APIs that will probably attract many developers interested in getting their feet wet: <a href="https://msdn.microsoft.com/en-us/library/system.device.location(v=VS.92).aspx">GeoLocation</a>. Building this code requires:</p>  <ul>   <li>The <a href="https://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce&amp;displaylang=en">Windows Phone Developer Tools</a>, fresh off the press as of <a href="windowsteamblog.com/windows_phone/b/wpdev/archive/2010/09/16/windows-phone-developer-tools-are-final.aspx">September 16</a>.</li>    <li>The <a href="https://msdn.microsoft.com/en-us/library/ff402535(VS.92).aspx">Windows Phone Development</a> documentation from MSDN.</li> </ul>  <p>Before I begin, a few things to be aware of. First, the samples are not intended to be production code. In other words, don’t use this code in your avionics system. Second, I emphasize Windows Phone code at the expense of other aspects. For example, while <a href="https://msdn.microsoft.com/en-us/library/ms750612.aspx">data binding</a> may provide an elegant solution to updating GUI elements, I’m leaving its implementation as an exercise to the reader :) Caveat emptor.</p>  <p>Enough prose, let’s write some code. Start by opening a new Windows Phone Application in Visual Studio. This will create the necessary directories and unfold the appropriate templates. Add a TextBlock to the Grid called ContentPanel; the XAML will look similar to the following (new content in green):</p>  <blockquote>   <p>&lt;Grid x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&quot;&gt;     <br />&#160;&#160;&#160; <font color="#008000">&lt;TextBlock Height=&quot;30&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;0,49,0,0&quot; Name=&quot;textBlock1&quot; Text=&quot;TextBlock&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;450&quot; /&gt;       <br /></font>&lt;/Grid&gt;</p> </blockquote>  <p>Next add a reference to the assembly holding the GeoLocation API (System.Device), and the appropriate using directive:</p>  <blockquote>   <p>using System.Device.Location;</p> </blockquote>  <p>As Windows Phone 7 includes the <a href="https://msdn.microsoft.com/en-us/devlabs/ee794896.aspx">.NET Reactive Framework (Rx)</a> I will be using it for event-based code. To that end add references to <a href="https://msdn.microsoft.com/en-us/library/system(v=VS.92).aspx">System.Observable</a> and <a href="https://msdn.microsoft.com/en-us/library/microsoft.phone.reactive(v=VS.92).aspx">Microsoft.Phone.Reactive</a>, and the appropriate using directive:</p>  <blockquote>   <p>using Microsoft.Phone.Reactive;</p> </blockquote>  <p>An instance of <a href="https://msdn.microsoft.com/en-us/library/ee808838(v=VS.92).aspx">GeoLocationWatcher</a> held in an instance variable of the MainPage class provides access to the location information. The OnNavigatedTo and OnNavigatedFrom methods ensure that the location watcher is started when the page opens, and stopped when it is abandoned.</p>  <blockquote>   <p>public partial class MainPage : PhoneApplicationPage     <br />{      <br />&#160;&#160;&#160; GeoCoordinateWatcher gcw; </p>    <p>&#160;&#160;&#160; // Constructor     <br />&#160;&#160;&#160; public MainPage()      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; InitializeComponent();      <br />&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160; protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedTo(e); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (gcw == null)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw = new GeoCoordinateWatcher(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw.Start(); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ShowGeoLocation();     <br />&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160; protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; base.OnNavigatedFrom(e); </p>    <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (gcw != null)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcw.Stop();      <br />&#160;&#160;&#160; }</p>    <p>&#160;&#160;&#160; // snip</p> </blockquote>  <p>The ShowGeoLocation method contains code that updates the UI (i.e., text box) with the location information. Before covering that code let’s go over a couple of helper methods that convert the .NET events raised by the GeoLocationWatcher class into Rx event streams. The first event of interest is <a href="https://msdn.microsoft.com/en-us/library/system.device.location.geocoordinatewatcher.statuschanged(v=VS.92).aspx">StatusChanged</a>. It signals when the location subsystem is ready and thus able to provide location information. The second event is <a href="https://msdn.microsoft.com/en-us/library/system.device.location.geocoordinatewatcher.positionchanged(v=VS.92).aspx">PositionChanged</a>, which signals whenever the position of the device, as determined by the location subsystem, changes. The following <a href="https://msdn.microsoft.com/en-us/library/bb383977.aspx">extension methods</a> provide the corresponding event streams:</p>  <blockquote>   <p>public static class Helpers     <br />{      <br />&#160;&#160;&#160; public static IObservable&lt;GeoPositionStatusChangedEventArgs&gt; GetStatusChangedEventStream(this GeoCoordinateWatcher watcher)      <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Observable.Create&lt;GeoPositionStatusChangedEventArgs&gt;(observer =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventHandler&lt;GeoPositionStatusChangedEventArgs&gt; handler = (s, e) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observer.OnNext(e);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; watcher.StatusChanged += handler;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { watcher.StatusChanged -= handler; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; );      <br />&#160;&#160;&#160; } </p>    <p>&#160;&#160;&#160; public static IObservable&lt;GeoPositionChangedEventArgs&lt;GeoCoordinate&gt;&gt; GetPositionChangedEventStream(this GeoCoordinateWatcher watcher)     <br />&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return Observable.Create&lt;GeoPositionChangedEventArgs&lt;GeoCoordinate&gt;&gt;(observable =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventHandler&lt;GeoPositionChangedEventArgs&lt;GeoCoordinate&gt;&gt; handler = (s, e) =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; observable.OnNext(e);      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; watcher.PositionChanged += handler;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return () =&gt; { watcher.PositionChanged -= handler; };      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; );      <br />&#160;&#160;&#160; }      <br />}</p> </blockquote>  <p>If you’re building an application that needs to determine the position just once (e.g., what’s around me based on where I’m at) then the following sequence of queries does just that, updating the contents of the text box with the location information:</p>  <blockquote>   <p>public void ShowGeoLocation()     <br />{      <br />&#160;&#160;&#160; var statusChanges = from statusChanged in gcw.GetStatusChangedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where statusChanged.Status == GeoPositionStatus.Ready      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select statusChanged; </p>    <p>&#160;&#160;&#160; var positionChanges = from s in statusChanges     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from position in gcw.GetPositionChangedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position.Position; </p>    <p>&#160;&#160;&#160; var positions = from position in positionChanges     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where position.Location.HorizontalAccuracy &lt;= 100      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position; </p>    <p>&#160;&#160;&#160; positions.Take(1).Subscribe(firstLocationFix =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; textBlock1.Text = string.Format(&quot;{0},{1}&quot;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , firstLocationFix.Location.Latitude      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , firstLocationFix.Location.Longitude      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160; );</p>    <p>}</p> </blockquote>  <p>The first query (statusChanges) represents an event stream comprised of status changed events signaling that the location subsystem is ready. The second query (positionChanges) is a join between statusChanges and position changed events; this ensures that the latter is gated by the former. Finally, the third query (positions) filters the position changes based on the horizontal accuracy of each reading. The accuracy depends on how the location subsystem determines the location, and the code above discard readings below 100m accuracy. The last statement updates the UI with the first reading satisfying the (composed by now) queries:</p>  <ul>   <li>Filtering of StatusChanged events by Status property</li>    <li>Joining between filtered StatusChanged events and LocationChanged events</li>    <li>Filtering of resulting LocationChanged events by HorizontalAccuracy property</li> </ul>  <p>What if you’re building an application that needs the series of location events (e.g., turn-by-turn navigation) rather than just one location? The Rx queries shown above remain unchanged. The only change involves how the event stream is consumed. The Take method is gone, and Action argument updates the text box contents. Here’s the ShowGeoLocation code, with the updated statement in green:</p>  <blockquote>   <p>public void ShowGeoLocation()     <br />{      <br />&#160;&#160;&#160; var statusChanges = from statusChanged in gcw.GetStatusChangedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where statusChanged.Status == GeoPositionStatus.Ready      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select statusChanged; </p>    <p>&#160;&#160;&#160; var positionChanges = from s in statusChanges     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from position in gcw.GetPositionChangedEventStream()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position.Position; </p>    <p>&#160;&#160;&#160; var positions = from position in positionChanges     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where position.Location.HorizontalAccuracy &lt;= 100      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position; </p>    <p><font color="#008000">&#160;&#160;&#160; positions.Subscribe(position =&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; textBlock1.Text = string.Format( &quot;{0},{1}&quot;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , position.Location.Latitude        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , position.Location.Longitude        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160; );</font></p>    <p>}</p> </blockquote>  <p>Even though the displayed latitude and longitude values may not change, the read values might change. To illustrate that the final update to this code adds a sequence number to the display. It also displays the horizontal accuracy. The code implements the sequence with the Scan operator (which applies an accumulator over the events) and an anonymous class encapsulating the sequence number. Here’s the ShowGeoLocation code, with the updated statement in green:</p>  <p>public void ShowGeoLocation()   <br />{    <br />&#160;&#160;&#160; var statusChanges = from statusChanged in gcw.GetStatusChangedEventStream()    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where statusChanged.Status == GeoPositionStatus.Ready    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select statusChanged; </p>  <p>&#160;&#160;&#160; var positionChanges = from s in statusChanges   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; from position in gcw.GetPositionChangedEventStream()    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position.Position; </p>  <p>&#160;&#160;&#160; var positions = from position in positionChanges   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where position.Location.HorizontalAccuracy &lt;= 1000    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select position; </p>  <p><font color="#008000">&#160;&#160; positions.Scan(new { i = 0     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , p = default(GeoPosition&lt;GeoCoordinate&gt;)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; },      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (a,e) =&gt; new { i = a.i + 1      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , p = e }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ).Subscribe(e =&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; textBlock1.Text = string.Format( &quot;{0}:{1},{2}@{3}&quot;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , e.i      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , e.p.Location.Latitude      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , e.p.Location.Longitude      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , e.p.Location.HorizontalAccuracy      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; );      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160; ); </font></p>  <p>}</p>  <p>In summary, this post has shown:</p>  <ul>   <li>How to get started with the Windows Phone GeoLocation API,</li>    <li>How to convert the StatusChanged and PositionChanged events into Rx event streams, and</li>    <li>How to write LINQ queries against them.</li> </ul>]]></content:encoded>
    </item>
    <item>
      <title>Coming Soon: Windows Phone 7 Blog Posts</title>
      <link>https://docs.microsoft.com/archive/blogs/dragoman/coming-soon-windows-phone-7-blog-posts</link>
      <pubDate>Wed, 08 Sep 2010 10:38:40 GMT</pubDate>
      <dc:creator><![CDATA[Dragos Manolescu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dragoman/2010/09/08/coming-soon-windows-phone-7-blog-posts/</guid>
      <description><![CDATA[It’s been an embarrassingly long time since my last post on this blog. Several cool projects in the...]]></description>
      <content:encoded><![CDATA[<p>It’s been an embarrassingly long time since my last post on this blog. Several cool projects in the Windows Phone 7 team kept me busy. Now that <a href="windowsteamblog.com/windows_phone/b/windowsphone/archive/2010/09/01/windows-phone-7-released-to-manufacturing.aspx">we shipped the bits</a> I’d like to revive this blog with snippets on writing Windows Phone 7 code. Stay tuned for posts with <em>WP7 Code</em> in the title :)</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/5808.photo_3B584162.jpg" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/5808.photo_5F00_3B584162.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="photo" border="0" alt="photo" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/88/10/metablogapi/2768.photo_thumb_287397EB.jpg" original-url="blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-10-metablogapi/2768.photo_5F00_thumb_5F00_287397EB.jpg" width="244" height="184" /></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Web Sandbox available under the Apache License</title>
      <link>https://docs.microsoft.com/archive/blogs/dragoman/web-sandbox-available-under-the-apache-license</link>
      <pubDate>Wed, 28 Jan 2009 01:36:00 GMT</pubDate>
      <dc:creator><![CDATA[Dragos Manolescu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dragoman/2009/01/28/web-sandbox-available-under-the-apache-license/</guid>
      <description><![CDATA[Earlier today&nbsp;we announced releasing the runtime code of the Web Sandbox available under the...]]></description>
      <content:encoded><![CDATA[Earlier today&nbsp;we announced releasing the runtime code of the <A class="" href="websandbox.livelabs.com/" mce_href="websandbox.livelabs.com/">Web Sandbox</A> available under the Open Source <A href="www.apache.org/licenses/LICENSE-2.0"><FONT color=#0099ff>Apache License 2.0</FONT></A>. The announcement has already been <A class="" href="port25.technet.com/archive/2009/01/26/web-sandbox-source-now-available-under-apache-license-2-0.aspx" mce_href="port25.technet.com/archive/2009/01/26/web-sandbox-source-now-available-under-apache-license-2-0.aspx">picked up&nbsp;by the blogosphere</A>. Should you head over to the site check out the Web Slices samples we added with this release: <A class="" href="websandbox-code.org/Samples/WebSlicesSample.aspx?cpolicy=webslice&amp;ua=IE8" mce_href="websandbox-code.org/Samples/WebSlicesSample.aspx?cpolicy=webslice&amp;ua=IE8">weather</A> and <A class="" href="websandbox-code.org/Samples/WebSlicesSample2.aspx?cpolicy=webslice&amp;ua=IE8" mce_href="websandbox-code.org/Samples/WebSlicesSample2.aspx?cpolicy=webslice&amp;ua=IE8">traffic</A>.]]></content:encoded>
    </item>
  </channel>
</rss>