Friday, October 03, 2008

Using the Google maps geocode service to find the co-ordinates of an address

I've been having a lot of fun playing with Google maps this week. One of things we need to be able to do is map an address to a longitude and latitude so that we can display a point on a google map. This is very easy to do. Simply send a GET request to http://maps.google.com/maps/geo?q=<the address>&output=xml&key=<your key>. This returns a 'kml' XML document containing the geocode information. I simply used Visual Studio to create an XSD from the XML and then XSD.exe to generate the C# types to deserialize the XML document into. Here's the code:

using System;
using System.IO;
using System.Net;
using System.Web;
using System.Xml.Serialization;
namespace Mike.GoogleGeocode
{
    class Program
    {
        private const string googleGeocodeUrl = "http://maps.google.com/maps/geo?q={0}&output=xml&key={1}";
        private const string proxyUrl = "your proxy address";
        private const string key = "your key";
        static void Main()
        {
            const string address = "St. Julians, Sevenoaks, Kent, UK";
            var kml = GetKml(address);
            Console.WriteLine("Co-ordinates: {0}, for address: {1}", kml.Response.Placemark.Point.coordinates, address);
        }
        private static kml GetKml(string address)
        {
            var url = string.Format(googleGeocodeUrl, HttpUtility.UrlEncode(address), key);
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Accept = "text/xml";
            request.Method = "GET";
            // set the proxy if needed.
            request.Proxy = new WebProxy(
                proxyUrl, true, new string[0],
                CredentialCache.DefaultNetworkCredentials);
            kml kml;
            using (var response = request.GetResponse())
            using (var responseStream = new StreamReader(response.GetResponseStream()))
            {
                try
                {
                    var serializer = new XmlSerializer(typeof(kml));
                    kml = (kml)serializer.Deserialize(responseStream);
                }
                catch (Exception)
                {
                    kml = null;
                }
            }
            return kml;
        }
    }
}

Running it gives this result:

googlecode_cmd

Which is the right location. One thing to watch out for is that the coordinates property is given as longitude, latitude, but Google maps expects you to enter co-ordinates as latitude, longitude. I was wondering why the API was resolving all my UK addresses to be off the East coast of Africa until I worked that out :P

You can download the full test solution here:

http://static.mikehadlow.com/Mike.GoogleGeocode.zip

4 comments:

Anonymous said...

Keep on exploring their public APIs. Incredibly useful.

Plus I like this post for the fact that you present a good demo code.
http://www.kenegozi.com/Blog/2008/10/05/thats-a-better-demo-code.aspx

Mike Hadlow said...

Thanks Ken.

I'm constantly surprised at how good the free Google stuff is. MS are going to have to try harder (and stop charging people) if they expect Live Services to compete,

Unknown said...

Great article Mike.

Personally I hope windows goes out of business and takes ASP with it. Never-the-less I found this very useful. Thanks.

Mike Hadlow said...

Thanks tmelvin.

I sometimes think it's a shame that .NET is owned by Microsoft. A great development platform hindered by the fact that it's only designed to run on Windows (yes yes, I know about Mono).

But then you wouldn't have the huge amount of investment in what are mostly free tools if the .NET frameworks wasn't sponsored by a large company.