Introduction

Hello everyone. I hope you're doing great with Windows Phone 8.1. I really love the new features of Windows Phone 8.1. Today I'll talk about Windows Phone Map Control and obviously it's Bing Map. In a new update of Windows Phone, there are significant APIs changed from the previous Windows Phone 8.0. Many great features were addedm like Geofencing. So let's get cracking with the entirely new Windows Phone 8.1 Map Control.

Creating a New Project and Add a Map Control

Create a new project and provide it a name (simply “Map” or whatever you want). Now, we'll add our Map Control from the “Toolbox”. Drag the “MapContol” tool from the “Toolbox” and place it in the main Grid.

mapControl
Figure 1

Making Grids

We'll now modify our main Grid to re-size the “MapControl” and to show some other stuffs. First of all, we'll make some rows for other controls.

  1. <Grid HorizontalAlignment="Stretch"
  2. Margin="8,8,8,8" VerticalAlignment="Stretch">
  3. <Grid.RowDefinitions>
  4. <RowDefinition Height="10"/>
  5. <RowDefinition Height="50"/>
  6. <RowDefinition Height="*"/>
  7. <RowDefinition Height="40"/>
  8. </Grid.RowDefinitions>
  9. ...
  10. </Grid>
Listing 1

Here, in line numbers 4, 5, 6 and 7 we've declared four “RowDefinitions”. The first one is 10px in height, the second 50px, the third one is “*” that will cover the rest of the grid space and the last one is 40px.

Adding Controls

Here are the controls we've used in our “MainPage.xaml”.
  1. <Canvas>
  2. <ProgressBar x:Name="progressBar" Grid.Row="0"
  3. IsIndeterminate="True"
  4. Maximum="100" Value="30"
  5. Height="10"
  6. Width="400"/>
  7. </Canvas>
  8. <TextBlock TextWrapping="NoWrap" Grid.Row="1"
  9. Text="Map control"
  10. FontSize="36"
  11. Margin="8,0,0,16" />
  12. <Maps:MapControl x:Name="MyMap" Grid.Row="2"
  13. HorizontalAlignment="Left"
  14. VerticalAlignment="Top"
  15. Height="500"
  16. Width="385"
  17. MapTapped="MyMap_MapTapped" />
  18. <Slider x:Name="mySlider" Grid.Row="3"
  19. Maximum="20"
  20. Minimum="10"
  21. ValueChanged="Slider_ValueChanged" />
Listing 2

We've used a “ProgressBar” control, to indicate when the Map is loading, a “TextBlock” to show the title, a “MapControl” to show the Bing Map and a “Slider” to zoom in and zoom out.

Adding AppBar

We've also used a “BottomAppBar” to locate your current position.
  1. <Page.BottomAppBar>
  2. <CommandBar ClosedDisplayMode="Minimal" Opacity="0.5">
  3. <AppBarButton Label="locate me" Icon="Target" Click="LocateMe_Click" />
  4. </CommandBar>
  5. </Page.BottomAppBar>
Listing 3

I'm not going into the details of adding controls and how they work, if you don't know please feel free to have a look at my previous articles.

So, finally our design will look like this.

map control
Figure 2

Code Behind

