MapPoint-GeocodingAndReverseGeocoding

32
Upgrading to Bing Maps From MapPoint Web Service Geocoding and Reverse Geocoding

Transcript of MapPoint-GeocodingAndReverseGeocoding

Page 1: MapPoint-GeocodingAndReverseGeocoding

Upgrading to Bing Maps From MapPoint Web Service

Geocoding and Reverse Geocoding

Page 2: MapPoint-GeocodingAndReverseGeocoding

2

Table of Contents

Purpose ..................................................................................................................................................................................................................... 4

Introduction ............................................................................................................................................................................................................ 4

Geocoding ............................................................................................................................................................................................................... 4

Geocoding Coordinates ................................................................................................................................................................................. 4

Parsing Address Data ..................................................................................................................................................................................... 6

Geocoding Accuracy ....................................................................................................................................................................................... 7

Best Map View ................................................................................................................................................................................................... 8

Geocoding Addresses with Placeholders ............................................................................................................................................... 8

Filtering Geocoding Results ......................................................................................................................................................................... 9

Geocoding Example ........................................................................................................................................................................................ 9

Reverse Geocoding ............................................................................................................................................................................................ 10

Location Entity Types .................................................................................................................................................................................... 11

Reverse Geocoding Example ..................................................................................................................................................................... 11

Conclusion ............................................................................................................................................................................................................. 12

Appendix A: Bing Maps Keys ......................................................................................................................................................................... 13

Appendix B: Code Listings for .NET C# ...................................................................................................................................................... 15

