Microsoft
provides three main services hosted on the cloud to be used by any
clients, including Windows Phone devices, as shown in the following:
In the following section, you will be using GeoCodeService
to convert any address into geocode (longitude and latitude) and plot
the address on the Bing Maps Silverlight Control. Through the demo, you
will learn to access the Bing Maps service using the credential that you
received when you registered.
The following demo interface
will contain a text box where you can enter an address to be plotted on
the map and a button to invoke a method to convert the address, using
the Bing Maps geocode service. It then plots the geocode onto the Bing
Maps Silverlight control, as shown in Figure 1.
1. Creating the AddressPlottingDemo Application
To set up the BingMapDemo project, follow the steps you've used for previous examples in this book:
Open Microsoft Visual Studio 2010 Express for Windows Phone on your workstation.
Create a new Windows Phone Application by selecting File =>
New Project on the Visual Studio command menu. Select the Windows Phone
Application template, and name the application "AddressPlottingDemo."
In order to use Bing Maps control in Windows Phone, you must reference Microsoft.Phone.Controls.Maps and System.Device.
2. Adding a Service Reference to the Bing Maps GeoCodeService
In order to use the Bing Maps GeoCodeService, you need to add a service reference to your project.
In Solution Explorer, right-click the References folder and choose Add Service Reference.
You see a list of services. In the Namespace text box, enter "BingMapGeoCodeService" and you should see a result similar to Figure 2.
Click OK and you should see BingMapGeoCodeService in Solution Explorer, as shown in Figure 3.
3. Coding the User Interface
AddressPlottingDemo has a very
simple UI, consisting of the textblock for capturing the address, the
button to invoke a method for plotting the address onto the map, and the
Bing Maps Silverlight control.
3.1. Declaring the UI Resources
The namespaces you see in the
following code snippet are typically declared by default when you first
create a Windows Phone project. In particular, namespaces xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" allow you to add common Windows Phone controls to the application main page.
<phone:PhoneApplicationPage
x:Class="AddressPlottingDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:BingMap="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
3.2. Creating the Main Page
The main page consists
of the Bing Maps Silverlight control, button, and address textblock to
capture the user address input. Notice on the bingMap control that CopyrightVisibility and LogoVisibity are set to Collapsed, giving you much more needed real estate on the screen.
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0"
Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle"
Text="AddressPlottingDemo"
Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<BingMap:Map Name="bingMap"
Width="425" Height="513"
Margin="0,0,19,25"
CopyrightVisibility="Collapsed"
LogoVisibility="Collapsed"
VerticalAlignment="Bottom" HorizontalAlignment="Right">
<BingMap:Pushpin Name="bingMapLocator"
Background="Transparent">
<BingMap:Pushpin.Content>
<Ellipse Fill="Red" Width="20" Height="20"
Name="locator" />
</BingMap:Pushpin.Content>
</BingMap:Pushpin>
</BingMap:Map>
<TextBox Height="72" Margin="110,10,6,0" Name="txtAddress"
Text="4237 Salisbury Rd, Suite 114 Jacksonville FL, 32216"
VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left"
Margin="33,32,0,0" Name="textBlock1"
Text="Address" VerticalAlignment="Top" />
<Button Content="Show on map" Height="72"
Name="btnPlot" Margin="17,68,192,556"
Click="btnPlot_Click" />
</Grid>
</Grid>
</phone:PhoneApplicationPage>
4. Coding the Application
One of most important
things to notice in this demo application is its use of the Bing Maps
geocode service to convert a street address to longitude and latitude
measures, so that it can be plotted on the map. Also, in order to use
the Bing Maps geocode service, you must provide the Bing Maps credential
that you created during the registration.
4.1. Specifying the Namespaces
Once the service is referenced, you will be able to declare the namespace of the Bing Maps geocode service, AddressPlottingDemo.BingMapGeoCodeService. Notice also that you are including System.Linq because you will be using Linq to query returned GeoCodeResults with the highest confidence.
using System.Windows;
using Microsoft.Phone.Controls;
using AddressPlottingDemo.BingMapGeoCodeService;
using Microsoft.Phone.Controls.Maps;
using System.Collections.ObjectModel;
using System.Linq;
4.2. Initializing Variables
The GeocodeServiceClient variable _svc
is a proxy class that lets you connect to the Bing Maps geocode service
to geocode the address in order to plot on the map. Notice that you
would need to subscribe to GeocodeCompleted event in order to receive result that contains longitude and latitude.
GeocodeServiceClient _svc;
public MainPage()
{
InitializeComponent();
// instantiate Bing Maps GeocodeService
_svc = new GeocodeServiceClient();
_svc.GeocodeCompleted += (s, e) =>
{
// sort the returned record by ascending confidence in order for
// highest confidence to be on the top.
// Based on the numeration High value is
// at 0, Medium value at 1 and Low volue at 2
var geoResult = (from r in e.Result.Results
orderby (int)r.Confidence ascending
select r).FirstOrDefault();
if (geoResult != null)
{
this.SetLocation(geoResult.Locations[0].Latitude,
geoResult.Locations[0].Longitude,
10,
true);
}
};
}
4.3. Handling the Button Event That Plots Address Data onto the Bing Maps Map
When btnPlot is clicked, you will be making a web service request to the Bing Maps geocode service to convert txtAddress.Text to return geocoordinates in longitude and latitude. When the event, GeoCodeCompleted, is raised you will receive multiple results that contain only the highest confidence level. Using GeoCodeResult you will be making a call to SetLocation that will plot the location on the Bing Maps Silverlight control.
private void SetLocation(double latitude, double longitude,
double zoomLevel, bool showLocator)
{
// Move the pushpin to geo coordinate
Microsoft.Phone.Controls.Maps.Platform.Location location =
new Microsoft.Phone.Controls.Maps.Platform.Location();
location.Latitude = latitude;
location.Longitude = longitude;
bingMap.SetView(location, zoomLevel);
bingMapLocator.Location = location;
if (showLocator)
{
locator.Visibility = Visibility.Visible;
}
else
{
locator.Visibility = Visibility.Collapsed;
}
}
private void btnPlot_Click(object sender, RoutedEventArgs e)
{
BingMapGeoCodeService.GeocodeRequest request =
new BingMapGeoCodeService.GeocodeRequest();
// Only accept results with high confidence.
request.Options = new GeocodeOptions()
{
Filters = new ObservableCollection<FilterBase>
{
new ConfidenceFilter()
{
MinimumConfidence = Confidence.High
}
}
};
request.Credentials = new Credentials()
{
ApplicationId = "Put-Your-BingMap-Credential-Id"
};
request.Query = txtAddress.Text;
// Make asynchronous call to fetch the geo coordinate data.
_svc.GeocodeAsync(request);
}
5. Testing the Finished Application
To test the application, press F5. The result should resemble the display shown in Figure 14-9.
Enter an address into Address text box and press the "Show on map"
button. You should see the pushpin move from its current position to the
coordinates provided by the Bing Maps geocode service.