I recently used the Google maps API in a list event handler to automatically populate the longitude and latitude values for items in a list.
If you too need geocoding, follow these easy to follow steps:
- Get your own Google Maps key by signing up at http://code.google.com/apis/maps/signup.html
- Read up on how to access the Maps API directly using HTTP requests at http://code.google.com/apis/maps/documentation/services.html#Geocoding_Direct
- Copy/Paste the class below in to your own .cs file (I was just kidding about step #2, you don't actually have to read J)
- Be sure to include using System.Xml, using System.IO
There were a few twists and turns necessary in my case, but that's the core of simple geocoding with Google.
public
class
GoogleMaps
{
static
public
string Status_ok = "200";
static
public
string Status_UnknownZipcode = "Unknown zipcode";
static
public
string GetGeoCode(string zipcode, string country, string key, out
string url, out
double longitude, out
double latitude)
{
string ret = "";
url = "";
longitude = 0;
latitude = 0;
try
{
//return out the url for debugging
url = string.Format("http://maps.google.com/maps/geo?q={0}&output=xml&key={1}", zipcode + "," + country, System.Web.HttpUtility.UrlEncode(key));
//create a web request against the google maps site
System.Net.WebRequest webReq = System.Net.HttpWebRequest.Create(url);
//get the response stream so we can read the reply to a string
StreamReader rdr = new
StreamReader(webReq.GetResponse().GetResponseStream());
string xmlString = rdr.ReadToEnd();
rdr.Close();
XmlDocument topNode = new
XmlDocument();
topNode.LoadXml(xmlString);
//create namespace aliases so we can drill down in to the results with xpath queries
XmlNamespaceManager ns = new
XmlNamespaceManager(topNode.NameTable);
ns.AddNamespace("ge", "http://earth.google.com/kml/2.0");
ns.AddNamespace("ad", "urn:oasis:names:tc:ciq:xsdschema:xAL:2.0");
XmlNode statusCodeNode =
topNode.SelectSingleNode("//ge:kml/ge:Response/ge:Status/ge:code", ns);
XmlNode coordNode =
topNode.SelectSingleNode("//ge:kml/ge:Response/ge:Placemark/ge:Point/ge:coordinates", ns);
XmlNode zipNode =
topNode.SelectSingleNode("//ge:kml/ge:Response/ge:Placemark/ad:AddressDetails//ad:PostalCodeNumber", ns);
if (statusCodeNode == null)
return
"Geocode error: Cannot find status node in response";
else
if (statusCodeNode.InnerText != Status_ok || coordNode == null)
return
"Geocode error: " + statusCodeNode.InnerText;
else
if (zipNode == null || string.Compare(zipNode.InnerText, zipcode.Substring(0, Math.Min(zipcode.Length, zipNode.InnerText.Length)), true) != 0)
return Status_UnknownZipcode;
else
{
ret = statusCodeNode.InnerText;
string[] points = coordNode.InnerText.Split(',');
if (points.Length >= 2)
{
longitude = double.Parse(points[0]);
latitude = double.Parse(points[1]);
}
}
}
catch (System.Exception ex)
{
return
"Exception: " + ex.Message;
}
return ret;
}
}