For the past several years, the Bing Map API has made search data available for developers to innovate and build various address/ geocode related applications. Using Bing Map API developer can retrieve latitude & longitude (geocode) of an address/ zipCode which is called Geocoding.
In this
documentation, I mainly focused to show the approach for Geocoding
using Bing Map Rest Api from a standalone sample Java class example.
Below I am giving an overview of what / how I approached with doing
that:
- In this approach I invoked http://dev.virtualearth.net/REST/v1/Locations Bing Api. In order to invoke this API developer needs an authentication key by purchasing a license. There are several other similar apis available in Bing which differ by different parameters.
- To get a license for using the Geocoding Webservice, developer needs to register for Bing Maps Developer account. Developer can sign up here: http://www.microsoft.com/maps/product/licensing.aspx . Developer also can use a free version of api without any license fee [free version of api has some limitation which is also documented in the above link]
- Now, I am assuming developer will have their own Bing Map authentication key. For this documentation and example I am using an authentication key value: "XXXXXXX".
- Create a class GeoCodeFetcher that would hold all the logic for interacting with geocoding webservices. By following the logic developer can create their own functionality by enhancing the logic.
- In GeoCodeFetcher class I hardcode "streetAddress", "city", "state", "country", "zipCode", "resposeOutputType" value inside main() method. Developer needs to modify all this dynamic value based on their requirement.
- I passed "streetAddress", "city", "state", "country", "zipCode", "resposeOutputType" as a parameter to prepareDynamicURL() function to prepare the URL dynamically by appending the parameter after the Bing Map API URL. Inside this prepareDynamicURL() function, I also called another encodeString() function to encode the value of parameters: streetAddress, city, state, country, zipCode.
- After preparing the URL dynamically, I invoked getResultHttpAsStream() method. This method opens calls the Bing URL by opening HttpURLConnection. After receiving a success status code from Bing API, this method populates the response data in a string and return the data to main() method for displaying. In this example I didn't play with result further and just displayed the data using SOP. But developer needs to process the result based on requirement.
- In this example, Bing API will return the data in XML format. Bing currently returns the data in XML/ JSON format. Developer can decide the response format type by "output" parameter value "xml/json". In this example "output" parameter value "xml" has been used by passing the "responseOutputType" value as "xml".
For the rest, I
have written commented code for your reading, this should be fairly
self-explanatory.
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import org.apache.commons.lang.StringUtils;
public class GeocodeFetcher {
//Bing service REST-URL
public static final String bingLocationUrl="http://dev.virtualearth.net/REST/v1/Locations";
//Authentication key to invoke Bing URL [user need to change this key]
public static final String bingAuthenticationKey=" XXXXXXX";
protected static final String EQUAL = "=";
protected static final String AND = "&";
private static final String PARAM_COUNTRY = "countryRegion";
private static final String PARAM_STATE = "adminDistrict";
private static final String PARAM_CITY = "locality";
private static final String PARAM_ZIP = "postalCode";
private static final String PARAM_ADDRESS = "addressLine";
protected static final String PARAM_KEY = "key";
protected static final String PARAM_OUTPUT = "output";
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GeocodeFetcher geocodeFetcherInstance = new GeocodeFetcher();
String streetAdreess = "3301 Stearns Hill Rd";
String city = "Waltham";
String state = "MA";
String country = "US";
String zipCode = "02451";
String resposeOutputType = "xml";
/*
* invoking prepareDynamicURL() to prepare URL dynamically by appenidng
* street address, city, state, country and zipCode
*/
String dynamicURl = geocodeFetcherInstance.prepareDynamicURL(streetAdreess, city, state, zipCode, country, resposeOutputType );
System.out.println("dynamicURl: " + dynamicURl);
String result = null;
if(!StringUtils.isEmpty(dynamicURl)){
result = geocodeFetcherInstance.getResultHttpAsStream(dynamicURl);
}
System.out.println("result: " + result);
}
/*
* This prepareDynamicURL() prepare URL dynamically by appending
* street address, city, state, country and zipCode as parameter
* after the static part of Bing api
*/
protected String prepareDynamicURL(String streetAdreess, String city,
String state, String zipCode, String country, String resposeOutputType )
{
StringBuffer sb = new StringBuffer();
sb.append(bingLocationUrl).append("?");
sb.append(PARAM_COUNTRY).append(EQUAL).append(country).append(AND);
try {
sb.append(PARAM_STATE).append(EQUAL).append(encodeString(state)).append(AND);
} catch (UnsupportedEncodingException e) {
System.out.println("Unsupported code of state. Ignore the state");
}
try {
sb.append(PARAM_CITY).append(EQUAL).append(encodeString(city)).append(AND);
} catch (UnsupportedEncodingException e) {
System.out.println("Unsupported code of city. Ignore the city");
}
sb.append(PARAM_ZIP).append(EQUAL).append(zipCode).append(AND);
try {
sb.append(PARAM_ADDRESS).append(EQUAL).append(encodeString(streetAdreess)).append(AND);
} catch (UnsupportedEncodingException e) {
System.out.println("Unsupported code of street. Ignore the address line");
}
//appending bing authentication key
sb.append(PARAM_KEY).append(EQUAL).append(bingAuthenticationKey).append(AND);
/*
* appending response type/ output type value. Bing return response in
* XML/ JSON/ Text format.
*/
sb.append(PARAM_OUTPUT).append(EQUAL).append(resposeOutputType);
return sb.toString();
}
/*
* this encodeString() used to encode
* street address, city, state, country and zipCode
*/
protected String encodeString(String str)
throws UnsupportedEncodingException
{
return URLEncoder.encode(str.replace(".", "").replace(",","").replace(":", ""), "UTF-8");//.replace("+", "%20");
}
/*
* this getResultHttpAsStream() used to invoke Bing Rest-api
* using HttpURLConnection and converting the result in string format
*/
protected final String getResultHttpAsStream(String url)
{
System.out.println("url = " + url);
HttpURLConnection conn = null;
InputStream in = null;
BufferedReader rd = null;
StringBuffer sb = new StringBuffer();
try {
URL u = new URL(url);
conn = (HttpURLConnection)u.openConnection();
if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
//in = conn.getInputStream();
// Get the response
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null)
{
sb.append(line);
}
rd.close();
}
} catch (Throwable e) {
in = null;
} finally{
conn = null;
}
return sb.toString();
}