Sunday, April 7, 2013

Using Google Geocoding API-v3 to extract latitude/longitude values of an address in C#.NET

Geocoding is the process of converting addresses into geographic coordinates (latitudes and longitudes). These coordinates  can be  used to place markers on a map. The Google Geocoding API is a direct way to access these services via an HTTP (HTTPS is recommended if you are dealing with sensitive data) request. This HTTP request must be of the following form:

"http://maps.googleapis.com/maps/api/geocode/output?parameters"



Output may be either json or xml (In Google Geocoding v2 they allowed csv also, but they have removed it in v3). Required parameters are 'address' (address that you want to geocode) and 'sensor' (indicates whether or not the request comes from a device with a location sensor).

XML output:





I wrote a simple code to send a API Request and retrieve the XML file and parse it and get the latitude/longitude values. The Send backed XML contains two important elements. 


1.) <status> - describe the status of the result-whether it's success or not.

2.) <result> - contains informations of the address including latitude/longitude values.

c# code:


string location = "1600+Amphitheatre+Parkway,+Mountain+View,+CA";
float[] position =new float[2];
position = getLatLongForAddress(location);
System.Diagnostics.Debug.Write("Lattitude:"+position[0]+"Location:"+position[1]);

public float[] GetLatLongForAddress(string location)
{

  string result = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?address={0}&sensor=true", location);
            

  var doc = XDocument.Load(result);
  string status = doc.Element("GeocodeResponse").Element("status").Value;

  //no errors occurred; the address was successfully parsed and at least one            
    geocode was returned.   
             
      if(status.Equals("OK"))
      {
         var point = doc.Element("GeocodeResponse").Element("result").
Element("geometry").Element("location");

         string lat = point.Element("lat").Value;
         string lng = point.Element("lng").Value;
         latLong[0] = (float)Convert.ToDouble(lat);
         latLong[1] = (float)Convert.ToDouble(lng);
                 
         }
         else if (status.Equals("ZERO_RESULTS")) 
         {
            //geocode was successful but returned no results
             throw new ApplicationException("No maps found for this address");
            
         }
         else if (status.Equals("REQUEST_DENIED")) 
         {
            //request was denied
            throw new ApplicationException("Request Denied");
            
         }
         else if (status.Equals("INVALID_REQUEST")) 
         {
             //address is missing
             throw new ApplicationException("Address not found");
         }
         else if (status.Equals("UNKNOWN_ERROR")) 
         {
             //the request could not be processed due to a server error
     //throw new ApplicationException("Unknown Error. Try agian.");
      GetLatLongForAddress(location);
         }       

    return latLong;
}


Similarly you can get the json output and get the latitude/longitude values.

If you wan't learn more details about Google Geocoding API, have a peek at their documentation.

"https://developers.google.com/maps/documentation/geocoding"

2 comments:

  1. Hi,

    thanks for your code - saved me lots of time.

    However a few glitches:
    -> watch out for case sensitivity (GetLatLongForAdress vs getLatLongForAdress)
    -> string.Format("http://maps.googleapis.com/maps/api/geocode/xml? address={0}&sensor=true", location); has a space between xml? and adress
    -> var doc = XDocument.Parse(result) throws an error. Use XDocument.Load(result) instead. (see http://stackoverflow.com/questions/18381912/xdocument-says-data-at-the-root-level-is-invalid)
    -> be careful when converting coordinates to numbers. This might be a remark only for german-speaking users, but 48.00000 will be converted to 48000.00 in german language sets. Check the CultureInvariance references on MSDN - but as said, this might be a problem only we have to suffer. ;)

    Thanks again for the code, i hope my remarks are understandable!

    ReplyDelete
    Replies
    1. Hey Konard,

      Thanks for your feedback. I corrected code according to your suggestions. Though I'm little surprised because XDocument.Parse(result) did worked for me.. :)

      Delete