Bing Maps Geocoding Example (C#) ...................................................................................................................................................... 15

Bing Maps Reverse Geocoding Example (C#) ..................................................................................................................................... 15

GetJsonResponse() and GetXmlResponse() (C#) ............................................................................................................................... 16

Bing Maps Sample JSON Classes (C#) ................................................................................................................................................... 17

Appendix C: Response Listings...................................................................................................................................................................... 24

Bing Maps Geocoding Response (JSON) .............................................................................................................................................. 24

Bing Maps Geocoding Response (XML) ................................................................................................................................................ 25

Bing Maps Reverse Geocoding Response (JSON) ............................................................................................................................. 26

Appendix D: Code Listings for VB.NET ....................................................................................................................................................... 28

Bing Maps Geocoding Example (VB.NET)............................................................................................................................................. 28

Bing Maps Reverse Geocoding Example (VB.NET) ........................................................................................................................... 28

GetJsonResponse() (VB.NET) ...................................................................................................................................................................... 29

Appendix E: Code Listings for Java .............................................................................................................................................................. 29

Page 3: MapPoint-GeocodingAndReverseGeocoding

3

Bing Maps Geocoding Example (Java) ................................................................................................................................................... 29

Bing Maps Reverse Geocoding Example (Java) .................................................................................................................................. 30

getResponse (Java) ........................................................................................................................................................................................ 30

Appendix F: Code Listings for PHP .............................................................................................................................................................. 31

Bing Maps Geocoding Example (PHP) ................................................................................................................................................... 31

Bing Maps Reverse Geocoding Example (PHP) .................................................................................................................................. 32

Page 4: MapPoint-GeocodingAndReverseGeocoding

4

Purpose

The purpose of this guide is to discuss advanced topics in geocoding and reverse geocoding, explore the

differences between geocoding in MapPoint versus Bing Maps, and highlight how to take advantage of new,

enhanced Bing Maps geocoding features in your applications. This guide is designed for technical audiences and

builds upon the content found in the introductory guide Upgrading from MapPoint Web Service to Bing Maps that

is available on the MapPoint Web Service Upgrade Portal.

Introduction

Geocoding is the process of determining the geographic coordinates (latitude and longitude) of an address,

location, or point-of-interest. Reverse geocoding is the process of determining the closest address or location to

a provided set of geographic coordinates (latitude and longitude). In this guide, you will learn about the

differences in geocoding and reverse geocoding methodology between MapPoint Web Service (MWS) and the

Bing Maps Locations API. Batch geocoding and batch reverse geocoding are covered in a separate article, which is

also available on the MapPoint Web Service Upgrade Portal.

The remainder of this guide discusses geocoding and reverse geocoding in further detail and provides advice for

upgrading from MapPoint Web Service to the Bing Maps Locations API.

Geocoding

Geocoding services return latitude and longitude coordinates when provided with a street address or other

location. Both MapPoint Web Service and Bing Maps provide geocoding (and reverse geocoding) functionality.

The most significant change, between MWS and Bing Maps, in how geocoding is accomplished is the style of the

API. MapPoint Web Service Customer Data Service is a SOAP API which includes overhead and wrappers

associated with SOAP architecture. The Bing Maps Locations API is a REST API, which is leaner, easier to use, and

readily accessed from various programming languages. For further information about the differences between

SOAP and REST, refer to this MSDN article.

Geocoding Coordinates

The most basic use of both the MWS and Bing Maps geocoding functionality is to obtain latitude and longitude

coordinates for a specified address, and then to perform follow-up actions with those coordinates (e.g., place a

marker on a map at those coordinates).

Page 5: MapPoint-GeocodingAndReverseGeocoding

5

In MapPoint Web Service, you would use the FindAddress method to geocode an address string (e.g., “1

Microsoft Way, Redmond, WA”). FindAddress returns a FindResults object, which contains a LatLong property

representing the coordinates found for the specified address.

In the Bing Maps Locations API, the response returned from a call to the API includes a Point element, which

stores the latitude and longitude coordinates for the specified address.

Listing 1 shows an example of a structured URL that geocodes an address using the Bing Maps Locations API.

http://dev.virtualearth.net/REST/v1/Locations/US/WA/98052/Redmond/1 Microsoft Way?key=BingMapsKey

Listing 1 Geocoding an address using a structured URL

Remember that, for the examples in this article, you must replace the parameter value BingMapsKey with your

Bing Maps Key. For more information about Bing Maps Keys, see Appendix A: Bing Maps Keys in this article.

Listing 2 shows the JSON response that will be returned from this call. The Point element is highlighted in bold.

{ "authenticationResultCode": "ValidCredentials", "brandLogoUri": "http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png", "copyright": "Copyright © 2010 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.", "resourceSets": [ { "estimatedTotal": 1, "resources": [ { "__type": "Location:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1", "bbox": [ 47.635884282429323, -122.13737419709076, 47.643609717570676, -122.12208780290925 ], "name": "1 Microsoft Way, Redmond, WA 98052-8300", "point": { "type": "Point", "coordinates": [ 47.639747, -122.129731 ] }, "address": { "addressLine": "1 Microsoft Way", "adminDistrict": "WA",

Page 6: MapPoint-GeocodingAndReverseGeocoding

6

"adminDistrict2": "King Co.", "countryRegion": "United States", "formattedAddress": "1 Microsoft Way, Redmond, WA 98052-8300", "locality": "Redmond", "postalCode": "98052-8300" }, "confidence": "High", "entityType": "Address" } ] } ], "statusCode": 200, "statusDescription": "OK", "traceId": "6dd03a0ca64e4b239f23242d2a478353|EWRM001672|02.00.59.1700|EWRMSNVM001808" }

Listing 2 JSON response from Bing Maps Locations API request

Note that the Locations API will also return XML response data (versus JSON) if you include the parameter o=xml

in the request URL. You can find a full listing of the equivalent XML to the response shown in Listing 2 in the

Appendix. Refer to the API documentation for more information on output parameters.

The remainder of this Guide will discuss some of the other information that may be requested from the Locations

API. While we will mainly focus on the different ways you can format request URLs in order to obtain the

information you require, you can also find information about how to write code to make a request to the

Locations API and parse the response data.

Parsing Address Data

In addition to geographic coordinates, both MapPoint Web Service and Bing Maps provide several other

important pieces of data when a geocode operation is performed on an address. One of these is a parsed

address, which is a representation of the structured or unstructured address passed into the geocoding service,

broken down into its individual components (street address, city, zip code, etc.).

MapPoint Web Service has two different methods that are commonly used to geocode addresses.

The MWS FindAddress method takes an address as a string and returns geographic coordinates

(latitude and longitude) for that address as a LatLong property in the response object.

The MWS ParseAddress method takes an address as a string and returns an Address object, with

various components of the address (street, city, country, etc.) in different properties so that they can be

extracted easily and worked with separately.

The Bing Maps Locations API parses addresses as part of a geocoding request; no additional address parsing calls

are necessary in order to isolate different components of an address. The JSON response in Listing 3 includes an

address element containing the parsed address; the full response can be found in the Appendix.

Page 7: MapPoint-GeocodingAndReverseGeocoding

7

"address": { "addressLine": "1 Microsoft Way", "adminDistrict": "WA", "adminDistrict2": "King Co.", "countryRegion": "United States", "formattedAddress": "1 Microsoft Way, Redmond, WA 98052-8300", "locality": "Redmond", "postalCode": "98052-8300" },

Listing 3 JSON address element returned from the Bing Maps Locations API

Both the MWS Address class and the address element in the Bing Maps Locations API response include much of

the same information. For reference, Figure 1 shows a comparison of the parsed address information provided in

each of the APIs.

MapPoint Geocoding Address Class Bing Geocode Location Resources Address

AddressLine AddressLine

PrimaryCity Locality

SecondaryCity N/A

Subdivision AdminDistrict

PostalCode PostalCode

CountryRegion CountryRegion

N/A AdminDistrict2

N/A FormattedAddress

Figure 1 Geocoding address return values

Note that AdminDistrict2 is only available in Bing Maps. AdminDistrict2 contains additional information about

the district in which the address exists (e.g., the county in Figure 1). FormattedAddress contains a complete

address string representing the geocoded address; this string can be useful as a result of a search for which not all

address information was provided in the original request (see the Geocoding Example later in this guide for

details).

Geocoding Accuracy

In MWS, the FindResult.Score property supplies the estimated level of accuracy for a given search result. The

score ranges between 1.0 and 0.0, between and exact match and no match respectively.

The Bing Locations API Location response contains a Confidence element with one of the following values: High,

Medium, Low and Unknown. The JSON response in the Appendix shows a confidence value of High for the single

result. For less specific searches, the JSON response may include multiple results.

Page 8: MapPoint-GeocodingAndReverseGeocoding

8

Best Map View

After geocoding an address, you will often want to display it on a map. In order to do this, you need to know the

best map view to display the geocoded address, including the ideal dimensions of the map as well as the scale or

zoom level it should be displayed at. For example, street addresses are best displayed at a higher zoom level,

whereas geocoded cities might require a much lower zoom level.

The MWS Location.BestMapView Property references a MapViewRepresentations object which offers a

bounding rectangle, height and width, or scale. This property can be used to specify the view that should be used

when displaying the geocoded location on a map.

The Bing Locations API result also returns a bounding box element (bbox in the JSON response). A bounding box

contains SouthLatitude, WestLongitude, NorthLatitude and EastLongitude values in degrees representing the

bottom left (southwest) and top right (northeast) corners of a rectangle. These coordinates can be passed into the

Bing Maps Imagery API in order to display a map of a specific size.

Geocoding Addresses with Placeholders

On occasion, you may not have all the parts of an address when making a geocoding request. If this is the case,

you can substitute a hyphen (-) for the missing parameter in the REST request. For example, the request in Listing

4 illustrates how to geocode a location whose parameters are missing a postalcode (zip code) and an

AdminDistrict (State):

http://dev.virtualearth.net/REST/v1/Locations/US/-/-/Redmond/1 Microsoft Way?key=BingMapsKey

Listing 4 A geocode request with placeholders using a structured URL

The response may include multiple results if the geocoder is unable to determine a single set of coordinates that

matches the request.

The Bing Maps Locations API also allows requests that use an unstructured format, supporting searches without

having to use hyphens to represent missing information. In an unstructured request, you simply include each

piece of information you do have as a parameter on the request, as shown in Listing 5.

http://dev.virtualearth.net/REST/v1/Locations?countryRegion=US&locality=Redmond&addressLine=1 Microsoft Way&key=BingMapsKey

Listing 5 A geocode request using an unstructured URL

Keep in mind that with structured URLs, the hyphen has to be explicitly added for missing parameters, but for

unstructured URLs, all parameters are optional and you can simply omit them.

Page 9: MapPoint-GeocodingAndReverseGeocoding

9

Filtering Geocoding Results

In MWS, you can include a FindOptions object with your FindAddress request, which can be configured to filter

or limit the geocoding results.

The Bing Maps Locations API has no direct equivalent to MWS FindOptions. If you use FindOptions

SearchContent to restrict the geographical area searched, in Bing Maps you can use the countryRegion

parameter to restrict the search to certain countries. You can also customize the Bing Maps geocoding responses

using Bing Maps common parameters. The output format can be chosen with the output parameter (e.g.

output=xml). You can change the culture of the response with the culture parameter (e.g. culture=en-GB). For

other ways to customize Bing Maps responses, please refer to the API documentation.

Geocoding Example

The .NET C# code sample in Listing 6 demonstrates how to make a geocoding request and process the JSON

results. In this example, no postal code or street number is provided in the geocoding request address; this causes

Bing Maps to return multiple results, which must be taken into account when processing. Note the latitude,

longitude, and bounding box are found in each Location result.

Important: The full code listings for all samples in this article, in .NET C#, VB.NET, Java, and PHP can be found in

the Appendix.

string textAddress = "1st Ave, Seattle, WA, US"; Console.WriteLine(string.Format("Matches for '{0}':", textAddress)); // Create a Bing Maps REST request. string requestUrl = string.Format( "http://dev.virtualearth.net/REST/v1/Locations/{0}?key={1}", textAddress, BingMapsKey); // Send the request and parse the response. BingMapsRestV1.Response jsonResponse = GetJsonResponse(requestUrl); // Display all matches to the user. foreach (Location location in jsonResponse.ResourceSets[0].Resources) { Console.WriteLine("Confidence: {0}; Type: {1}; Address: {2}", location.Confidence, location.EntityType, location.Address.FormattedAddress); } // Get the info on the first match so we can show it on a map. Location firstMatchLocation = (Location)jsonResponse.ResourceSets[0].Resources[0]; double centerLatitude = firstMatchLocation.Point.Coordinates[0]; double centerLongitude = firstMatchLocation.Point.Coordinates[1]; double northLatitude = firstMatchLocation.BoundingBox.NorthLatitude; double westLongitute = firstMatchLocation.BoundingBox.WestLongitude; double southLatitude = firstMatchLocation.BoundingBox.SouthLatitude; double eastLongitude = firstMatchLocation.BoundingBox.EastLongitude;

Page 10: MapPoint-GeocodingAndReverseGeocoding

10

Listing 6 Code for constructing a REST request and to loop through the result set

Listing 7 contains example code for making an HTTP request to Bing Maps and deserializing the JSON response.

The example JSON classes used for deserialization can be found in the full code sample in the Appendix.

/// <summary> /// Send the request to the Bing Maps REST API /// and deserialize the JSON response. /// </summary> public static BingMapsRestV1.Response GetJsonResponse(string requestUrl) { HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest; using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { if (response.StatusCode != HttpStatusCode.OK) throw new Exception(String.Format( "Server error (HTTP {0}: {1}).", response.StatusCode, response.StatusDescription)); DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer( typeof(BingMapsRestV1.Response)); object objResponse = jsonSerializer.ReadObject( response.GetResponseStream()); BingMapsRestV1.Response jsonResponse = objResponse as BingMapsRestV1.Response; return jsonResponse; } }

Listing 7 Example code for deserializing a Bing Maps REST response.

Reverse Geocoding

Reverse geocoding services return an address or set of addresses when provided with latitude and longitude

coordinates. Both MapPoint Web Service (MWS) and Bing Maps provide reverse geocoding functionality

In MapPoint Web Service (MWS), the FindServiceSoap method GetLocationInfo searches for geographic

entities and addresses when passed longitude and latitude coordinates.

The Bing Maps Locations API uses REST calls like the one shown in in Listing 8 to retrieve location information

from latitude and longitude coordinates:

Page 11: MapPoint-GeocodingAndReverseGeocoding

11

http://dev.virtualearth.net/REST/v1/Locations/47.639747,-122.129731?key=BingMapsKey

Listing 8 Sample Bing Maps Locations API reverse geocoding call

Location Entity Types

The MapPoint Web Service GetLocationInfo method takes an optional GetInfoOptions parameter that can help

determine what types of entities are returned. The entity types in MWS range from Island to Sea to Park to Forest

but are generally specific to a data source. For example the MapPoint.NA data source has 187 entity types.

The Bing Maps Locations API supports an optional comma separated list of entity types which include:

Address

Neighborhood

PopulatedPlace

Postcode1

AdminDivision1

AdminDivision2

CountryRegion

Bing Maps entities are more general in nature than the MWS entity types. By passing in one or more entity types,

you can filter the results. Note that the aforementioned Bing Maps entity types are in order from most specific to

general. If multiple entity types are combined and more than one type is found, only the most specific entity types

will be returned. The exception to this is when a request combines the entity types Neighborhood and

PopulatedPlace, in which both types would be returned if found.

The Bing Maps Locations API call in Listing 9 requests PopulatedPlace entity types from a longitude and latitude

coordinate set.

http://dev.virtualearth.net/REST/v1/Locations/47.640545555176843,-122.12934213381237?includeEntityTypes=PopulatedPlace&o=xml&key=BingMapsKey

Listing 9 Specifying an entity type for a reverse geocoding call

Reverse Geocoding Example

Listing 10 shows C# code to retrieve entities based on coordinates. Note that the type of entity returned is

restricted using the includeEntityTypes parameter. Here AdminDivision1 and AdminDivision2 have been

selected, meaning you wish nothing more specific to be returned except for the State and County associated with

the geographic coordinates.

string latitude = "47.640545555176843"; string longitude = "-122.12934213381237"; string includedEntityTypes = "AdminDivision1,AdminDivision2";

Page 12: MapPoint-GeocodingAndReverseGeocoding

12

string requestUrl = string.Format( "http://dev.virtualearth.net/REST/v1/" + "Locations/{0},{1}?includeEntityTypes={2}" + "&key={3}", latitude, longitude, includedEntityTypes, BingMapsKey); BingMapsRestV1.Response response = GetJsonResponse(requestUrl); //Only the most specific entity type is returned BingMapsRestV1.Location location = response.ResourceSets[0].Resources[0] as BingMapsRestV1.Location; //In this case AdminDivision1 is returned string name = location.Name;

Listing 10 Reverse geocoding request for AdminDivision1 and AdminDivision2 using Bing Maps REST API

Conclusion

The Bing Maps Locations API offers full-featured geocoding and reverse geocoding functionality, using a much

simpler REST interface and standardized response types than those of MapPoint Web Service. As a MapPoint Web

Service customer, the benefits of upgrading your application to Bing Maps are numerous. Over the coming

months, we invite you to use this and other upgrade guides and resources, and to take advantage of other

opportunities we will make available to make your move to Bing Maps efficient and straightforward.

Please refer to the MapPoint Web Service Upgrade Portal for more information and resources for facilitating the

upgrade to Bing Maps.

Page 13: MapPoint-GeocodingAndReverseGeocoding

13

Appendix A: Bing Maps Keys

In Bing Maps, you no longer need to work with two different environments for staging and production

applications. However, the best approach for developing with Bing Maps is to generate two Bing Maps keys for

any application being developed: one for development and one for production. When moving between staging

and production, all you need to change is the Bing Maps key that you use to access the services from your code;

the Bing Maps REST service URIs and environments remain the same.

The recommended steps for creating your Bing Maps Key are as follows.

1. Create a Bing Maps account at the Bing Maps Account Center.

2. Generate a Bing Maps key. When creating this key, set the “key type” to “developer” and set its associated

URL to http://localhost.

a. We invite you to use the “developer” key type and free use terms outlined in the Bing Maps Terms of

Use (TOU) as you transition to Bing Maps. Production applications outside the free use thresholds in

the TOU will need a Bing Maps Enterprise account. For assistance with Bing Maps licensing, please

contact [email protected] (including your Bing Maps Account Center ID) and identify yourself

as a MapPoint upgrade customer.

b. Enterprise customers are advised to use keys of type “developer” for all pre-production application

testing.

3. Send an email including this new (or existing if you are already using Bing Maps) Bing Maps Account

Center Acct ID to your Bing sales professional to “activate” your account and to ensure proper access

privileges to Bing services and enterprise support options. If you do not have your sales person’s email

address, [email protected] can help you acquire this information.

Prior to transitioning your existing application or starting development on a new Bing Maps application, you

should generate a Bing Maps key using the Bing Maps Account Center (http://www.bingmapsportal.com/) as

shown in Figure 2. A Bing Maps key must be registered against a particular domain; often, for development

purposes, you will register your key against http://localhost using the “Developer” key type.

When the mapping application is tested and ready to be deployed to a production environment, a production

Bing Maps key is required, which can also be obtained from the Bing Maps Account Center using the “Enterprise”

type. Alternatively, you can use the “Update” feature in the Bing Maps Account Center to change your “Developer”

key to “Enterprise” (see Figure 2 for example). The production key must be registered against your production

domain, though for desktop and mobile applications http://localhost can still be used in production. Your

application should be re-tested to ensure that no issues arise from the key change and you can then complete

your production deployment.

By default, each Bing Maps account is limited to five (5) Bing Maps keys. However, additional keys can be

provided if required. Contact the Bing Maps Account Administrators at [email protected] if you require

additional keys.

Page 14: MapPoint-GeocodingAndReverseGeocoding

14

Figure 2 Bing Maps Account Center – Update Key Feature

Useful Links

Bing Maps Portal (account setup, reporting, and key management)

http://www.bingmapsportal.com/

Getting a Bing Maps Key

http://msdn.microsoft.com/en-us/library/ff428642.aspx

Viewing Bing Maps Usage Reports

http://msdn.microsoft.com/en-us/library/ff859477.aspx

Page 15: MapPoint-GeocodingAndReverseGeocoding

15

Appendix B: Code Listings for .NET C#

This section contains extended sample code and code for helper classes referenced in this document.

Bing Maps Geocoding Example (C#)

The following example code demonstrates geocoding with multiple results returned.

string textAddress = "1st Ave, Seattle, WA, US"; Console.WriteLine(string.Format("Matches for '{0}':", textAddress)); // Create a Bing Maps REST request. string requestUrl = string.Format( "http://dev.virtualearth.net/REST/v1/Locations/{0}?key={1}", textAddress, BingMapsKey); // Send the request and parse the response. BingMapsRestV1.Response jsonResponse = GetJsonResponse(requestUrl); // Display all matches to the user. foreach (Location location in jsonResponse.ResourceSets[0].Resources) { Console.WriteLine("Confidence: {0}; Type: {1}; Address: {2}", location.Confidence, location.EntityType, location.Address.FormattedAddress); } // Get the info on the first match so we can show it on a map. Location firstMatchLocation = (Location)jsonResponse.ResourceSets[0].Resources[0]; double centerLatitude = firstMatchLocation.Point.Coordinates[0]; double centerLongitude = firstMatchLocation.Point.Coordinates[1]; double northLatitude = firstMatchLocation.BoundingBox.NorthLatitude; double westLongitute = firstMatchLocation.BoundingBox.WestLongitude; double southLatitude = firstMatchLocation.BoundingBox.SouthLatitude; double eastLongitude = firstMatchLocation.BoundingBox.EastLongitude;

Bing Maps Reverse Geocoding Example (C#)

The following example code reverse geocodes a point and restricts the entity types returned.

string latitude = "47.640545555176843"; string longitude = "-122.12934213381237"; string includedEntityTypes = "AdminDivision1,AdminDivision2"; string requestUrl = string.Format( "http://dev.virtualearth.net/REST/v1/" + "Locations/{0},{1}?includeEntityTypes={2}" + "&key={3}", latitude, longitude,

Page 16: MapPoint-GeocodingAndReverseGeocoding

16

includedEntityTypes, BingMapsKey); BingMapsRestV1.Response response = GetJsonResponse(requestUrl); //Only the most specific entity type is returned BingMapsRestV1.Location location = response.ResourceSets[0].Resources[0] as BingMapsRestV1.Location; //In this case AdminDivision1 is returned string name = location.Name;

GetJsonResponse() and GetXmlResponse() (C#)

The following methods are used to send a request to Bing and return JSON or XML.

/// <summary> /// Send the request to the Bing Maps REST API /// and deserialize the JSON response. /// </summary> public static BingMapsRestV1.Response GetJsonResponse(string requestUrl) { HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest; using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { if (response.StatusCode != HttpStatusCode.OK) throw new Exception(String.Format( "Server error (HTTP {0}: {1}).", response.StatusCode, response.StatusDescription)); DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer( typeof(BingMapsRestV1.Response)); object objResponse = jsonSerializer.ReadObject( response.GetResponseStream()); BingMapsRestV1.Response jsonResponse = objResponse as BingMapsRestV1.Response; return jsonResponse; } } /// <summary> /// Send the request to the Bing Maps REST API and deserialize the XML response. /// </summary> public static XmlDocument GetXmlResponse(string requestUrl)

Page 17: MapPoint-GeocodingAndReverseGeocoding

17

{ HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest; using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { if (response.StatusCode != HttpStatusCode.OK) throw new Exception(String.Format("Server error (HTTP {0}: {1}).", response.StatusCode, response.StatusDescription)); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(response.GetResponseStream()); return xmlDoc; } }

Bing Maps Sample JSON Classes (C#)

The following code listing contains the sample JSON classes used throughout the examples in this article to

deserialize Bing Geocode Dataflow API JSON responses.

using System.Runtime.Serialization; namespace BingMapsMigrationCsExamples.BingMapsRestV1 { [DataContract] public class Address { [DataMember(Name = "addressLine")] public string AddressLine { get; set; } [DataMember(Name = "adminDistrict")] public string AdminDistrict { get; set; } [DataMember(Name = "adminDistrict2")] public string AdminDistrict2 { get; set; } [DataMember(Name = "countryRegion")] public string CountryRegion { get; set; } [DataMember(Name = "formattedAddress")] public string FormattedAddress { get; set; } [DataMember(Name = "locality")] public string Locality { get; set; } [DataMember(Name = "postalCode")] public string PostalCode { get; set; } }

Page 18: MapPoint-GeocodingAndReverseGeocoding

18

public enum AuthenticationResultCode { None, NoCredentials, ValidCredentials, InvalidCredentials, CredentialsExpired, NotAuthorized, } [DataContract] public class BoundingBox { [DataMember(Name = "southLatitude")] public double SouthLatitude { get; set; } [DataMember(Name = "westLongitude")] public double WestLongitude { get; set; } [DataMember(Name = "northLatitude")] public double NorthLatitude { get; set; } [DataMember(Name = "eastLongitude")] public double EastLongitude { get; set; } } public enum Confidence { High, Medium, Low, Unknown, } [DataContract(Namespace = "http://schemas.microsoft.com/search/local/ws/rest/v1")] public class DataflowJob : Resource { [DataMember(Name = "completedDate")] public string CompletedDate { get; set; } [DataMember(Name = "createdDate")] public string CreatedDate { get; set; } [DataMember(Name = "status")] public string Status { get; set; } [DataMember(Name = "errorMessage")] public string ErrorMessge { get; set; } [DataMember(Name = "failedEntityCount")] public int FailedEntityCount { get; set; } [DataMember(Name = "processedEntityCount")] public int ProcessedEntityCount { get; set; }

Page 19: MapPoint-GeocodingAndReverseGeocoding

19

[DataMember(Name = "totalEntityCount")] public int TotalEntityCount { get; set; } } [DataContract] public class Hint { [DataMember(Name = "hintType")] public string HintType { get; set; } [DataMember(Name = "value")] public string Value { get; set; } } [DataContract] public class Instruction { [DataMember(Name = "maneuverType")] public string ManeuverType { get; set; } [DataMember(Name = "text")] public string Text { get; set; } //[DataMember(Name = "value")] //public string Value { get; set; } } [DataContract] public class ItineraryItem { [DataMember(Name = "travelMode")] public string TravelMode { get; set; } [DataMember(Name = "travelDistance")] public double TravelDistance { get; set; } [DataMember(Name = "travelDuration")] public long TravelDuration { get; set; } [DataMember(Name = "maneuverPoint")] public Point ManeuverPoint { get; set; } [DataMember(Name = "instruction")] public Instruction Instruction { get; set; } [DataMember(Name = "compassDirection")] public string CompassDirection { get; set; } [DataMember(Name = "hint")] public Hint[] Hint { get; set; }

Page 20: MapPoint-GeocodingAndReverseGeocoding

20

[DataMember(Name = "warning")] public Warning[] Warning { get; set; } } [DataContract] public class Line { [DataMember(Name = "point")] public Point[] Point { get; set; } [DataMember(Name = "coordinates")] public double[][] Coordinates { get; set; } } [DataContract] public class Link { [DataMember(Name = "role")] public string Role { get; set; } [DataMember(Name = "name")] public string Name { get; set; } [DataMember(Name = "value")] public string Value { get; set; } [DataMember(Name = "url")] public string Url { get; set; } } [DataContract(Namespace = "http://schemas.microsoft.com/search/local/ws/rest/v1")] public class Location : Resource { [DataMember(Name="entityType")] public string EntityType { get; set; } [DataMember(Name="address")] public Address Address { get; set; } [DataMember(Name = "confidence")] public string Confidence { get; set; } } [DataContract] public class Point : Shape { /// <summary> /// Latitude,Longitude /// </summary> [DataMember(Name = "coordinates")]

Page 21: MapPoint-GeocodingAndReverseGeocoding

21

public double[] Coordinates { get; set; } //[DataMember(Name = "latitude")] //public double Latitude { get; set; } //[DataMember(Name = "longitude")] //public double Longitude { get; set; } } [DataContract] [KnownType(typeof(Location))] [KnownType(typeof(Route))] [KnownType(typeof(DataflowJob))] public class Resource { [DataMember(Name = "name")] public string Name { get; set; } [DataMember(Name = "id")] public string Id { get; set; } [DataMember(Name = "link")] public Link[] Link { get; set; } [DataMember(Name = "links")] public Link[] Links { get; set; } [DataMember(Name = "point")] public Point Point { get; set; } [DataMember(Name = "boundingBox")] public BoundingBox BoundingBox { get; set; } } [DataContract] public class ResourceSet { [DataMember(Name="estimatedTotal")] public long EstimatedTotal { get; set; } [DataMember(Name="resources")] public Resource[] Resources { get; set; } } [DataContract] public class Response { [DataMember(Name = "copyright")] public string Copyright { get; set; } [DataMember(Name = "brandLogoUri")]

Page 22: MapPoint-GeocodingAndReverseGeocoding

22

public string BrandLogoUri { get; set; } [DataMember(Name = "statusCode")] public int StatusCode { get; set; } [DataMember(Name = "statusDescription")] public string StatusDescription { get; set; } [DataMember(Name = "authenticationResultCode")] public string AuthenticationResultCode { get; set; } [DataMember(Name = "errorDetails")] public string[] errorDetails { get; set; } [DataMember(Name = "traceId")] public string TraceId { get; set; } [DataMember(Name = "resourceSets")] public ResourceSet[] ResourceSets { get; set; } } [DataContract(Namespace = "http://schemas.microsoft.com/search/local/ws/rest/v1")] public class Route : Resource { [DataMember(Name = "distanceUnit")] public string DistanceUnit { get; set; } [DataMember(Name = "durationUnit")] public string DurationUnit { get; set; } [DataMember(Name = "travelDistance")] public double TravelDistance { get; set; } [DataMember(Name = "travelDuration")] public long TravelDuration { get; set; } [DataMember(Name = "routeLegs")] public RouteLeg[] RouteLegs { get; set; } [DataMember(Name = "routePath")] public RoutePath RoutePath { get; set; } } [DataContract] public class RouteLeg { [DataMember(Name = "travelDistance")] public double TravelDistance { get; set; } [DataMember(Name = "travelDuration")] public long TravelDuration { get; set; }

Page 23: MapPoint-GeocodingAndReverseGeocoding

23

[DataMember(Name = "actualStart")] public Point ActualStart { get; set; } [DataMember(Name = "actualEnd")] public Point ActualEnd { get; set; } [DataMember(Name = "startLocation")] public Location StartLocation { get; set; } [DataMember(Name = "endLocation")] public Location EndLocation { get; set; } [DataMember(Name = "itineraryItems")] public ItineraryItem[] ItineraryItems { get; set; } } [DataContract] public class RoutePath { [DataMember(Name = "line")] public Line Line { get; set; } } [DataContract] [KnownType(typeof(Point))] public class Shape { [DataMember(Name = "boundingBox")] public double[] BoundingBox { get; set; } } [DataContract] public class Warning { [DataMember(Name = "warningType")] public string WarningType { get; set; } [DataMember(Name = "severity")] public string Severity { get; set; } [DataMember(Name = "value")] public string Value { get; set; } } }

Page 24: MapPoint-GeocodingAndReverseGeocoding

24

Appendix C: Response Listings

This section contains full listings of responses retrieved from the Bing Maps REST API.

Bing Maps Geocoding Response (JSON)

The following is a response from Bing Maps Locations API in JSON format.

{ "authenticationResultCode": "ValidCredentials", "brandLogoUri": "http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png", "copyright": "Copyright © 2010 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.", "resourceSets": [ { "estimatedTotal": 1, "resources": [ { "__type": "Location:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1", "bbox": [ 47.635884282429323, -122.13737419709076, 47.643609717570676, -122.12208780290925 ], "name": "1 Microsoft Way, Redmond, WA 98052-8300", "point": { "type": "Point", "coordinates": [ 47.639747, -122.129731 ] }, "address": { "addressLine": "1 Microsoft Way", "adminDistrict": "WA", "adminDistrict2": "King Co.", "countryRegion": "United States", "formattedAddress": "1 Microsoft Way, Redmond, WA 98052-8300", "locality": "Redmond", "postalCode": "98052-8300" }, "confidence": "High", "entityType": "Address" } ] }

Page 25: MapPoint-GeocodingAndReverseGeocoding

25

], "statusCode": 200, "statusDescription": "OK", "traceId": "6dd03a0ca64e4b239f23242d2a478353|EWRM001672|02.00.59.1700|EWRMSNVM001808" }

Bing Maps Geocoding Response (XML)

The following is a response from Bing Maps Locations API in XML format.

<?xml version="1.0" encoding="utf-8"?> <Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1"> <Copyright>Copyright © 2010 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright> <BrandLogoUri>http://dev.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri> <StatusCode>200</StatusCode> <StatusDescription>OK</StatusDescription> <AuthenticationResultCode>ValidCredentials</AuthenticationResultCode> <TraceId>3e7649455d50400eb3300f544e185cc7|EWRM001663|02.00.59.1700|EWRMSNVM001806</TraceId> <ResourceSets> <ResourceSet> <EstimatedTotal>1</EstimatedTotal> <Resources> <Location> <Name>1 Microsoft Way, Redmond, WA 98052-8300</Name> <Point> <Latitude>47.639747</Latitude> <Longitude>-122.129731</Longitude> </Point> <BoundingBox> <SouthLatitude>47.635884282429323</SouthLatitude> <WestLongitude>-122.13737419709076</WestLongitude> <NorthLatitude>47.643609717570676</NorthLatitude> <EastLongitude>-122.12208780290925</EastLongitude> </BoundingBox> <EntityType>Address</EntityType> <Address> <AddressLine>1 Microsoft Way</AddressLine> <AdminDistrict>WA</AdminDistrict> <AdminDistrict2>King Co.</AdminDistrict2> <CountryRegion>United States</CountryRegion> <FormattedAddress>1 Microsoft Way, Redmond, WA 98052-8300</FormattedAddress>

Page 26: MapPoint-GeocodingAndReverseGeocoding

26

<Locality>Redmond</Locality> <PostalCode>98052-8300</PostalCode> </Address> <Confidence>High</Confidence> </Location> </Resources> </ResourceSet> </ResourceSets> </Response>

Bing Maps Reverse Geocoding Response (JSON)

The following example response in JSON format is for a Bing Maps reverse geocoding request.

{ "authenticationResultCode": "ValidCredentials", "brandLogoUri": "http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png", "copyright": "Copyright © 2010 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.", "resourceSets": [ { "estimatedTotal": 2, "resources": [ { "__type": "Location:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1", "bbox": [ 47.635884282429323, -122.13737419709076, 47.643609717570676, -122.12208780290925 ], "name": "1 Microsoft Way, Redmond, WA 98052-6399", "point": { "type": "Point", "coordinates": [ 47.639747, -122.129731 ] }, "address": { "addressLine": "1 Microsoft Way", "adminDistrict": "WA", "adminDistrict2": "King Co.", "countryRegion": "United States", "formattedAddress": "1 Microsoft Way, Redmond, WA 98052-6399", "locality": "Redmond",

Page 27: MapPoint-GeocodingAndReverseGeocoding

27

"postalCode": "98052-6399" }, "confidence": "Medium", "entityType": "Address" }, { "__type": "Location:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1", "bbox": [ 47.635758182583437, -122.13737435692933, 47.64348361772479, -122.12208799963806 ], "name": "Street, Redmond, WA 98052", "point": { "type": "Point", "coordinates": [ 47.639620900154114, -122.12973117828369 ] }, "address": { "addressLine": "Street", "adminDistrict": "WA", "adminDistrict2": "King Co.", "countryRegion": "United States", "formattedAddress": "Street, Redmond, WA 98052", "locality": "Redmond", "postalCode": "98052" }, "confidence": "Medium", "entityType": "Address" } ] } ], "statusCode": 200, "statusDescription": "OK", "traceId": "09b2b207add14ef1924d9c8a5aa83026|EWRM001663|02.00.59.1700|EWRMSNVM001811, EWRMSNVM001727, EWRMSNVM001737" }

Page 28: MapPoint-GeocodingAndReverseGeocoding

28

Appendix D: Code Listings for VB.NET

The VB .NET code samples below make use of the JSON deserialization classes from the C# code listing.

Bing Maps Geocoding Example (VB.NET)

Dim textAddress As String = "1st Ave, Seattle, WA, US" Console.WriteLine(String.Format("Matches for '{0}':", textAddress)) ' Create a Bing Maps REST request. Dim requestUrl As String = String.Format("http://dev.virtualearth.net/REST/v1/Locations/{0}?key={1}", textAddress, BingMapsKey) ' Send the request and parse the response. Dim jsonResponse As BingMapsRestV1.Response = GetJsonResponse(requestUrl) ' Display all matches to the user. For Each location As Location In jsonResponse.ResourceSets(0).Resources Console.WriteLine("Confidence: {0}; Type: {1}; Address: {2}", location.Confidence, location.EntityType, location.Address.FormattedAddress) Next ' Get the info on the first match so we can show it on a map. Dim firstMatchLocation As Location = DirectCast(jsonResponse.ResourceSets(0).Resources(0), Location) Dim centerLatitude As Double = firstMatchLocation.Point.Coordinates(0) Dim centerLongitude As Double = firstMatchLocation.Point.Coordinates(1) Dim northLatitude As Double = firstMatchLocation.BoundingBox.NorthLatitude Dim westLongitute As Double = firstMatchLocation.BoundingBox.WestLongitude Dim southLatitude As Double = firstMatchLocation.BoundingBox.SouthLatitude Dim eastLongitude As Double = firstMatchLocation.BoundingBox.EastLongitude

Bing Maps Reverse Geocoding Example (VB.NET)

Dim latitude As String = "47.640545555176843" Dim longitude As String = "-122.12934213381237" Dim includedEntityTypes As String = "AdminDivision1,AdminDivision2" Dim requestUrl As String = String.Format("http://dev.virtualearth.net/REST/v1/" + "Locations/{0},{1}?includeEntityTypes={2}" + "&key={3}", latitude, longitude, includedEntityTypes, BingMapsKey) Dim response As BingMapsRestV1.Response = GetJsonResponse(requestUrl) 'Only the most specific entity type is returned Dim location As BingMapsRestV1.Location = TryCast(response.ResourceSets(0).Resources(0), BingMapsRestV1.Location)

Page 29: MapPoint-GeocodingAndReverseGeocoding

29

'In this case AdminDivision1 is returned Dim name As String = location.Name

GetJsonResponse() (VB.NET)

''' <summary> ''' Send the request to the Bing Maps REST API and deserialize the JSON response. ''' </summary> Private Function GetJsonResponse(ByVal requestUrl As String) As BingMapsRestV1.Response Dim request As HttpWebRequest = TryCast(WebRequest.Create(requestUrl), HttpWebRequest) Using response As HttpWebResponse = TryCast(request.GetResponse(), HttpWebResponse) Dim jsonSerializer As New DataContractJsonSerializer(GetType(BingMapsRestV1.Response)) Dim objResponse As Object = jsonSerializer.ReadObject(response.GetResponseStream()) Dim jsonResponse As BingMapsRestV1.Response = TryCast(objResponse, BingMapsRestV1.Response) Return jsonResponse End Using End Function

Appendix E: Code Listings for Java

The following Java examples use the JSON processing code available at http://www.json.org, namely JSONObject

and JSONArray.

Bing Maps Geocoding Example (Java)

String textAddress = "1st Ave, Seattle, WA, US"; System.out.println(String.format("Matches for '%s':", textAddress)); URI requestURI = new URI("http", null, "dev.virtualearth.net", 80, "/REST/v1/Locations/"+textAddress, "key=" + BING_MAPS_KEY, null); JSONObject jsonResponse = getResponse(requestURI); JSONArray resources = jsonResponse.getJSONArray("resourceSets").getJSONObject(0).getJSONArray("resources"); for (int index = 0; index < resources.length(); ++index) {

Page 30: MapPoint-GeocodingAndReverseGeocoding

30

JSONObject resource = resources.getJSONObject(index); System.out.println(String.format("Confidence: %s; Type: %s; Address: %s", resource.getString("confidence"), resource.getString("entityType"),resource.getJSONObject("address").getString("formattedAddress"))); } JSONObject jsonObject = resources.getJSONObject(0); JSONArray coords = jsonObject.getJSONObject("point").getJSONArray("coordinates"); JSONArray bboxcoords = jsonObject.getJSONArray("bbox"); double centerLatitude = coords.getDouble(0); double centerLongitude = coords.getDouble(1); double northLatitude = bboxcoords.getDouble(0); double westLongitute = bboxcoords.getDouble(1); double southLatitude = bboxcoords.getDouble(2); double eastLongitude = bboxcoords.getDouble(3);

Bing Maps Reverse Geocoding Example (Java)

String latitude = "47.640545555176843"; String longitude = "-122.12934213381237"; String includedEntityTypes = "AdminDivision1,AdminDivision2"; URI requestURI = new URI("http", null, "dev.virtualearth.net", 80, "/REST/v1/Locations/"+latitude+","+longitude, "includeEntityTypes=" +includedEntityTypes + "&key=" + BING_MAPS_KEY, null); JSONObject jsonResponse = getResponse(requestURI); String name = jsonResponse.getJSONArray("resourceSets").getJSONObject(0). getJSONArray("resources").getJSONObject(0).getString("name");

getResponse (Java)

private JSONObject getResponse(URI requestURI) throws MalformedURLException, IOException, JSONException, URISyntaxException { URLConnection connection = requestURI.toURL().openConnection(); String line; StringBuilder builder = new StringBuilder();

Page 31: MapPoint-GeocodingAndReverseGeocoding

31

BufferedReader reader = new BufferedReader(new InputStreamReader( connection.getInputStream())); while ((line = reader.readLine()) != null) { builder.append(line); } return new JSONObject(builder.toString()); }

Appendix F: Code Listings for PHP

Bing Maps Geocoding Example (PHP)

<!-- Set Bing Map Keys --> <?php require '../BingMapsKey.inc.php' ?> <!-- Map functions --> <?php function ExampleFuzzySearch() { global $bingMapsKey; // URL of Bing Maps REST Services Locations API $locationURL = "http://dev.virtualearth.net/REST/v1/Locations/"; // Required start and end waypoint parameters (location string // or a pair of latitude and longitude coordinates). $address = str_ireplace(" ","%20","1st Ave, Seattle, WA"); // Compose URI for Locations API request $findURL = $locationURL.$address."?key=".$bingMapsKey; // get the response from the Locations API and store it in a string $output = file_get_contents($findURL); // create an XML element based on the XML string $response = json_decode($output); echo "<table>\n"; foreach($response->resourceSets[0]->resources as $resource) { echo "<tr>\n"; echo "<td>Confidence: </td><td>".$resource->confidence.";</td>"; echo "<td>Entity Type: </td><td>".$resource->entityType.";</td>"; echo "<td>Address: </td><td>".$resource->address->formattedAddress."</td>";

Page 32: MapPoint-GeocodingAndReverseGeocoding

32

echo "<tr>\n"; } echo "</table>\n"; } ?>

Bing Maps Reverse Geocoding Example (PHP)

<!-- Set Bing Map Keys --> <?php require '../BingMapsKey.inc.php' ?> <!-- Map functions --> <?php function ExampleChooseEntityTypes() { global $bingMapsKey; // URL of Bing Maps REST Services Locations API $locationURL = "http://dev.virtualearth.net/REST/v1/Locations/"; $latitude = "47.640545555176843"; $longitude = "-122.12934213381237"; $includedEntityTypes = "AdminDivision1,AdminDivision2"; // Compose URI for Locations API request $findURL = $locationURL.$latitude.",".$longitude."?includeEntityTypes=" .$includedEntityTypes."&key=".$bingMapsKey; // get the response from the Locations API and store it in a string $output = file_get_contents($findURL); $response = json_decode($output); $name = $response->resourceSets[0]->resources[0]->name; echo "Name: ".$name; } ?>