Interactive Mapping Blog

Mapping Solutions News

Archive for March, 2010

Writing a Bing Maps location aware application for Windows Phone 7 Series

Tuesday, March 16th, 2010

imageIf you have been keeping up with the news from Mix2010 and yesterdays’ keynote you will know a number of exciting things have been released for windows phone 7 series:

  • completely free developer tools
  • the windows 7 phone series beta sdk
  • lots of details about using silverlight and xna to develop phone applications

So what does that mean for Bing Map, will there be a new silverlight control for mobile? There may well be an update to better support mobile development but you can start right now using the current Bing Maps silverlight control and it works! To show you how here is a quick tutorial creating your first location aware Bing Maps phone application.

Prerequisites

Getting Started

Start by opening Visual Studio 2010 (or express as offered free in the sdk) and create a new project, selecting the “Windows Phone Application” project template.

image

Now add references to the Bing Maps silverlight control (usually found in C:\Program Files\Bing Maps Silverlight Control\V1\Libraries). You may find you need to also add a reference to System.Windows.Browser to get it to compile correctly (from c:\Program Files\Microsoft Silverlight\4.0.50303.0\).

Finally for the setup, add a reference to System.Device.Location.

Creating a Basic User Interface

Now we have the project created lets create a simple user interface in XAML that has a Bing Map Control, a status bar and a start button. First add the Bing Maps namespace to you MainPage.xaml file:

xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"

Then add the following block of XAML in the grid named “ContentGrid” which should already be in MainPage.xaml:

  1. <m:Map Name="mapMain" NavigationVisibility="Collapsed" Mode="AerialWithLabels" CredentialsProvider="ADD_YOUR_BINGMAPS_KEY_HERE">
  2. </m:Map>
  3. <Border Background="Black" Height="40" Opacity="0.7" VerticalAlignment="Top">
  4.     <TextBlock Name="tbStatus" Text="Click below to start" Margin="5 5 0 0" />
  5.    </Border>

Now change the name of the application and the title to be whatever you want. Hit F5 and you should get the emulator load up with you application showing a Bing Map!"

Making it actually do something

For the next part of the tutorial we are going to make the application actually do something with the map by making it location aware, that is to say use the devices location to change the map in some way.

First add the following to your XAML just under the map control, to add a button:

  1. <Button Name="btnStart" Click="btnStart_Click" Width="260" Height="40">
  2.     <Button.Content>
  3.         <StackPanel Orientation="Horizontal">
  4.             <Path Fill="White" Data="F1 M 2.339,6.489 C 1.193,5.343 1.193,3.485 2.339,2.339 C 3.485,1.192 5.344,1.193 6.489,2.339 C 7.635,3.485 7.635,5.343 6.489,6.489 C 5.344,7.636 3.485,7.636 2.339,6.489 Z M 11.711,10.209 L 8.185,6.684 C 9.207,4.986 9.000,2.757 7.535,1.293 C 5.812,-0.431 3.017,-0.431 1.293,1.293 C -0.431,3.017 -0.431,5.812 1.293,7.536 C 2.757,8.999 4.988,9.206 6.685,8.185 L 10.209,11.710 L 11.711,10.209 Z" Margin="0,0,5,0">
  5.                 <Path.RenderTransform>
  6.                     <ScaleTransform ScaleX="2.5" ScaleY="2.5" />
  7.                 </Path.RenderTransform>
  8.             </Path>
  9.             <TextBlock Foreground="White" Text="Find Me Now" Margin="20 -5 0 0" />
  10.         </StackPanel>
  11.     </Button.Content>
  12. </Button>

 

Then and add a map layer with a simple circle pushpin to the map control:

  1.           <m:Map Name="mapMain" NavigationVisibility="Collapsed" Mode="AerialWithLabels" CredentialsProvider="ApXw1_p4abRAyITXFZGy6IvPyUN05hwF08hfkkNMUfExuujgB-XpmebygnDRH1RA">
  2.               <m:MapLayer Name="lMain">
  3.                   <Ellipse Fill="Red" Width="20" Height="20" m:MapLayer.Position="0,0" Name="ppLocation" Visibility="Collapsed" />
  4.                           </m:MapLayer>
  5.             </m:Map>

Now we are going to wire up the click event of the button to get the users location and update the map. We will do this in a number of stages.

Firstly, add these using statements to the top of your code:

  1. using System.Device.Location;
  2. using Microsoft.Maps.MapControl;

 

