Using Google Maps for Geocoding in C#

Recently, I wanted to find out how to programmatically find the longitude and latitude given a city and state. From my previous work using Google Maps I knew this was possible. I did some digging and found Google Maps API supports a particular URL for geocoding a specific location. The URL looks like this:

http://maps.google.com/maps/geo?output=xml&key=<your_google_api_key>&q=<city_state>

Simply specify your $g(Google API Key) and your URL encoded city and state and you will get a result similar to the following (for “scotts valley ca”):

<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
  <name>scotts valley ca</name>
  <Status>
    <code>200</code>
    <request>geocode</request>
  </Status>
  <Placemark id="p1">
    <address>Scotts Valley, CA, USA</address>
    <AddressDetails Accuracy="4" xmlns="">
      <Country>
        <CountryNameCode>US</CountryNameCode>
        <CountryName>USA</CountryName>
        <AdministrativeArea>
          <AdministrativeAreaName>CA</AdministrativeAreaName>
          <Locality>
            <LocalityName>Scotts Valley</LocalityName>
          </Locality>
        </AdministrativeArea>
      </Country>
    </AddressDetails>
    <Point>
      <coordinates>-122.0120480,37.0555750,0</coordinates>
    </Point>
  </Placemark>
</Response>
</kml>

Hint: For illustration purposes this works without using an API Key although you should review Google’s Maps TOS.

Getting Geocode Information Programmatically

I wrote the following C# function (which lacks error checking) to fetch the above XML response from the Google Maps service. As you can see I’m using a simple regular expression to locate and return the actual coordinates.

private string GeoCode(string city, string state)
{
    string url = "http://maps.google.com/maps/geo?output=xml&key=<your_API_key>&q=" + System.Web.HttpUtility.UrlEncode(city + " " + state);
    WebRequest req = HttpWebRequest.Create(url);
    WebResponse res = req.GetResponse();
    StreamReader sr = new StreamReader(res.GetResponseStream());
    try
    {
        Match coord = Regex.Match(sr.ReadToEnd(), "<coordinates>.*</coordinates>");
        if(!coord.Success) return "";
        return coord.Value.Substring(13, coord.Length - 27);
    }
    finally
    {
        sr.Close();
    }
}

This turned out to be a lot less painful than I had originally thought it might be all thanks to Google’s Maps service. Have you done anything similar/easier/better?
[Update: Dec, 2 2008] Using Google Maps for Geocoding in C# Part 2: Deserializing to a class
[Update: Dec, 16 2008] Status codes returned by this service.