Bing Maps Using Web API

Bing Maps recently retired their SOAP web service interface. The new interface is a REST service and the JSON Data Contracts define the response interface. There is a sample program Parsing REST Services JSON Responses that I used as a starting point for my code which is located here.

Bing Maps Key

To use the Bing Maps interface you will need a key. See Getting a Bing Maps key if you don’t have one already. In my code I read the key from the environment variable named “BingMapsKey”:

1
_bingMapsKey = Environment.GetEnvironmentVariable("BingMapsKey");

Building and sending the request URI

The base of the URI for all requests is:

1
private const string BingRestLocation = "http://dev.virtualearth.net/REST/v1/";

With this base we add “Locations” then the search string and add the key at the end. Be sure to use WebUtility.UriEncode on your location search.

1
var urlRequest = $"{BingRestLocation}Locations/{place}?key={_bingMapsKey}";

Next we make a call with Web API to the service using the MakeRequestWebApi function with “New York” in the place string. The Tuple that is returned has a status string and Bing Response object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static Tuple<Response, string> MakeRequestWebApi(string requestUrl)
{
var httpResponseMessage = Client.GetAsync(requestUrl).Result;

if (!httpResponseMessage.IsSuccessStatusCode)
{
return new Tuple<Response, string>(null, $"Response Status: {httpResponseMessage.StatusCode}");
}

var jsonString = httpResponseMessage.Content.ReadAsStringAsync().Result;

using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
var deserializer = new DataContractJsonSerializer(typeof (Response));
return new Tuple<Response, string>((Response) deserializer.ReadObject(ms), "success");
}
}

Parsing the return

Once we get a Response object back, we have to cast to the object that we requested, in this case a Location. The other objects are Route, Traffic Incident, CompressedPointList, ElevationData, or SeaLevelData.

The function ProcessLocationResponse is from the original program and shows the locations found with high confidence and their geocode points.

Retrieving a Route

I also needed to get route instructions from the Bing Map interface. I added a Location search for three more specific addresses to make a cross country musical journey from the Brill Building in New York to the Whiskey A Go Go in LA with a stop by the Stax Studios in Memphis.

1
2
3
const string brillBuildingAddress = "1619 Broadway New York NY 10019";
const string staxStudiosAddress = "926 E McLemore Ave, Memphis, TN 38126";
const string whiskyaGoGoAddress = "8901 W. Sunset Blvd West Hollywood, CA 90069";

The Route parameter requires at least two waypoints in the request. The MakeWayPointString takes a List of Locations and builds the string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static string MakeWaypointString(List<Location> waypoints)
{
var waypointsSb = new StringBuilder();
var waypointCntr = 1;

foreach (var waypoint in waypoints)
{
waypointsSb.Append($"wp.{waypointCntr}=");
waypointsSb.Append($"{waypoint.Point.Coordinates[0]},");
waypointsSb.Append($"{waypoint.Point.Coordinates[1]}&");
waypointCntr++;
}
return waypointsSb.ToString();
}

The ProcessRouteResponse parses the route information and shows the instructions and coordinates of each itinerary item in both legs of the trip.