What is the correct way to modify the location data during an update/insert?
You can't modify the data during the save, as the geocoding hasn't occured yet, so it has to be during update/insert...
The method below I'm trying has the effect of creating _extra_ locations, despite my attempts to fix this...
Background: using zipcode geocoding, all of the items are given identical lat/lon, leading to a map with all of the items stacked in one place.
A random 'peppering' effect is desired, once geocoding occurs, I want to modify the lat/long automagically, adding a random factor.
I ONLY want one location, and the content type is set to only allow one location.
function CUSTOMMODULE_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
// copied from location module, for code clarity
define('LOCATION_LATLON_UNDEFINED', 0);
define('LOCATION_LATLON_USER_SUBMITTED', 1);
define('LOCATION_LATLON_GEOCODED_APPROX', 2);
define('LOCATION_LATLON_GEOCODED_EXACT', 3);
// if the nodetype allows locations
if (!variable_get('location_maxnum_'. $node->type, 0)) {
return;
}
// only if it's the desired nodes, pepper the geocoding
if ($node->type == "item1" OR $node->type == "item2") {
switch ($op) {
case 'insert':
case 'update':
$node->locations[0] = location_form2api($node->locations[0]);
$node->locations[0]['latitude'] = trim($node->locations[0]['latitude']);
$node->locations[0]['longitude'] = trim($node->locations[0]['longitude']);
// submitted lat/lons are either blank or valid numbers. Now, we need to find out determine
// the source of these lat/lons since they can either be prefilled from postalcode data
// or manually entered by the user.
if (!empty($node->locations[0]['latitude']) && !empty($node->locations[0]['longitude']) && ($node->locations[0]['source'] > 1) ) {
// add a random variation, plus or minus a bit, to 'pepper' the values.
$node->locations[0]['lat'] = (float)$node->locations[0]['latitude'] + ((.5 - ((float)rand()/(float)getrandmax())) *.1);
$node->locations[0]['lon'] = (float)$node->locations[0]['longitude'] + ((.5 - ((float)rand()/(float)getrandmax())) *.1);
$node->locations[0]['source'] = LOCATION_LATLON_USER_SUBMITTED;
// added in attempt to deal with dupes, but didn't...
if ($node->locations[0]['lid']) {
db_query('DELETE FROM {location} WHERE lid = %d', $node->locations[0]['lid']);
location_invoke_locationapi($node->locations[0], 'delete');
}
//without the save, the data isn't saved.
_location_save($node->locations[0] ? $node->locations[0] : array(), $node, 'node');
}
break;
default:
break;
}
}
return;
}
So what am I doing wrong here? And if there is a better way to do this, what is it?
Comments
Comment #1
sethcohn commentedFound a better way... I'll post it in the next day or 3...
essentially, I needed to reload the node (to get an lid) and then used SQL to directly update the location table.
Comment #2
sethcohn commentedThis is the major difference from the above code... except this works.
Fixes:
a) reload the node... it's stale already, location has changed the contents, and added fields.
b) don't try and use the save, do a direct SQL update.
Comment #3
summit commentedWill this also help in D6, greetings, Martijn