I truly hope I'm not duplicating on you with this. I was having trouble with my site's geocoding failing to run automatically. I googled for a few issues and found multiple people never quite got their answers. I believe the issue is caused by 3 separate bugs, or maybe I just thing the module should work differently. For people looking for answers, it's important you understand that the location module is attempting to run for you if the coordinates are not user submitted. It just doesn't return any information about success or failures. This leads to a lot of head scratching for people. To that end, I recommend adding some drupal set messages. I've added them in the code I'll post here. First, a generic fallback:
In location.module, function: _location_geo_logic
else {
$location['source'] = LOCATION_LATLON_UNDEFINED;
$location['latitude'] = 0;
$location['longitude'] = 0;
//A generic fall back for when address geolocation fails
drupal_set_message(t('The location could not be identified based on the address, or zip code provided.'), 'warning');
}
But the actual bugs need to be addressed more than messages. In location.module, function: _location_geo_logic, an if statement currently reads:
if ($changed['street'] || $changed['additional'] || $changed['city'] || $changed['province'] || $changed['country'] || $changed['postal_code'] || $location['source'] == LOCATION_LATLON_USER_SUBMITTED) {
But later in the file it sets $location['source'] to LOCATION_LATLON_UNDEFINED (0). If the user saves the node again, without changing the address hoping to fire geoencoding, the if statement does not allow for the check (and gives no warning). I would suggest adding LOCATION_LATLON_UNDEFINED to the if statement. I know that it will only come up while testing like I am, or maybe if you hit your limit on geoencodes from google for a day, but it keeps the behavior more predicable. New if statement:
if ($changed['street'] || $changed['additional'] || $changed['city'] || $changed['province'] || $changed['country'] || $changed['postal_code'] || $location['source'] == LOCATION_LATLON_USER_SUBMITTED || $location['source'] == LOCATION_LATLON_UNDEFINED) {
Also in location.module, function: location_strip, the current stripping patterns were removing the ['locpick'], ['user_latitude'], and ['user_longitude'] arrays. If those are stripped out, the checks for differences that fire geoencoding fail to see a difference from the merged location array to the old location array. Please consider altering $tmp or changing the function to something similar to:
function location_strip(&$location) {
static $tmp;
if (!isset($tmp)) {
$tmp = array();
$defaults = location_invoke_locationapi($location, 'defaults');
foreach ($defaults as $k => $v) {
if (!isset($v['nodiff'])) {
$tmp[$k] = TRUE;
}
}
}
foreach ($location as $k => $v) {
if (!isset($tmp[$k])) {
if(!($location[$k] == "locpick" || $location[$k] == "user_latitude" || $location[$k] == "user_longitude")) {
unset($location[$k]);
}
}
}
}
In location.inc, function: location_get_postalcode_data, I found that the $country_specific_function was failing everytime. For me, at least, the required location.xx.inc file was not loaded at the time the function checked for it's existence. All that needed done was to include_once the country file. I've got code for that below, along with the drupal_set_messages if there are errors.
function location_get_postalcode_data($location = array()) {
$location['country'] = isset($location['country']) ? trim($location['country']) : NULL;
$location['postal_code'] = isset($location['postal_code']) ? trim($location['postal_code']) : NULL;
if (is_null($location['postal_code']) || is_null($location['country']) || empty($location['country']) || empty($location['postal_code']) || $location['postal_code'] == 'xx') {
return NULL;
}
$country_specific_function = 'location_get_postalcode_data_'. $location['country'];
if (function_exists($country_specific_function)) {
return $country_specific_function($location);
}
else {
if ($cache = cache_get('location:supported-countries', 'cache_location')) {
$country = $location['country'];
if ($cache->data[$country]) {
$include = drupal_get_path('module', 'location') .'/supported/location.'. $location['country'] .'.inc';
if (file_exists($include)){
include_once($include);
if (function_exists($country_specific_function)) {
return $country_specific_function($location);
} else {
drupal_set_message(t('The support file for: ' . $location['country']. ' found at <i>' . $include .'</i>. does not have a function to support zip code look ups. Missing funtion: <i>' . $country_specific_function . '</i>'), 'error');
}
} else {
drupal_set_message(t('The support file for: ' . $location['country']. ' could not be found at <i>' . $include .'</i>.'), 'error');
}
} else {
drupal_set_message(t('The country code requested: ' . $location['country']. ' is not supported by this site.'), 'warning');
}
} else {
drupal_set_message(t('There are no supported countries in the site cache.'), 'warning');
}
return NULL;
}
}
| Comment | File | Size | Author |
|---|---|---|---|
| #21 | location-411360.patch | 5.62 KB | hadsie |
| #16 | 411360-16.patch | 9.21 KB | wretched sinner - saved by grace |
| #14 | 411360-14.patch | 64.9 KB | wretched sinner - saved by grace |
| #7 | location.inc_.txt | 28.9 KB | lance.gliser |
| #7 | location.module_.txt | 59.11 KB | lance.gliser |
Comments
Comment #1
lance.gliser commentedMy generic fallback message has an issue.
If you set the location as optional, and the user fills in nothing, the message prints warning them it wasn't saved.
It needs an if statement checking if the user even entered a zip or street. Something like:
Comment #2
SeanBannister commented+1 been trying to get this working :)
Comment #3
pacesolutions commentedAs per my installation I did not found any problems. Everything is working as it suppose to work. Here how you can work around the problem.
Packages:
- Latest Drupal - http://ftp.drupal.org/files/projects/drupal-6.10.tar.gz
- Latest Location Module - http://drupal.org/project/location (6.x-3.1-rc1)
- Latest GMap Module - http://drupal.org/project/gmap (6.x-1.1-rc1)
- Install or Upgrade to latest Drupal 6.10
- Download and place modules in the modules directory of your Drupal.
- Now activate the following modules from Administrator section (admin/build/modules)
* User Locations
* Node Locations
* Location Search
* Location
* GMap
* GMap Location
- Once modules are enabled. Get Google Maps API and configure the Location module (admin/settings/location).
* In Main settings tab, make sure you select United States as default country.
* Toggle location display: Enable
* Use a Google Map to set latitude and longitude is checked.
* Now in Geocoding Options tab, under United States choose Google Maps.
* Hit saves Configuration
* Now again under United States choose Configure Parameters (This is where you put your Google API key).
- Now configure GMap module (admin/settings/gmap).
* Put your API key here (If not already there.)
* Set default width & height as you like and choose also the default center (e.g.: 39.9434364619742,-77.2998046875), you can also configure more settings as you like.
* Now hit Save Configurations to save them.
- Now configure GMap Location (admin/settings/gmap_location)
* For each Macro put something like this: [gmap zoom=3 |center=39.9434364619742,-77.2998046875 |width=100% |height=300px |control=Small |type=Physical]
- Now most important part is to enable Location block in the content or sidebar to display the map correctly.
* Enable 'Location map' block (admin/build/block) and set to display in sidebar or content - now a small map will be displayed next to nodes that have a location.
- You can create a new content type or modify the existing to display and enter the location/map data. I will modify the default Page content type (admin/content/node-type/page)
* Under Locative Information click on Number of locations
* Set 1 for Minimum number of locations, Maximum number of locations and Number of locations that can be added at once.
* Under Collection Settings, choose the fields you want to display in the form for adding/editing.
* Now hit Save Content Type.
- Now create a new test page (node/add/page) to see if Google maps are working or not.
* Fill the details as you like,
* Double click on the map to place the marker and auto fill the Latitude & Longitude
* Save the Page node.
- You should be able to see the Google Map with marker in right place under your block. You can free place Location block anywhere as you like.
There is no need for CCK or any other module to work around. CCK module is not working.
Comment #4
lance.gliser commentedI'm not entirely sure you have understood want I was after, pacesolutions.
You're suggesting that the user:
My current goal is let the user choose their own coordinates, like you suggest, or leave them unselected to fire geolocation automatically based off their address.
Your solution would end with all user entered coordinates, not what I'm after.
Also the purpose of this posting is to address your last line:
I have posted solutions to multiple bugs in the location module.
When fixed, the CCK module does work. I user multiple working CCK Location fields over multiple content types on the site I'm building. And they all work fantastically. (Well... it get's sketchy when you try to pull the view.)
I have a working copy solution. I'm trying to give back since the developers did the majority of the heavy lifting.
Comment #5
ajevans85 commentedJust trying this module and was unable to get automatic population of lng/lat fields.
Applying the patch from lance.gliser lead me to track the issue down to the location.uk.inc not having the function 'location_get_postalcode_data_uk' . Thats only half my problem as 'location_get_postalcode_data_uk' should be a fallback function if geocaching isn't working (and i had set up geocaching). I haven't had chance to implement 'location_get_postalcode_data_uk' yet as I am more concerned with the google geocaching and feasability of integrating this module with the apache solr module with solr local searching. As I am uk based and things are looking promising when just playing about with this I'll probably have a patch soon as it's fairly trivial.
Any way back to my problem... further tracking lead me to the '_google_geocode_flatten' function. It was generating a invalid query string for uk geo caching. The function applies the province code 'CHS' for Cheshire, this meant nothing to Google as 'CHS' it's not a valid UK county (province). Changing the flatten function to use province name also didn't work, it was a valid address but google was still providing a status 602 (no valid address found). Dropping the province filed worked so my function now looks like:
Works for me but not that elegant considering theres 242 supported locations in the supported directory and they may all need to structure the query sting differently. What would probably be better is checking if a function such as 'location_geocode_flatten_$country' exists to flattern the string otherwise fall back to the default implementation.
I agree with lance that some error messages are needed and without his patch it probably would of took me longer tracking down my issue.
Comment #6
pacesolutions commentedAbove fixes seems to work with CCK and Location module.
If you can provide the complete location.module file, that will be more helpful.
Comment #7
lance.gliser commentedI'll upload the two file's I've altered.
Look for //emfluence on the functions I've altered.
Also, to get CCK working with views I had to do the work around in http://drupal.org/node/366880
It's a nasty hack, acknowledged by the author and myself. You have to theme out locations and theme in location CCK.
I'm waiting for his proper fix. But for now it all works when you put it together.
Comment #8
yesct commentedthe idea in the original post about messages seems reasonable.
Comment #9
kvvnn commentedSubscribing - will edit w/ results
Comment #10
kvvnn commentedPrompting the User , and preventing the form from being submitted if (latitude, longitude) can not be found
Line 574, location.module
I prefer this to the #1's initial code sample, because it stops the form from saving information in the database. Obviously, it would be best to have a map for the user to manually enter a location after this, instead of not allowing non-supported cities.
Comment #11
socialnicheguru commentedsubscribing
Comment #12
wretched sinner - saved by grace commentedI have tested the replacement files from lance in #7, and my maps are now displaying (I'm in Australia)
I can roll a patch if required...
Comment #13
summit commentedYes please, roll a patch!
Thanks in advance! Greetings, Martijn
Comment #14
wretched sinner - saved by grace commentedI have attached a patch for the files in #411360-7: Node Locations not geocoding, no errors given.
Comment #15
jax commentedThe patch completely replaces location.inc with lines that end in CR LF in stead of only LF. Please configure your text editor correctly and reroll the patch.
Comment #16
wretched sinner - saved by grace commentedSorry about that. I just copied the files in #411360-7: Node Locations not geocoding, no errors given. over and diffed from there. I didn't think to check the line endings, and that would explain the trouble I had last time.
Attached is a patch with correct line endings.
Comment #17
jax commentedThis is meaningless:
Is $location['country'] is not set then $location['country'] will be different than 'xx' … Also I'm not sure this even should be modified.
Please remove:
Comment #18
mvci agree with all of lance.gliser's suggested changes described above in the original post. however, as i understand it, form_set_error() can only be called from a form validation function. all of the above changes including warnings are very useful, but if you want to force your users to choose a valid location either by geocoding or by clicking on the map, those aren't sufficient. the geocoding isn't even attempted until $op 'save' case of location_node's nodeapi hook, by which point all validation is supposed to be completed.
i personally solved this via a custom module which we'll call my_custom_module shown here acting on a custom content type we'll call test:
the correct solution would be to add the validation hook to location_node and a setting someplace specifying whether users should be forced to submit a valid location via one of these two strategies. i wasn't sure where to put this UI code so i just used a separate module but hopefully this is a good starting point for anyone wanting to do this properly. ideally the geocoding functions themselves wouldn't have to be called twice, but that would be a more drastic change to this module then i currently have the time for.
Comment #19
osopolarI came here while I was looking for a way to validate the postal code in the cck address field. Maybe it would be useful to know that there is a hook_locationapi which allows form validation. It's especially useful if you have to validate the same field in different forms. Here a short example:
Comment #20
reubenavery commentedNow this is what I call a handsome bug issue thread. Subscribing :-) patch #16 solved things for me, btw.
Comment #21
hadsie commentedI've re-rolled the patch against the latest dev version. There were a couple things I didn't understand in the patch though:
* The part starting with "case 'instance_links':", where is this called from? I see it's added in the patch, but don't see any code that the patch adds that would evaluate this.
* You remove the _location_patch_locpick() function... why is this?
Comment #22
yesct commentedSomeone please post a summary of the current status of this issue, like for example does the patch in #21 address the concerns brought up in #16 and #17?
If someone can provide a good summary and review, it will make it much more likely that a maintainer will take a look at the proposed solution and we might have a chance of getting a commit. Post the summary assuming someone is coming in fresh and has not been following every step of the way.
Comment #23
hadsie commentedThe patch I created in #21 does not take into account #17. It does take into account #16.
Comment #24
nickbits commentedHi,
The patch from #21 works for me on newly created nodes just fine for me.
Nick
Comment #25
Anonymous (not verified) commentedWith the newest 6.x-3.x-dev version geocoding does not work for me. Providing a manual location via the map does work fine, but geocoding from an address does not. All the necessary api keys are there.
Second thing which I do not understand is that once I enter a manual lat/long I cannot delete it anymore. It can be removed, but as soon as the the node is saved the old location is back.
Any suggestions?
Thanks and best regards
SkyWombat
EDIT: Patch #21 works as far as error messages are concerned, but geocoding still is not working properly. The error message reads: "The support file for: es found at sites/all/modules/location/supported/location.es.inc. does not have a function to support zip code look ups. Missing funtion: location_get_postalcode_data_es"
But according to the settings a Spanish address should be geocoded via google, so why do I need a zip look up function? Is there some misunderstanding on my side?
EDIT2: It works for Germany without any issue, but for Spain it does not. Any ideas?
Comment #26
yesct commentedin your edit #2, do you mean that it works for germany without the patch?
Comment #27
yesct commentedtagging.
Comment #28
Anonymous (not verified) commentedI did not try it for Germany without the patch. But it worked with the patch.
For Australia it did not work without the patch, but it works with the patch.
Oddly enough, after some hacking of location.es.inc it did not work immediately, but after one day waiting it is now working fine. Maybe there was an issue with caching the location function or there was an issue with the connection to google maps. I have no clue.
Currently everything seems fine and I' happy.
Hacking of location.es.inc was just copying the routines of location.de.inc and adjusting names and country specific points.
Comment #29
bryancasler commentedsubscribing, any update would be helpful
Comment #30
webwriter commentedSubscribe. Sometimes I get a geolocation from an adddress, sometimes I do not. I can't seem to find a pattern to it.
Comment #31
UNarmed commentedThis geocode things is a nightmare i simply cant get it to work.
Comment #32
Josephnewyork commentedI figured it out! It must be a particular order of when the geocoding options are set and what other options are also set...
If the geocoding doesn't auto-fill the long/lat, go to admin/settings/location/geocoding, and click "Reset to default". Then, choose your geocoder again, (im my case, USA:google) and "Save configuration"
Now its working :)
Comment #33
alexborsody commentedI was having the same problem. I was able to fix this by uploading a list of area codes and searching by proximity
Comment #34
summit commentedHi, @F.E.M. COUld you elaborate more on this. Somehow I do not get geocoding working anymore..
Thanks a lot in advance. Greetings, Martijn
Comment #35
marleo commentedIn my case it was being stopped by the "State/Province" field being filled by people using a commonly-used abbreviation. The correct name for the state is "Victoria", but it's very common here (Aus) for people to enter abbreviated state names, eg "VIC". Choosing the auto-lookup "Victoria" as offered by the field made it work.
Comment #36
Marc Storms commentedI was having the same problems. The patch helped me to get the error "Google geocoding returned status code: 610" and googling this I found on comment 40 of http://drupal.org/node/1940474 the patch that solved my day (I am using Location 6.x.3.2).
Thanks to all of you.
Comment #37
legolasboClosing old D6 issues as D6 is end of life