Proximity Search using Views in Drupal
Wed, Feb 10, 2010 by Rexx
Problem:
I am working on a project that requires the user to input a maximum of two zip codes during. When the user is redirected to their dashboard, based on the zip codes provided, the site should list advertisers within the 30 mile radius. Note that if the user decides to change their zip codes later on, somewhere on their profile, the dashboard will show advertisers within the radius of the given zip codes.
Solution:
Implement the advertiser as a node with node location attached to it and create a “Location" type view.
Modules used:
Location – 6.x-3.0
Views - 6.x-2.7
Implementation:
Here are the steps to create the “Location" view, which will do a proximity search, given the user's zip code on their profile:
1) Navigate to "admin/build/views/add".
2) Enter the view name and description.
3) Select “Location" under “View type".
4) Under “Fields", select “Location" and add “Location: Distance / Proximity"
NOTE: The distance from the selected location and either the current user or a specific location.
5) Configure “Units" and select the “Origin" to “User's location (blank if unset)" or “User's location (fall back to static if unset)"
6) Click Update.
7) Under “Filters", select “Location" filter
8) Add “Location: Distance / Proximity" and set the “Distance"
To make it dynamic we need to modify the view object by inserting the latitude and longitude of the zip code, which corresponds to the user. We also need to modify the filter, so that we can insert the latitude and longitude for the distance. Since the user does not have a location then you will have to calculate the latitude and longitude of the given zip code. In order to do this, we need to implement hook_views_pre_view.
function my_module_views_pre_view(&$view, &$display_id, &$args) {
if (in_array($view->name, $proximity_views)) {
global $user;
$params = array(
'uid' => $user->uid,
'type' => 'subscriber_account',
);
$subscriber_account = node_load($params);
$zip_code = $subscriber_account->field_zip_codes[0]['value'];
if ($zip_code) {
module_load_include('inc', 'location', 'geocoding/google');
$location['postal_code'] = $zip_code;
$points = google_geocode_location($location);
$user->locations[0]['latitude'] = $points['lat'];
$user->locations[0]['longitude'] = $points['lon'];
// will filter advertisers from within 30 miles of this coordinate
if((arg(0) == 'admin') &&
(arg(1) == 'build') &&
(arg(2) == 'views') &&
(arg(4) == 'preview')) {
// NOTE:
// Only works on you are on Views UI and trying to preview the view.
$view->display[$display_id]->handler->handlers['filter']['distance']->value['latitude'] = $points['lat'];
$view->display[$display_id]->handler->handlers['filter']['distance']->value['longitude'] = $points['lon'];
} else {
// NOTE: Will NOT work when using
// Views UI. It will work when you invoke views_embed_view
$item = $view->get_item($display_id, 'filter', 'distance');
$item['value']['latitude'] = $points['lat'];
$item['value']['longitude'] = $points['lon'];
$view->set_item($display_id, 'filter', 'distance', $item);
}
}
}
}
There are alternative ways of solving this issue. However, since we only needed to embed the view on some pages, this solution will do.
Share some of your ideas and thoughts on how we can solve the issues of proximity searching, given the users zip code.
salmi posted on July 29, 2010 7:35 pm
I spent whole day and finnaly your guide really makes my happy day.
Thinking back, I am shocked in the location dev version (currenty dated as 27-May), those 2 bugs and (addtional function required in the xx.inc) have not been fixed even it's so obviously.
paul posted on July 14, 2010 6:20 pm
. Implementing location proximity search (for Belgium) with Drupal and .... Not sure what version of Views you are using on this tutorial ...
TBasket posted on June 24, 2010 5:35 am
I did the same thing but it's not working for me. I get no search results. I uploaded the us database into my database and followed all the instructions. What's the problem with it?
Mike T posted on April 26, 2010 6:51 pm
I am unclear of where that code goes as well. Everything else I had setup. This seems like it will solve my problem. Any help on where that code goes would be appreciated.
Alex posted on March 12, 2010 4:36 am
Thank you so much for this. I adopted your example to my problem and it works like a charm. Much obliged!
John posted on February 28, 2010 11:12 am
Hi Rexx,
Thanks for this tutorial, but how do I ' implement hook_views_pre_view'? Where do I put that code?
John
Andy posted on February 15, 2010 9:28 pm
Hi Rexx,
You said that you need to implement the pre_view hook to make the view 'dynamic'. I'm not sure I get that: are you referring to the fact that Views won't accept a zip code for its distance filter, so you need to have an up-to-date location? If so, do you think an alternative implementation could use a computed_field that generates the location from the zip code?
Thanks for the article,
Andy
Jeremy posted on February 11, 2010 12:48 pm
Unbelievable. I had this EXACT idea about 8 months ago and have two different projects that I have completely mapped out but haven't built yet. This idea of local ads was the whole reason I started learning Drupal and have been devouring every learning tool around for the past 6 months trying to learn all I can about Drupal. Creating sites in my minimal spare time will always have me trailing the pack.
Kudos for implementing this and for posting it out there for others to follow.
Thanks.
Jeremy
Post new comment