It is now time to do the code behind in C#. Let's open “MainPage.xaml.cs” and find the “OnNavigatedTo” method. Modify it as in the following.
  1. public sealed partial class MainPage : Page
  2. {
  3. Geolocator geolocator;
  4. protected async override void OnNavigatedTo(NavigationEventArgs e)
  5. {
  6. // Map Token for testing purpose,
  7. // otherwise you'll get an alart message in Map Control
  8. MyMap.MapServiceToken = "abcdef-abcdefghijklmno";
  9. geolocator = new Geolocator();
  10. geolocator.DesiredAccuracyInMeters = 50;
  11. try
  12. {
  13. // Getting Current Location
  14. Geoposition geoposition = await geolocator.GetGeopositionAsync(
  15. maximumAge: TimeSpan.FromMinutes(5),
  16. timeout: TimeSpan.FromSeconds(10));
  17. MapIcon mapIcon = new MapIcon();
  18. // Locate your MapIcon
  19. mapIcon.Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/my-position.png"));
  20. // Show above the MapIcon
  21. mapIcon.Title = "Current Location";
  22. // Setting up MapIcon location
  23. mapIcon.Location = new Geopoint(new BasicGeoposition()
  24. {
  25. //Latitude = geoposition.Coordinate.Latitude, [Don't use]
  26. //Longitude = geoposition.Coordinate.Longitude [Don't use]
  27. Latitude = geoposition.Coordinate.Point.Position.Latitude,
  28. Longitude = geoposition.Coordinate.Point.Position.Longitude
  29. });
  30. // Positon of the MapIcon
  31. mapIcon.NormalizedAnchorPoint = new Point(0.5, 0.5);
  32. MyMap.MapElements.Add(mapIcon);
  33. // Showing in the Map
  34. await MyMap.TrySetViewAsync(mapIcon.Location, 18D, 0, 0, MapAnimationKind.Bow);
  35. // Disable the ProgreesBar
  36. progressBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
  37. // Set the Zoom Level of the Slider Control
  38. mySlider.Value = MyMap.ZoomLevel;
  39. }
  40. catch (UnauthorizedAccessException)
  41. {
  42. MessageBox("Location service is turned off!");
  43. }
  44. base.OnNavigatedTo(e);
  45. }
  46. ...
  47. }
Listing 4

Our main work is done, now we are ready to write the other methods for it to work perfectly.
  1. // Slider Control
  2. private void Slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
  3. {
  4. if (MyMap != null)
  5. MyMap.ZoomLevel = e.NewValue;
  6. }
  7. // Locate Me Bottom App Bar
  8. private async void LocateMe_Click(object sender, RoutedEventArgs e)
  9. {
  10. progressBar.Visibility = Windows.UI.Xaml.Visibility.Visible;
  11. geolocator = new Geolocator();
  12. geolocator.DesiredAccuracyInMeters = 50;
  13. try
  14. {
  15. Geoposition geoposition = await geolocator.GetGeopositionAsync(
  16. maximumAge: TimeSpan.FromMinutes(5),
  17. timeout: TimeSpan.FromSeconds(10));
  18. await MyMap.TrySetViewAsync(geoposition.Coordinate.Point, 18D);
  19. mySlider.Value = MyMap.ZoomLevel;
  20. progressBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
  21. }
  22. catch (UnauthorizedAccessException)
  23. {
  24. MessageBox("Location service is turned off!");
  25. }
  26. }
  27. // Custom Message Dialog Box
  28. private async void MessageBox(string message)
  29. {
  30. var dialog = new MessageDialog(message.ToString());
  31. await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => await dialog.ShowAsync());
  32. }
Listing 5

Adding Tap Event

One more thing I'd like to add is Map Tapped functionality. We'll add another method that will provide us a cool feature when we tap somewhere and in the Map Icon. It'll show the location details in the Message Dialog Box.

To add this method, go to “MainPage.xaml”, select “MapControl” in the main grid. If you don't see the “Properties” tab, then hit F4 and you'll find it on the left side of Visual Studio.

Now double-click on the “MapTapped” section and it'll automatically generate the method stub for you.

properties
Figure 3

Now complete the “MyMap_MapTapped” method in the “MainPage.xaml.cs”
  1. private async void MyMap_MapTapped(MapControl sender, MapInputEventArgs args)
  2. {
  3. Geopoint pointToReverseGeocode = new Geopoint(args.Location.Position);
  4. // Reverse geocode the specified geographic location.
  5. MapLocationFinderResult result =
  6. await MapLocationFinder.FindLocationsAtAsync(pointToReverseGeocode);
  7. var resultText = new StringBuilder();
  8. if (result.Status == MapLocationFinderStatus.Success)
  9. {
  10. resultText.AppendLine(result.Locations[0].Address.District + ", " + result.Locations[0].Address.Town + ", " + result.Locations[0].Address.Country);
  11. }
  12. MessageBox(resultText.ToString());
  13. }
Listing 6

Adding Location Capability

