Serverside Google geocoding

Last updated on
30 April 2025

Getlocations does all it's geocoding clientside (eg in the browser) but there may be times when a developer needs to do some geocoding serverside, here are a couple of functions to help with that:

/**
 * Geocode an address
 * Input can be a string or an array
 * Output is an array if successful, string if failed
 *
 */
function google_geocode($address) {
  if (empty($address)) {
    return;
  }
  if (is_array($address)) {
    if (count($address)) {
      $address = implode('+', $address);
    }
    else {
      return;
    }
  }

  $query = array(
    'address' => $address,
    'sensor' => 'false'
  );
  $msg = '';
  $url = url("http://maps.googleapis.com/maps/api/geocode/json", array('query' => $query));
  $result = drupal_http_request($url);
  $data = json_decode($result->data);
  $status = $data->status;
  if ($status == 'OK') {
    return array(
      'latitude' => $data->results[0]->geometry->location->lat,
      'longitude' => $data->results[0]->geometry->location->lng,
      'location_type' => $data->results[0]->geometry->location_type
    );
  }
  elseif ($status == 'ZERO_RESULTS') {
    $msg = t("No result");
  }
  elseif ($status == 'OVER_QUERY_LIMIT') {
    $msg = t("Over query limit");
  }
  elseif ($status == 'REQUEST_DENIED') {
    $msg = t("Request denied");
  }
  elseif ($status == 'INVALID_REQUEST') {
    $msg = t("Request invalid");
  }
  return $msg;
/**
 * "OK" indicates that no errors occurred; the address was successfully parsed and at least one geocode was returned.
 * "ZERO_RESULTS" indicates that the geocode was successful but returned no results. This may occur if the geocode was passed a non-existent address or a latlng in a remote location.
 * "OVER_QUERY_LIMIT" indicates that you are over your quota.
 * "REQUEST_DENIED" indicates that your request was denied, generally because of lack of a sensor parameter.
 * "INVALID_REQUEST" generally indicates that the query (address or latlng) is missing.
 */

}

/**
 * Reverse Geocode an address
 * Input can be a string or an array
 * Output is an array if successful, string if failed
 *
 */
function google_reverse_geocode($latlng) {
  if (empty($latlng)) {
    return;
  }
  if (is_array($latlng)) {
    if (count($latlng)) {
      $latlng = implode(',', $latlng);
    }
    else {
      return;
    }
  }
  $query = array(
    'latlng' => $latlng,
    'sensor' => 'false'
  );
  $msg = '';
  $url = url("http://maps.googleapis.com/maps/api/geocode/json", array('query' => $query));
  $result = drupal_http_request($url);
  $data = json_decode($result->data);
  $status = $data->status;
  if ($status == 'OK') {
    $address_components = $data->results[0]->address_components;
    $out = array();
    foreach ($address_components AS $component) {
      $type = $component->types[0];
      if ($type == 'street_address') {
        $out['street_address'] = $component->long_name;
      }
      if ($type == 'street_number') {
        $out['street_number'] = $component->long_name;
      }
      elseif ($type == 'route') {
        $out['route'] = $component->short_name;
        $out['address1'] = $component->long_name;
      }
      elseif ($type == 'locality') {
        $out['locality'] = $component->long_name;
      }
      elseif ($type == 'administrative_area_level_3') {
        $out['administrative_area_level_3'] = $component->long_name;
      }
      elseif ($type == 'administrative_area_level_2') {
        $out['administrative_area_level_2'] = $component->long_name;
      }
      elseif ($type == 'administrative_area_level_1') {
        $out['administrative_area_level_1'] = $component->long_name;
      }
      elseif ($type == 'country') {
        $out['country'] = $component->long_name;
        $out['country_short'] = $component->short_name;
      }
      elseif ($type == 'postal_code_prefix') {
        $out['postal_code'] = $component->long_name;
      }
      elseif ($type == 'intersection') {
        $out['intersection'] = $component->long_name;
      }
      elseif ($type == 'colloquial_area') {
        $out['colloquial_area'] = $component->long_name;
      }
      elseif ($type == 'sublocality') {
        $out['sublocality'] = $component->long_name;
      }
      elseif ($type == 'neighborhood') {
        $out['neighborhood'] = $component->long_name;
      }
      elseif ($type == 'premise') {
        $out['premise'] = $component->long_name;
      }
      elseif ($type == 'subpremise') {
        $out['subpremise'] = $component->long_name;
      }
      elseif ($type == 'natural_feature') {
        $out['natural_feature'] = $component->long_name;
      }
      elseif ($type == 'airport') {
        $out['airport'] = $component->long_name;
      }
       elseif ($type == 'park') {
        $out['park'] = $component->long_name;
      }
      elseif ($type == 'point_of_interest') {
        $out['point_of_interest'] = $component->long_name;
      }
       elseif ($type == 'post_box') {
        $out['post_box'] = $component->long_name;
      }
      elseif ($type == 'floor') {
        $out['floor'] = $component->long_name;
      }
      elseif ($type == 'room') {
        $out['room'] = $component->long_name;
      }
    }
    $out['formatted_address'] = $data->results[0]->formatted_address;
    $out['location_type'] = $data->results[0]->geometry->location_type;
    return $out;
  }
  elseif ($status == 'ZERO_RESULTS') {
    $msg = t("No result");
  }
  elseif ($status == 'OVER_QUERY_LIMIT') {
    $msg = t("Over query limit");
  }
  elseif ($status == 'REQUEST_DENIED') {
    $msg = t("Request denied");
  }
  elseif ($status == 'INVALID_REQUEST') {
    $msg = t("Request invalid");
  }
  return $msg;
/**
 * "OK" indicates that no errors occurred; the address was successfully parsed and at least one geocode was returned.
 * "ZERO_RESULTS" indicates that the geocode was successful but returned no results. This may occur if the geocode was passed a non-existent address or a latlng in a remote location.
 * "OVER_QUERY_LIMIT" indicates that you are over your quota.
 * "REQUEST_DENIED" indicates that your request was denied, generally because of lack of a sensor parameter.
 * "INVALID_REQUEST" generally indicates that the query (address or latlng) is missing.
 */

}

Help improve this page

Page status: Not set

You can: