A common problem for Google Maps developers who plot addresses on the map via postcode or other address data is getting the actual lat/lng coordinates of the address.

Now we all know we can "geocode" a postcode or address into lat/lng vales for plotting in real time via Google's JavaScript API (details @ http://code.google.com/apis/maps/documentation/services.html#Geocoding), but this has obviously got to be conducted client-side and is not suitable for geocoding a large (bulk) number of addresses. Frequently when you are loading lots of new addresses into a database these restrictions prove a problem...

The Solution Google also offers an HTTP Geocoding service which can be called server-side and is more suited for bulk geocoding! I'll let you read the details @ http://code.google.com/apis/maps/documentation/geocoding/index.html

However, Google don't give you much support in respect to how to actually programmatically use this HTTP service, and so I've included a pseudo-java implementation below that should be enough to get you started...

private String googleURL = "http://maps.google.com/maps/geo?output=csv&oe=utf8&sensor=false&key="; //note csv output requested
private String googleKey = "_your_key_here_";
private String googleQuery = "&q=";

//
//...
//
private void geocode(String geoTarget) {
//encode the geoTarget in case there are any non-URL friendly
//characters included (such as spaces and quotes)
String encodedGeoTarget = null;
try {
encodedGeoTarget = URLEncoder.encode(geoTarget, "UTF-8");
} catch (UnsupportedEncodingException uee) {
throw new InfrastructureException(uee);
}

//build the geocoding URL
URL googleGeocodeURL = null;
try {
googleGeocodeURL = new URL(googleURL + googleKey + googleQuery + encodedGeoTarget);
log.finer("Complete URL for geocode request : " + googleGeocodeURL.toString());
} catch (MalformedURLException mue) {
//do something
}

try {
in = new BufferedReader(new InputStreamReader(googleGeocodeURL.openStream()));

if (in.ready()) {
response = in.readLine();
log.finer("Google Responded with : " + response);
String[] split = response.split(",");
log.finer("split is " + split);

try {
//first check the response code for sign of problems
responseCode = Integer.parseInt(split[0]);
log.finer("Response Code: " + responseCode);
if (responseCode.equals(620)) {
//max number of queries exceeded
} else if (responseCode.compareTo(new Integer(201)) > 0) {
//Google indicated a problem occurred - the responseCode value will provide more info
see http:code.google.com/apis/maps/documentation/geocoding/index.html#StatusCodes
}

//response code good
//parse geocode data from CSV response...
latitude = Float.parseFloat(split[2]);
log.finer("latitude is " + latitude);
longitude = Float.parseFloat(split[3]);
log.finer("longitude is " + longitude);
accuracy = Float.parseFloat(split[1]);
log.finer("accuracy is " + accuracy);
} catch (NumberFormatException nfe) {
log.severe("Problem parsing response..." + nfe.getMessage());
}

} else {
log.severe("Unable to open URL @ " + googleGeocodeURL.toString());
}
} finally {
if (in != null) {
in.close();
}
}
}

Feel free to drop me a line if you need more info...

Daniel

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Daniel Bryant (Director) | Tai-Dev Ltd
www.tai-dev.co.uk - IT Consultancy Services Specialising in JEE, Web 2.0 and RDBMS