### Eclipse Workspace Patch 1.0
#P geocode
Index: includes/geocode.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/geocode/includes/geocode.inc,v
retrieving revision 1.5
diff -u -r1.5 geocode.inc
--- includes/geocode.inc	4 Nov 2009 21:07:31 -0000	1.5
+++ includes/geocode.inc	13 Sep 2010 07:11:21 -0000
@@ -54,7 +54,7 @@
 
   function get_field_postal() {
     $postal = array();
-    foreach (array('street1', 'street2', 'city', 'state', 'zip', 'country') as $item) {
+    foreach (array('street_number', 'street1', 'street2', 'city', 'state', 'zip', 'country') as $item) {
       if (isset($this->$item)) $postal[$item] = $this->$item;
     }
     return $postal;
@@ -62,49 +62,98 @@
 }
 
 class geocode_google extends geocode {
+  var $formatted_address;
+  var $street_number;
 
   function set_result($result) {
     $this->result = $result;
-    if (isset($result->AddressDetails)) {
-      $addr = $result->AddressDetails->Country;
-      $this->country_name = $addr->CountryName;
-      $this->country = $addr->CountryNameCode;
-      $this->state = $addr->AdministrativeArea->AdministrativeAreaName;
-      $this->city = $addr->AdministrativeArea->Locality->LocalityName;
-      $this->street1 = $addr->AdministrativeArea->Locality->Thoroughfare->ThoroughfareName;
-      $this->zip = $addr->AdministrativeArea->Locality->PostalCode->PostalCodeNumber;
-    }
 
-    if (isset($result->Point)) {
-      $point = (array) $result->Point->coordinates;
-      $this->point = array(
-        'type' => 'point', 'lat' => $point[1], 'lon' => $point[0], 'alt' => $point[2],
+    // Store the formatted address if present.
+    $this->formatted_address = $result->formatted_address;
+
+    // Translate the values returned by the Google Geocoding API to values used
+    // by the Geocode module. An associative array containing the google
+    // property names (such as "administrative_area_level_1") as keys, and an 
+    // array mapping the subtype (such as "long_name") to a geocode property.
+    //
+    // For example: array('postal_code' => array('long_name' => 'zip'))
+    // Store the property "long_name" of the google type "postal_code" in 
+    // Geocode's "zip" property.
+    $translate_map = array(
+      'postal_code' => array('long_name' => 'zip'),
+      'country' => array('long_name' => 'country_name', 'short_name' => 'country'),
+      'administrative_area_level_1' => array('long_name' => 'state'),
+      'locality' => array('long_name' => 'city'),
+      'route' => array('long_name' => 'street1'),
+      'street_number' => array('long_name' => 'street_number'),
+    );
+
+    foreach ($result->address_components as $component) {
+      foreach ($component->types as $google_type) {
+        foreach($translate_map[$google_type] as $source => $destination) {
+          $this->$destination = $component->$source;
+        }
+      }
+    }
+
+    $this->point = array(
+     'type' => 'point',
+     'lat' => $result->geometry->location->lat,
+     'lng' => $result->geometry->location->lng,
+    );
+
+    // Convert the new viewport data into the old north-east-south-west format
+    // to maintain backward compatibility.
+    if (isset($result->geometry->viewport)) {
+      $this->box = array(
+        'north' => $result->geometry->viewport->northeast->lat,
+        'east' => $result->geometry->viewport->northeast->lng,
+        'south' => $result->geometry->viewport->southwest->lat,
+        'west' => $result->geometry->viewport->southwest->lng,
       );
     }
-    if (isset($result->ExtendedData->LatLonBox)) {
-      $this->box = (array) $result->ExtendedData->LatLonBox;
-    }
   }
 
+  /**
+   * Executes a geocoding request against Google's geocoding webservice.
+   * 
+   * @param $input
+   *   The location or address that needs to be geocoded. Can be either a string
+   *   or an array containing multiple locations.
+   * @param $options
+   *   An array of optional options to pass to the geocoding webservice.
+   * 
+   * @return
+   *   TRUE if the geocoding request was successful, FALSE otherwise.
+   */
   function geocode($input, $options) {
     if (is_array($input)) $input = join(',', $input);
-    $url = "http://maps.google.com/maps/geo?";
-    $url .= 'q='. urlencode($input);
 
-    // Deliberately reusing the GMAP key, still pending an interface.
-    global $conf;
-    if ($key = variable_get('googlemap_api_key', '')) {
-      $url .= '&key='. check_plain($key);
-    }
-    $url .= '&sensor=false&output=json&oe=utf-8';
-    $ret = drupal_http_request($url);
-    $result = json_decode($ret->data);
+    $query = array(
+      'address' => $input,
+      'sensor' => 'false',
+    );
 
-    if ($result->Status->code == '200') {
-      $this->set_result($result->Placemark[0]);
+    $url = url('http://maps.google.com/maps/api/geocode/json', array('query' => $query));
+
+    $geocode_result = drupal_http_request($url);
+    $result = json_decode($geocode_result->data);
+
+    if ($result->status == 'OK') {
+      $this->set_result($result->results[0]);
       return TRUE;
     }
 
     return FALSE;
   }
+  
+  /**
+   * Gets the human-readable address of the requested location.
+   * 
+   * @return
+   *   A string containing the human-readable address of this location.
+   */
+  function get_formatted_address() {
+    return $this->formatted_address;
+  }
 }
