In my previous post, Using the Bing Maps Web Services for Geocoding Addresses, I talk about geocoding addresses using the Bing Maps Web Services. Now it is time to talk about getting imagery of maps, roads or aerials views for addresses or geocodes.
In order to get started using the Bing Maps Web Services, check out the previous post Getting Started section.
Bing Maps Web Services
Bing Maps Web Services is a set of Web services that allow you to add mapping and search functionality to your application, including location finding, map imagery, and routing capabilities. For example, you can:
Use the Imagery Service to:
- Return a link to a map with a pushpin at a specific location
- Provide a road map or bird’s eye or aerial imagery to you application
Use the Route Service to:
- Get directions that include traffic warnings and route hints between multiple locations.
- Get directions from all major roads to a destination (1-click directions, also referred to as a "party map") and then use the Imagery Service to map those routes.
For this post we will cover the Imagery service.
Just like the Geocode Service, there is a request, MapUriRequest, and response, MapUriResponse, object for the Imagery Service.
In order to get the Uri to display a map in your application you will need to use the imagery service client, ImageryServiceClient. The ImageryServiceClient needs to be instantiated with the WCF endpoint to use, by default it should be ‘BasicHttpBinding_IImageryService’. Then call the GetMapUri method passing your MapUriRequest object.
ImageryServiceClient imageryService = new ImageryServiceClient("BasicHttpBinding_IImageryService");
MapUriResponse mapUriResponse = imageryService.GetMapUri(mapUriRequest);
Building the MapUriRequest
The MapUrilRequest has two properties that need to be populated; the Credentials property which should contain you Bing Maps Id and either the Center, MajorRoutesDestination, or Pushpins property. The code snippet below demonstrates instantiating the MapUriRequest and setting the properties based on values passed into a method (outlined later).
MapUriRequest mapUriRequest = new MapUriRequest
{
Credentials = new Credentials {ApplicationId = appId},
Pushpins = pushpins,
Center = new Location {Latitude = latitude, Longitude = longitude}
};
Now you can customize the options for the map using the MapUriOptions property of the MapUriRequest object. Here is a list of the properties from the MSDN documentation:
| Property name |
Description |
|
DisplayLayers
|
A string array indicating the layer data to display on the map. Optional. The default value is null.
|
| ImageSize |
A SizeOfint Class object specifying the height and width of the image to return. Optional. The default width is 350 and the default height is 350. |
| ImageType |
An ImageType Enumeration value specifying the format of the image to return. Optional. The default value is ImageType.Default, which means the default changes depending on the map style specified. |
| PreventIconCollision |
A bool indicating whether or not to separate pushpin icons that are close to each other on the map so that they are more visible. Optional. The default value is false. |
| Style |
A MapStyle Enumeration value specifying the map style of the image to return. Optional. The default value is MapStyle.Road. |
| UriScheme |
A UriScheme Enumeration value specifying the URI scheme to return. Optional. The default value is UriScheme.Http. |
| ZoomLevel |
An int indicating the zoom level of the map to return. Optional. |
Assigning some of the options:
// Set the map options
MapUriOptions mapUriOptions = new MapUriOptions();
mapUriOptions.Style = MapStyle.Road;
mapUriOptions.ZoomLevel = zoom;
mapUriOptions.ImageSize = new SizeOfint {Height = height, Width = width};
// Set the options property of the request.
mapUriRequest.Options = mapUriOptions;
Now you are ready to call the image service client to get the MapUriResponse.
ImageryServiceClient imageryService = new ImageryServiceClient("BasicHttpBinding_IImageryService");
MapUriResponse mapUriResponse = imageryService.GetMapUri(mapUriRequest);
Here is a helper class,
, which wraps the GetMapUri function with 8 different overloads.
Working with the MapUriResponse
The MapUriResponse object has three properties:
For brevity sake, we will just use the Uri property. You should, though, for good programming practices, check the ResponseSummary property for any exceptions.
string mapUri = Imagery.GetMapUri("YourAppId", 47.62, -122.2);
imgMap.imageUrl = mapUri;
This call retrieve the Uri to use to display a 200x200 road map of the area at latitude 47.62 and longitude -122.2 with a zoom of 14, which is downtown Bellevue, WA.
If you want to add pushpins or markers similar to the above image you will need to populate the an array of PushPin objects. A PushPin object has an IconStyle which is the type of icon to use, a Label which an optional text to display on the pushpin (only works with certain pushpins) and the Location which contains the latitude and longitude that the pushpin should be located at.
That’s it. It seems like a lot of work for a one line call. With the attached Imagery.cs class, a lot of the overhead work was done for you.
For the MVPSummitEvents and Mix10Events site I wanted to create a map of all of the events listed on the site. In order to do that I needed to Geocode all of the addresses for the events. There are several services out there for geocoding an address, Microsoft, Yahoo, and Google provide this service as well as others. I decided to go with the Microsoft Bing services, being a Microsoft MVP.
Getting Started
Let’s get started. MSDN has just about everything you need to get started with using the Bing Map Web Services.
Step 1: The first step is to get a key or token to use in your application for the Bing Maps Web Services application. This can be done by visiting the Bing Maps Account center and clicking on Create a Bing Maps account.
Step 2: If you are using Visual Studio, add a service reference to one or more Bing Maps Web Services that provide the features you need. See the Generating Client Proxy Classes topic and the Bing Maps Web Services Metadata topic.
Whether you used Visual Studio or the svcutil application you should have one file, most likely named VirtualEarthWebServices.cs. The file will contain a bunch of wrapper classes around the Bing Maps Web Services, and the required Windows Communication Foundation (WCF) classes. You will also see the generated configuration settings for the app or web config files.
Step 3: Set every Bing Maps Web Services request a valid Credentials property. You will see more on this in a bit.
Geocoding an Address
There are two properties that are required to successfully request a GeoCode for an address.
- 1) Set the Credential Property of the GeoCodeRequest object
- 2) Set either the Query property or Address property of the GeoCodeRequest object.
Here is a helper function that wraps the call to GeoCodeRequest.
/// <summary>
/// Gets the location.
/// </summary>
/// <param name="appId">The app id.</param>
/// <param name="address">The address.</param>
/// <returns></returns>
public static GeocodeResponse GetGeocodeResponse(string appId, string address)
{
GeocodeRequest geocodeRequest = new GeocodeRequest
{
Credentials = new Credentials {ApplicationId = appId},
Query = address
};
ConfidenceFilter[] filters = new ConfidenceFilter[1];
filters[0] = new ConfidenceFilter {MinimumConfidence = Confidence.High};
GeocodeOptions geocodeOptions = new GeocodeOptions {Filters = filters};
geocodeRequest.Options = geocodeOptions;
GeocodeServiceClient geocodeServiceClient = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
return geocodeServiceClient.Geocode(geocodeRequest);
}
This method will return a GeocodeResponse object. The GeocodeResponse object contains three properties that are populated based on the query.
To keep this article short(er) I will just cover the Results object. Depending on the Confidence filter and Geocode options that were set in the call you could receive more than one result.
Let’s assume that we only want to work with the first result and get the Geocode for “1 Microsoft Way, Redmond, WA”. We simply call the static method of GetGeocodeResponse and pass in the Bing Maps API key and the address to search for.
var address = "1 Microsoft Way, Redmond, WA";
GeocodeResponse response = GetGeocodeResponse(appId, address);
Assuming the address was found we can now work with the properties of the GeocodeResult class to find out the Geocode. The Geocode is located in the Locations property which is an array of GeocodeLocation objects. If the Count of the Locations is greater than one, let’s just take the first one and update the txtLatitude and txtLongitude objects.
if (response.Results != null)
{
var geocodeLocation = response.Results[0].Locations[0];
if (geocodeLocation != null)
{
txtLatitude.Value = geocodeLocation.Latitude;
txtLongitude.Value = geocodeLocation.Longitude;
}
else
{
txtLatitude.Value = txtLongitude.Value = 0;
}
}
That’s it. Next up, using the Bing Maps Web Services for getting map images.