Storm were recently asked to create a local office finder for franchised business VoIP provider, Datasharp. The client requested that the user should be able to enter their postcode or town/city and be informed where their nearest branch was. To make this possible we would need the latitude and longitude co-ordinates for each office and the customer, but how do you get the co-ordinates from the address?

Using the Google Maps API

Note: To make use of the example in the post you will need to sign-up for a free Google Maps API Key.

The following example is written in C#, but it can be converted to any language fairly trivially as we are actually only making an HTTP request and parsing the result.

We use a little helper class to hold a latitude/longitude co-ordinate.

public class LatLng { public double Latitude {get;set;} public double Longitude {get;set; public LatLng(){ } public LatLng(double lat, double lng) { this.Latitude = lat; this.Longitude = lng; } }

We’ve packaged the function to get the co-ordinates in a helper class so that we can add extra Google Maps functionality if required. It also allows us to reuse the code across multiple projects as the API key is not hard coded.

using System; using System.IO; using System.Net; using System.Web; using Storm.Common.Utils.Extensions; public class GoogleMaps { private string API_KEY = string.Empty; public GoogleMaps(string api_key) { this.API_KEY = api_key; } public void SetApiKey(string key) { if (key.IsNullOrEmpty()) { throw new ArgumentException("API Key is invalid"); } this.API_KEY = key; } /// <summary> /// Perform a geocode lookup of an address /// </summary> /// <param name="addr">The address in CSV form line1, line2, postcode</param> /// <param name="output">CSV or XML</param> /// <returns>LatLng object</returns> public LatLng GetLatLng(string addr) { var url = "http://maps.google.co.uk/maps/geo?output=csv&key=" + this.API_KEY + "&q=" + HttpContext.Current.Server.UrlEncode(addr); var request = WebRequest.Create(url); var response = (HttpWebResponse)request.GetResponse(); if (response.StatusCode == HttpStatusCode.OK) { var ms = new MemoryStream(); var responseStream = response.GetResponseStream(); var buffer = new Byte[2048]; int count = responseStream.Read(buffer, 0, buffer.Length); while (count > 0) { ms.Write(buffer, 0, count); count = responseStream.Read(buffer, 0, buffer.Length); } responseStream.Close(); ms.Close(); var responseBytes = ms.ToArray(); var encoding = new System.Text.ASCIIEncoding(); var coords = encoding.GetString(responseBytes); var parts = coords.Split(","); return new LatLng( Convert.ToDouble(parts[2]), Convert.ToDouble(parts[3])); } return null; } }

Let’s talk through whats going on. First up, the boring bit:

private string API_KEY = string.Empty; public GoogleMaps(string api_key) { this.API_KEY = api_key; } public void SetApiKey(string key) { if (key.IsNullOrEmpty()) { throw new ArgumentException("API Key is invalid"); } this.API_KEY = key; }

Here we have a private field to store the Maps API key required to issue a request. The key can be set either through the constructor or by using the SetApiKey() function.

Now lets see how we use this in the lookup function.

var url = "http://maps.google.co.uk/maps/geo?output=csv&key=" + this.API_KEY + "&q=" + HttpContext.Current.Server.UrlEncode(addr); var request = WebRequest.Create(url); var response = (HttpWebResponse)request.GetResponse();

First, we build the a URL which represents the request we want to make. The output param sets the format Google will return the results, here we have chosen CSV but you can also get JSON if you wish. Next we include our API key to identify ourselves. Finally, we pass the address we are searching for.

Using this URL we create a WebRequest and call GetResponse to fetch the page contents. Before we go any further we check that the result was returned successfully:

if (response.StatusCode == HttpStatusCode.OK)

Now we have another boring bit which reads the result of the web request into a byte array and converts the result into an ASCII encoded string

var ms = new MemoryStream(); var responseStream = response.GetResponseStream(); var buffer = new Byte[2048]; int count = responseStream.Read(buffer, 0, buffer.Length); while (count > 0) { ms.Write(buffer, 0, count); count = responseStream.Read(buffer, 0, buffer.Length); } responseStream.Close(); ms.Close(); var responseBytes = ms.ToArray(); var encoding = new System.Text.ASCIIEncoding(); var coords = encoding.GetString(responseBytes);

This string should look something like:

200,5,51.2268219,-2.4646913

We are interested in the 3rd and 4th values – the latitude and longitude. So, we split the string at the comma separator, create a new LatLng object and return the result:

var parts = coords.Split(","); return new LatLng(Convert.ToDouble(parts[2]), Convert.ToDouble(parts[3]));

I hope this tutorial has proven useful and that you can go away and develop some cool apps!