Our work is now done, but if you run the application in your device or emulator, you'll definitely get an error. Because we've given permission to track our current position to our application. To do this, go to “Package.appxmanifest” and find the “Capabilities” section and tick the “Location” service and save it.

Adding Location Capability
Figure 4

Running the Application

Now if you run the application it'll look exactly like this.

Running the Application

If you tap on the “MapIcon” it'll show the location details on the Message Dialog Box.

Using Polygon for Pushpin

Another thing is, if don't want to use an external image as a “MapIcon” then you can use a custom “Pushpin” like a “Polygon” control. Then you only need to modify the “OnNavigatedTo” method like this:
  1. protected async override void OnNavigatedTo(NavigationEventArgs e)
  2. {
  3. // Map Token for testing purpose,
  4. // otherwise you'll get an alart message in Map Control
  5. MyMap.MapServiceToken = "abcdef-abcdefghijklmno";
  6. geolocator = new Geolocator();
  7. geolocator.DesiredAccuracyInMeters = 50;
  8. try
  9. {
  10. // Getting Current Location
  11. Geoposition geoposition = await geolocator.GetGeopositionAsync(
  12. maximumAge: TimeSpan.FromMinutes(5),
  13. timeout: TimeSpan.FromSeconds(10));
  14. // Create a New Pushpin
  15. var pushpin = CreatePushPin();
  16. MyMap.Children.Add(pushpin);
  17. // Setting up Pushpin location
  18. var location = new Geopoint(new BasicGeoposition()
  19. {
  20. Latitude = geoposition.Coordinate.Latitude,
  21. Longitude = geoposition.Coordinate.Longitude
  22. });
  23. MapControl.SetLocation(pushpin, location);
  24. // Position of the Pushpin
  25. MapControl.SetNormalizedAnchorPoint(pushpin, new Point(0.0, 1.0));
  26. // Showing in the Map
  27. await MyMap.TrySetViewAsync(location, 18D, 0, 0, MapAnimationKind.Bow);
  28. // Disable the ProgressBar
  29. progressBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
  30. // Set the Zoom Level of the Slider Control
  31. mySlider.Value = MyMap.ZoomLevel;
  32. }
  33. catch (UnauthorizedAccessException)
  34. {
  35. MessageBox("Location service is turned off!");
  36. }
  37. base.OnNavigatedTo(e);
  38. }
Listing 7

And the “CreatePushPin” method is given below.
  1. private DependencyObject CreatePushPin()
  2. {
  3. // Creating a Polygon Marker
  4. Polygon polygon = new Polygon();
  5. polygon.Points.Add(new Point(0, 0));
  6. polygon.Points.Add(new Point(0, 50));
  7. polygon.Points.Add(new Point(25, 0));
  8. polygon.Fill = new SolidColorBrush(Colors.Red);
  9. // Return the Polygon Marker
  10. return polygon;
  11. }
Listing 8

Running the Application

Now, if you run the application, the marker will look like this.

output
Figure 6

Map Overlaying

It’s really cool and awesome using a custom Pushpin in Windows Phone 8.1. One more thing I’d like to add is overlaying tiled images on a map. If you want to overlay third-party or custom tiled images on the map and make it customized, then you simply need to use the following lines of code in the “OnNavigatedTo” method at the top.
  1. protected async override void OnNavigatedTo(NavigationEventArgs e)
  2. {
  3. var httpsource = new HttpMapTileDataSource("http://a.tile.openstreetmap.org/{zoomlevel}/{x}/{y}.png");
  4. var ts = new MapTileSource(httpsource);
  5. MyMap.TileSources.Add(ts);
  6. ...
  7. base.OnNavigatedTo(e);
  8. }
Listing 9

And if your run the application, it will provide you a much more graphical view than before with some details.

graphical view
Figure 7

Summary

And that’s it! I hope you understand how to use the “MapControl” in Windows Phone 8.1. Have fun with the Map Control and make some cool applications with it. Read more about Maps and directions (XAML) at: http://bit.ly/X7S7ei

I will be here with a new topic soon. Until then good bye. Have a nice day.

Happy Coding!

Read the original article at: bit.ly/1D6O93Q