Hi,

I try to geocode the user adress from an Adress field cck and there're no data output follow up the geocoding.

How can I solve that issue?

Thanks in advance,

Comments

Loikkk’s picture

No one have this bug?

tvilms’s picture

I'm having this bug too. It's really really frustrating, and I can't seem to get to the bottom of it. I get two types of errors, depending on how I'm configuring the content type fields:

Error #1: Trying to get property of non-object in GoogleGeocode->read() (line 51 of /public_html/sites/all/libraries/geoPHP/lib/adapters/GoogleGeocode.class.php).

Error #2: Warning: Invalid argument supplied for foreach() in geocode_widget_validate_walkthrough() (line 287 of /public_html/sites/all/modules/geocode/geocode.module)

Error 1 seems to be related to Geofield when it tries to geocode the address. Error 2 is then something in the geocode module itself. I had this all working a few module updates back, but now it's not geocoding. I suspect there may be something in Address Field that's leading to Error #1, which I see most of the time.

idmacdonald’s picture

Title: Adress Field and Geocode » geoPHP library needs 'allow_url_fopen' to use Google API
Project: Address Field » Geocoder

The module uses $this->result = json_decode(@file_get_contents($url)); (line 49 of GoogleGeocode.class.php) to actually send the request to Google and get the response. However, the file_get_contents operation will only work if 'allow_url_fopen' is on in the PHP configuration. If 'allow_url_fopen' is not allowed, then the 'file_get_contents' will not be allowed to execute, but the '@' sign suppresses error reporting. A lot of hosting providers rightly consider allow_url_fopen to be a security risk, so it's not really ideal. But this is in the geoPHP library, so I guess an issue should be filed with that project rather than here on Drupal.org.

In any case, in the Apache configuration, I added this line, which made the thing work: php_admin_flag allow_url_fopen on

Drupal uses 'drupal_http_request()' these days for those sorts of operations. It would be good if the geoPHP library could use something similar instead of 'allow_url_fopen'.

-Ian

idmacdonald’s picture

Project: Geocoder » Geofield
Version: 7.x-1.x-dev » 7.x-1.0-alpha5
Assigned: Loikkk » Unassigned
hutch’s picture

Personally I think the geoPHP library is overkill, something like this works (from a helper module I use on one of my sites):

/**
 * Geocode an address
 * Input can be a string or an array
 * Output is an array if successful, string if failed
 *
 */
function myhelper_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 myhelper_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.
 */

}

They work with allow_url_fopen Off, 'drupal_http_request()' uses 'stream_socket_client()'

Seems a better way to do it.

Brandonian’s picture

Project: Geofield » Geocoder
Version: 7.x-1.0-alpha5 » 7.x-1.x-dev

Two things:

1. From the Drupal module perspective, this is an issue with Geocoder, not Geofield. This functionality isn't called from anywhere in Geofield proper. It's up to the maintainers of Geocoder to address if/how to tackle this problem on the module level. IMHO, hutch's code at a glance looks like it could work either as a fallback or as the primary geocoding engine, but would basically amount to duplicating effort between the library and the module.

2. Since the issue is really with the library, the issue needs to be taken up there. I've opened up an issue there for discussion. https://github.com/phayes/geoPHP/issues/6

phayes’s picture

Interesting that drupal_http_request is allowed but fopen is not!

I would fully support not using geoPHP for geocoding purposes. I think hutch's approach makes a lot of sense. It also helps resolve the issue we were having with additional metadata that geoPHP doesn't return.

phayes’s picture

Status: Active » Fixed

This has been fixed. We're now using a hand-rolled google-geocoder.

This is better anyway as it will let us to address this request: #1295262: Accuracy from google geocode

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

ahmedhanyfawzy’s picture

#5 is working , very good solution since the location and gmap still under development and their patches are useless in doing reverse geocoding.

Thanks hutch you made my day :)