Hi all,
this is an issue I came along when I'd to implement location search for austria.
Currently there is no support of austria (no database database/zipcodes.at.mysql) within the location project.
What to do?

I descided to get rid of all this database zip stuff and to implement a small function that requests the location data dynamicly from google:

function get_coordinates_from_zip($country = 'de', $zip = '', $city = '', $street = '') {
 $query = array(
		'key' => /* your google key */',
    'q' => $zip . '+' . $city . '+' . $street . '+' . $country
  );
  $url = url('http://maps.google.com/maps/geo', array(
    'query' => $query,
    'external' => TRUE,
  ));

  $http_reply = drupal_http_request($url);
  $location_data = json_decode($http_reply->data);

  if ($location_data->Status->code != 200) {
  	drupal_set_message('Derzeit kein Zugriff auf Google möglich', 'error');
    return NULL;
  }

  $point['latitude'] = $location_data->Placemark[0]->Point->coordinates[1];
  $point['longitude'] = $location_data->Placemark[0]->Point->coordinates[0];

  return $point;
}

Just change e.g. location.de.inc to

function location_get_postalcode_data_de($location = array()) {
  $dash_index == strpos($location['postal_code'], '-');
  // First we strip slash off if we're dealing with a 9-digit US zipcode
  if ($dash_index === FALSE) {
    $location['postal_code'] = substr($location['postal_code'], 0, $dash_index);
  }

  // $pixelfraud patch reading lat/lon from google instead of reading from DB 
  $point = get_coordinates_from_zip( $location['country'] = 'de',
  						       $location['postal_code'],
  						       $location['city'],
  						      $location['street'] );
																							 
  return array('lat' => $point['latitude'],
               'lon' => $point['longitude'],
  						 'city' => $location['city'],
  						 'province' => '',
  						 'country' => $location['country']); 
 }

and it works!.

Please check this approach and i will apreciated if this approach will find its way in the location module.
thx joerg

Comments

summit’s picture

Hi,
This is looking great. Does this mean that not the .inc files are used with this solution, but the google api is used instead?
As this is the case, could you also add $location[province] to the code?

Thanks a lot in advance for your response.
greetings,
Martijn

hutch’s picture

if gmap is installed you can get the google key with gmap_get_key()

summit’s picture

Hi, could you explain what you mean with gmap_get_key() in code example please?

hutch’s picture

For example:

if (module_exists(gmap)) {
  $key = gmap_get_key();
else {
  $key = "your_key_here";
}

As running location module without gmap seems odd to me this should help integrate your ideas. I haven't tested the json idea but it looks good, it just needs integrating into location, possibly by putting it into supported/location.at.inc (for Austrian searches)

If someone can post some Austrian addresses to test with I'll have a go ;-)

joergm’s picture

you're totally right you don't use the .inc files but the google api instead.
Here is the Link to the Google Maps API Key generator : http://code.google.com/intl/en/apis/maps/signup.html
This key you've to insert into the code example, just replace /* your google key */ with the generated key.
Concerning the $location[province] just look at the google API eg http://maps.google.com/maps/geo?q=de+80809 and you can see what information is available.
joerg

summit’s picture

Hi I am still confused.
I use allready the google maps api together with location and gmap.

But when I want to set a camping on a specific spot, I need to insert the country, province and place through the Location UI Right? To have these values come up next to the camping as a sort of address.

For this I need the location.xx.inc files (for example autocomplete province in latest version of location).
I use for example location.fr.inc and in this there is a list of provinces, but the one which is in .dev is not complete.

But..couldn;t this list be got through a webservice on google so that the same provinces are used as on google maps?
Now I can add some things to the list, and then with clearing the province cache the new provinces are there, but isn't this a waste of time?
Shouldn;t location use other webservices to fill these lists like province and places?

Does anybody have a working example for say france or italy to use this sort of service together with location and gmap?

Thanks a lot for going into this again, and sorry if I was not clear enough in my latests posts.
greetings, Martijn

joergm’s picture

Hello Martijn,
ok, for the complete list of provinces you need the function location_province_list_xy() in supported/location.xy.inc.
I don't know any web-interface that will provide you the complete list.
joerg

joergm’s picture

Hallo all,
again some news concerning my feature request to integrate http://maps.google.com/maps/geo API instead of using database zip tables.

Here is an update of the Google api request code:

function get_location_infos($country = 'de', $zip = '', $city = '', $street = '') {

$q = $country;
if ($zip != '')
	$q .= '+' . $zip;
if ($city != '')
	$q .= '+' . $city;
if ($street != '')
	$q .= '+' . $street;
	
$query = array(
		'key' => 'xyzassddffgghghhhhjjjkkklklllwehiohgoiweghoiweqghoiwegho',
                /* You get your  Google Api key here http://code.google.com/intl/en/apis/maps/signup.html */
               'q' => $q
  );

  $url = url('http://maps.google.com/maps/geo', array(
    'query' => $query,
    'external' => TRUE,
  ));

  $http_reply = drupal_http_request($url);
  $location_data = json_decode($http_reply->data);

  if ($location_data->Status->code != 200) {
  	$infos['status'] = t('Google Map Interface error, please try later');
  }
  else {
	
  	$infos['CountryName'] = $location_data->Placemark[0]->Country->CountryName;
  	$infos['CountryNameCode'] = $location_data->Placemark[0]->Country->CountryNameCode;
	  $infos['latitude'] = $location_data->Placemark[0]->Point->coordinates[1];
	  $infos['longitude'] = $location_data->Placemark[0]->Point->coordinates[0];
	  $infos['province'] = $location_data->Placemark[0]->Country->AdministrativeAreaName;
	  $infos['status'] = 'OK';
	  
	  if (strtolower($location_data->Placemark[0]->AddressDetails->Country->CountryNameCode) != strtolower($country)) {
	  	// ungültige PLZ
	  	$infos['status'] = t('unknown postal code');
	  }
  }
  
  return $infos;
}

And here is the function that supports italy in support/location.it.inc.
You can change this piece of code to any desired country.
E.g. for country xy just edit support/location.xy.inc and add the following function.
Adapt the function to country xy: change the name of the function to location_get_postalcode_data_xy and within the function the line $infos = get_location_infos($location['country'] = 'xy'.

function location_get_postalcode_data_it($location = array()) {
  $dash_index == strpos($location['postal_code'], '-');
  // First we strip slash off if we're dealing with a 9-digit US zipcode
  if ($dash_index === FALSE) {
    $location['postal_code'] = substr($location['postal_code'], 0, $dash_index);
  }

  // $pixelfraud Patch reading lat/lon from google instead of reading from DB 
  $infos = get_location_infos($location['country'] = 'it',
  					  $location['postal_code'],
  					  $location['city'],
  					  $location['street'] );
																							 
  return array('lat' => $infos['latitude'],
               'lon' => $infos['longitude'],
  	       'city' => $location['city'],
  	       'province' => $infos['province'],
  	       'country' => $location['country']); 
 }
hutch’s picture

See geocoding/google.inc, function google_geocode_location() for code that already does this.

ankur’s picture

Status: Active » Closed (fixed)

This issue should be resolved now, by the function mentioned by hutch in #9