Now add a private member of type GeoCoordinateWatcher above the MainPage constructor:

  1. GeoCoordinateWatcher watcher;
  2. public MainPage()
  3. {
  4.     InitializeComponent();
  5.  
  6.     SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
  7. }

And add the following event handler for the button click:

  1. private void btnStart_Click(object sender, RoutedEventArgs e)
  2. {
  3.     // Reinitialize the GeoCoordinateWatcher
  4.     watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
  5.     watcher.MovementThreshold = 100;//distance in metres
  6.  
  7.     // Add event handlers for StatusChanged and PositionChanged events
  8.     watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
  9.     watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
  10.  
  11.     // Start data acquisition
  12.     watcher.Start();
  13.  
  14.     //hide button
  15.     btnStart.Visibility = Visibility.Collapsed;
  16. }

This creates a new GeoCoordinateWatcher when the button is clicked with the accuracy set to high, sets a movement threshold allowing movement by 100 metres before the application is alerted and attaches two events. The first event “StatusChanged” will fire when the status of the location data changes (like during initialisation and once we have a location) and the second event handles changes to the current location. We will add the handlers for both in a minute. Lastly we start the watcher and hide the button then wire it up in the XAML to our recently added button’s click event:

  1. <Button Name="btnStart" Click="btnStart_Click" Width="260" Height="40">
  2.     <Button.Content>
  3.         <StackPanel Orientation="Horizontal">
  4.             <Path Fill="White" Data="F1 M 2.339,6.489 C 1.193,5.343 1.193,3.485 2.339,2.339 C 3.485,1.192 5.344,1.193 6.489,2.339 C 7.635,3.485 7.635,5.343 6.489,6.489 C 5.344,7.636 3.485,7.636 2.339,6.489 Z M 11.711,10.209 L 8.185,6.684 C 9.207,4.986 9.000,2.757 7.535,1.293 C 5.812,-0.431 3.017,-0.431 1.293,1.293 C -0.431,3.017 -0.431,5.812 1.293,7.536 C 2.757,8.999 4.988,9.206 6.685,8.185 L 10.209,11.710 L 11.711,10.209 Z" Margin="0,0,5,0">
  5.                 <Path.RenderTransform>
  6.                     <ScaleTransform ScaleX="2.5" ScaleY="2.5" />
  7.                 </Path.RenderTransform>
  8.             </Path>
  9.             <TextBlock Foreground="White" Text="Find Me Now" Margin="20 -5 0 0" />
  10.         </StackPanel>
  11.     </Button.Content>
  12. </Button>

 

Ok, the next piece of the puzzle is to add the event handlers we attached in the button click handler above, watcher_StatusChanged and watcher_PositionChanged:

  1. #region Event Handlers
  2.  
  3. /// <summary>
  4. /// Handler for the StatusChanged event. This invokes MyStatusChanged on the UI thread and
  5. /// passes the GeoPositionStatusChangedEventArgs
  6. /// </summary>
  7. /// <param name="sender"></param>
  8. /// <param name="e"></param>
  9. void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
  10. {
  11.     Deployment.Current.Dispatcher.BeginInvoke(() => MyStatusChanged(e));
  12.  
  13. }
  14.  
  15. /// <summary>
  16. /// Handler for the PositionChanged event. This invokes MyStatusChanged on the UI thread and
  17. /// passes the GeoPositionStatusChangedEventArgs
  18. /// </summary>
  19. /// <param name="sender"></param>
  20. /// <param name="e"></param>
  21. void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
  22. {
  23.     Deployment.Current.Dispatcher.BeginInvoke(() => MyPositionChanged(e));
  24. }
  25.  
  26. #endregion

You will notice these call two methods when they are triggered, but they ensure that these methods are called on the UI thread otherwise we will get some nasty cross thread errors.

