In my last post I showed you how to get started using the Bing Maps WPF control by creating an earthquake application. Now I want to introduce you to the Bing Maps SOAP Services. The Bing Maps SOAP Services is a set of programmable SOAP services that allow you to integrate maps and imagery, driving directions, distance calculations, and other location intelligence into your applications, business processes, and Web sites.
Let’s start with the Geocode Service which is used to match addresses, places, and geographic entities to latitude and longitude coordinates on the map, as well as return location information for a specified latitude and longitude coordinate. We will create a simple application that allows you to enter an address and place a pushpin at that location. First thing is first:
You MUST have a Bing Maps API key in order to use any of the SOAP services. Now that you have that out of the way let’s write an application. Create a new WPF application targeting the .NET 4.0 framework. Add a reference to the Microsoft.Maps.MapControl.WPF.dll. This will most likely be located in Program Files or Program Files (x86) –> Bing Maps WPF Control –> Beta –> Libraries.
Open up your App.xaml. You need to add an ApplicationIdCredentialsProvider as a resource and enter your ApplicationId:
Now create a very simple UI that will accept an address and a button to perform the geocoding:
The next thing we need to do is add a new Service Reference to the project and point to the following service:
Give your service a name (I called mine BingMapsService) and just for fun, in the “Add Service Reference” dialog, click the “Advanced” button and click “Generate asynchronous operations”.
Next we need to create a ViewModel to support our View. This is a WPF application after all. This ViewModel will need a command for the button that will perform the geocoding, and a property that will represent the result of the service that the UI will use to map the address. It should resemble something like this:
I want to point out that the DelegateCommand<T> is a very simple ICommand implementation and should not be used in production applications. Here is the code:
Let’s hook our UI up to our command. it should look something like this:
Notice that we are using the text of the TextBox as the CommandParameter. Next, we need to implement the command:
In this command we are simply creating an instance of the service client, creating a GeocodeRequest, setting the credentials using the ApplicationId we have stored in the App.xaml, and then using the address as the Query for the request. When the call to the service is completed we are setting the GeocodeResult property to the first element in the results.
Now the tricky part. We want to place a Pushpin on the address that was entered and then move the map to that location. We also need to make sure that when another address is entered, we clear any previous Pushpins that may exist on the map. We also have to be aware that other elements my be on the map and we don’t want to accidentally alter those elements. Oh and did I mention this was an MVVM application and this has to be done with just data binding?
The approach that I decided to go with is to use Attached Properties. So I created two attached properties; one for the GeocodeResult and another for a MapLayer that will be dedicated to the GeocodeResult. This will allow us to create a MapLayer that is specific to our GeocodeResut and not alter any other elements that may be on the map. Let’s check out the code.
Notice that when the GeocodeResult changes we get the Location and create a pushpin for that location. We also set the tooltip to the FormattedAddress of the GeocodeResult. So when we hover over the pushpin we will see a nice little tooltip of the address. Next we try to get the GeocodeResultLayer from the map, if it is null this means it doesn’t exist on the map yet so we create one and assign it accordingly. We clear the layer child elemnts and then add out pushpin. The last thing we do is call the SetView method of the Map control passing in the location and the current ZoomLevel.
The final step is to use our AttachedProperty on the map. Be sure to create a namespace for the MapInteractivity class and define it as follows:
One last thing. Be sure to remember to set your DataContext of your View to the ViewModel we have created:
That’s it. You now have an application the can map (geocode) an address using the Bing Maps WPF Control and the Geocoding SOAP Service. Oh and we are doing this all with MVVM and data binding which is my favorite part. Be sure to Download the Source and start playing around.