Finally add the two UI thread methods for doing something when the events fire, and a simple ResetMap method that’s called when the user initially clicks the button:

  1. /// <summary>
  2. /// Custom method called from the PositionChanged event handler
  3. /// </summary>
  4. /// <param name="e"></param>
  5. void MyPositionChanged(GeoPositionChangedEventArgs<GeoCoordinate> e)
  6. {
  7.     // Update the map to show the current location
  8.     Location ppLoc = new Location(e.Position.Location.Latitude, e.Position.Location.Longitude);
  9.     mapMain.SetView(ppLoc, 10);
  10.  
  11.     //update pushpin location and show
  12.     MapLayer.SetPosition(ppLocation, ppLoc);
  13.     ppLocation.Visibility = System.Windows.Visibility.Visible;
  14.  
  15.     
  16. }
  17.  
  18. /// <summary>
  19. /// Custom method called from the StatusChanged event handler
  20. /// </summary>
  21. /// <param name="e"></param>
  22. void MyStatusChanged(GeoPositionStatusChangedEventArgs e)
  23. {
  24.     switch (e.Status)
  25.     {
  26.         case GeoPositionStatus.Disabled:
  27.             // The location service is disabled or unsupported.
  28.             // Alert the user
  29.             tbStatus.Text = "sorry we can’t find you on this device";
  30.             break;
  31.         case GeoPositionStatus.Initializing:
  32.             // The location service is initializing.
  33.             // Disable the Start Location button
  34.             tbStatus.Text = "looking for you…";
  35.             break;
  36.         case GeoPositionStatus.NoData:
  37.             // The location service is working, but it cannot get location data
  38.             // Alert the user and enable the Stop Location button
  39.             tbStatus.Text = "can’t find you yet…";
  40.             ResetMap();
  41.  
  42.             break;
  43.         case GeoPositionStatus.Ready:
  44.             // The location service is working and is receiving location data
  45.             // Show the current position and enable the Stop Location button
  46.             tbStatus.Text = "found you!";
  47.             break;
  48.  
  49.     }
  50. }
  51.  
  52. void ResetMap()
  53. {
  54.     Location ppLoc = new Location(0, 0);
  55.     mapMain.SetView(ppLoc, 1);
  56.  
  57.     //update pushpin location and show
  58.     MapLayer.SetPosition(ppLocation, ppLoc);
  59.     ppLocation.Visibility = System.Windows.Visibility.Collapsed;
  60. }

 

These first method MyPositionChanged updates the map by setting the current map view to the new location and zooming in. It also makes the pushpin icon visible. The second method MyStatusChanged simply updates the status text in the UI with a message telling the user the current state of the location services.

Houston we have a problem

By now you should have a finished application the compiles, if not you can download the source code below to see the full code:

butdownloadcode[1]

You can run the application in the emulator by clicking F5 and the map and UI should appear, BUT here we find a problem.

The emulator currently does not support the location service, so all we ever get back is a status change of NoData. There is currently not even any way to add fake data to the emulator so we will have to wait for an update to allow us to actually get location aware applications working in the emulator :-(

So until we can get our hands on some real hardware “Nudge, Nudge”  there is no real way to test this application.

Google Street View Launched UK Wide In Commercial Property Website

Thursday, March 11th, 2010

Within hours of Google launching Google Street View imagery covering 99% of UK roads, Earthware has released their first implementation of the new imagery in commercial property portal NovaLoca.com.

The Google Street View imagery in NovaLoca.com allows users to view commercial property in the major UK cities and in smaller towns and villages right across Google Street View in NovaLoca.com England, Scotland, Wales and Northern Ireland. The user now gets an even better impression of what a property being advertised on the site is like, without having to visit it in person, making finding commercial property easier than it has ever been before.

Earthware and NovaLoca have been working together for a long time to keep NovaLoca’s property mapping well ahead of the competition. In October 2008 we implemented the very first UK street side imagery in NovaLoca’s maps for commercial property in London before Google released any of their Street View imagery in the UK. This latest addition means that Street View imagery is now a standard function of the property maps where ever you are looking for commercial property in the UK. Yet again, this means NovaLoca have beaten all their competitors by becoming the first UK commercial property website to be using this technology.

If you want to know how you can use online mapping and Google Street View in your website please contact Earthware on 0845 642 9880.

Google Street View Launches UK wide

Thursday, March 11th, 2010

Google Maps have today launched Google StreetView imagery for the entire UK and we mean the entire UK!  Google Street View CoverageNearly a quarter of a million roads across England, Scotland, Wales and Northern Ireland are now available to ‘walk’ down from your computer screen. The 360 degree pictures mean you can have a good look around as you travel down the street, and you can deep zoom into the images to see the detail (although faces and registration plates are blurred out in accordance to the privacy protection rules).

But Google have been even busier than that: they have also released Google Street View imagery covering the majority of France, Italy and Spain too.

Although Google Street View has been available in 25 major cities in the UK since March 2009, to now have Street View right across the UK is a phenomenal achievement from the Google Maps team and will be changing the way people use online maps to display geographical information in interactive maps. The StreetView maps can be embedded into any website to help businesses display their location and any geographical information on a map, immediately we see major benefits from property mapping and travel mapping.

For anyone that’s interested you can now see where all the Earthware fun happens:
View Larger Map

If you are interested in how you can use Google Maps and Google Street View to display your information then contact Earthware on 0845 642 9880.