Proximity Search based on lat/lon, using views arguments
yhzsailor - January 11, 2009 - 15:59
| Project: | Location |
| Version: | 6.x-3.0 |
| Component: | Location_views |
| Category: | feature request |
| Priority: | normal |
| Assigned: | bdragon |
| Status: | needs work |
| Issue tags: | location bounties, location proximity to user viewing node, Location proximity view, location useful code, location view arguments |
Description
I would like the views module to be capable of doing a proximity based on a proximity search where the Latitude & Longitude are supplied as parameters and not input through a map view. Perhaps I'm missing how I can do this.

#1
I am also interested in implementing args in views for lat/lon.
#2
subscribe
I'm also looking for a way to create views on the proximity of the current viewed node id. This feature would make that possible, I think.
#3
Good idea.
#4
bdragon, I'll take a hack or beta version for testing if/when you are ready.
#5
Any progress? I too volunteer to beta test on this feature.
Can't wait to see it implemented:)
#6
Hi, I've rewrite the module to allow search for street, city and others. But it needs some work. If anyone is interested i attach the file rewritten, just replace it by the original and test it. I will improve some features in a few weeks so i don't have time right now.
if you have some questions or sugestions mail me silverhubahubi@gmail.com
#7
What am I missing ... I don't have this include file in Drupal 5. :(
#8
this is for drupal 6, but in drupal 5 it would be something similar
#9
hubahubi, your modified version, does that include the ability to use lat/lon as arguments?
If so, Ill gladly test it! :)
#10
Yes, I've modified the include to allow another form mode called address auto geocoded. But it needs some work, for example allow search for postal number and choose country for example. made a backup of the include and try it. Maybe you have troubles with the theme, tell me your opinion.
#11
hubahubi,
Great job... this works great for me. Not only that but I can sort the table's results by distance (nearest to farthest) from the entered address.
Is there anyway to make it show the distances from the address entered to the addresses shown in the views table?
I am making a radio tower checker... the radio towers addresses and range are entered in via cck. I want someone to be able to type in their address and check weather or not a radio tower is within range.
EDIT: Figured it out, awesome! I just added a distance/proximity field to the view.
One thing to note: You dont really need the 'number' textbox. I just put in 10712 Frog St in the 'street' text box and it still works.
Thanks,
#12
Is this feature implemented in dev yet?
#13
I'm confused about the status too. I'm thinking of trying out this file .. But my info is stored as CFO [edit: CCK. my phone is "correcting" my misspelling of CCK to CFO... opps] location fields And I'm using the nid, vid, genid hack and I'm not sure about the two hacks interacting! :)
[edit: I didn't link to the hack when I posted this.. I dont remember which one it was, but it might have been #382778: Location CCK does not save nid and vid ]
#14
#394624: How-to? Embedded Proximity View/ Passing Args might be related (EDIT: it was marked as a duplicate of this one)
#15
I tried replacing the file with #6, but the proximity filter only works if I fill in the lat and long...
I attached some screen shots, one set is with just the zip, one set is with the lat/long.
I would LOVE to be able to have a zip exposed filter in a view.
I wonder why my zip set didnt work... I thought #6 would get it to work...
Any ideas?
#16
EDIT: Wrong thread, sorry:)
#17
To put things straight (hope I haven't misunderstood something):
This thread seems to be discussing two different issues, with a turn in #6:
1: the ability to use ARGUMENTS in the creation of views (embed a map into a page with predefined values) (#1 - #6)
2: Modifying the SEARCH FILTER to include more parameters. (#6 - #15)
The second issue should be put into its own issue thread.
Args are still missing for lat and lon, i'm very much in need for that:)
Is there any progress on this?
EDIT:
I declare a USD $50 bounty to the someone who implements lat/lon args, if an alpha/beta/hack is available before April 27th 2009.
Hope this helps speeding up progress:)
#18
does anyone know how to add a chip in? per issue, or for the whole module?
Also, hamaldus, consider describing exactly what your bounty is for. I know you said this issue, but I've must admit, there are many components to location, proximity, search, arguments, cck. It is a bit confusing. And repeating exactly what your bounty is for, might make it easier for someone who wants to work on it. :)
#19
Marked
#208686: Views filters - Filter by typed address and Filter by proximity to user
as a duplicate of this one.
And tagging.
#20
marked
#247499: How to make the proximity search by using arguments.
as a duplicate of this one.
[edit fixing [#nnnnnn] notation so it correctly shows the issue title, etc]
#21
YesCT, here's a description of what the $50 bounty is for:
I need the ability to implement proximity views (maps,lists etc) into nodes (tpl) using lat/lon arguments.
Then, it will be possible to call a proximity view by something like:
print views_embed_view('proximity_search', 45.67, 9.66);This is not possible to achieve using views filters.
I also need to make a proximity map based on the current user's location, but I guess this is possible using lat/lon args and a profile_load, once the views lat/lon argument options are in place.
#22
in number #19 I marked #208686: Views filters - Filter by typed address and Filter by proximity to user as a duplicate, but 208686 also implemented proximity to user viewing the node. Did that part get implemented here too?
#23
related to #362648: views distance filter by user location
#24
Subscribing
#25
marked #403138: proximity search based on views argument for lat/long for cck locations as a duplicate of this one. (it is kind of asking for a cck location implementation though)
#26
This was my workaround way to do a proximity search based on the current node's location. I used a block, but this could just as easily be used inside a node.
Basically, I setup a node view, with an exposed filter of Location: Distance / Proximity, and made sure this was working first. I used latitude / longitude for the Form Mode. Saved view.
In my module, I used hook_block to create a block that will embed this view using views_get_view. I loaded up the current node, and retrieved that node's latitude and longitude. Now, the beauty of this is that you can dynamically set your exposed filter values. Almost like using arguments.
I also removed the display of the exposed form since, I was using the node to inject params, and not the form.
<?php
/**
* Implementation of hook_block
*/
function d6dev_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
// Provide a view block for the location module
$blocks[0] = array(
'info' => t('Location distance proximity block'),
'weight' => 0,
'status' => 1,
'region' => 'sidebar_last',
);
return $blocks;
case 'view':
switch ($delta) {
case 0:
// We check to make sure this block is actually valid,
// Usually meaning it's only relevant on a node view
// That holds location information
if ($content = _d6dev_load_proximity()) {
$block = array(
'subject' => 'Locations within 100 Miles of this business',
'content' => _d6dev_load_proximity(),
);
} else {
return;
}
break;
}
return $block;
}
}
/**
* Inspect current node and pass lat / lng through location distance filter,
* to get nodes within a certain radius
*/
function _d6dev_load_proximity() {
// Retrieve current node object
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(arg(1));
} else {
return;
}
// We're on a node view, make sure we have location information
// for this node.
// If using just location module for nodes, locations should be in $node->locations
// Else, check cck_location fields
// Nodes can have more than one location, assume there's only one
if (!empty($node->locations)) {
$location = is_array($node->locations) ? $node->locations[0] : $node->locations;
} else {
return;
}
$view = views_get_view('business_listing');
$view->set_display('default');
$view->is_cacheable = FALSE;
// Fetch the distance filter (name of exposed Location proximity filter)
$item = $view->get_item('default', 'filter', 'distance');
// Apply dynamic elements to our exposed filter based on current node
$item['value'] = array(
'latitude' => $location['latitude'],
'longitude' => $location['longitude'],
'search_distance' => 1000,
'search_units' => 'mile',
);
$view->set_item('default', 'filter', 'distance', $item);
// This removes the exposed form from the display handler,
// because we want behind the scenes filtering
$view->display_handler->options['filters']['distance']['exposed'] = FALSE;
$output = $view->render();
return $output;
}
?>
If anyone has any suggestions or improvements, please comment
#27
Here is a node way of calling and setting this view by lat / lng, you would just have to set "distance" to whatever you named your exposed filter.
<?php
function get_location_proximity_view($view, $lat, $lng) {
$view = views_get_view($view);
$view->set_display('default');
$view->is_cacheable = FALSE;
// Fetch the distance filter (name of exposed Location proximity filter)
$item = $view->get_item('default', 'filter', 'distance');
// Apply dynamic elements to our exposed filter based on current node
$item['value'] = array(
'latitude' => $lat,
'longitude' => $lon,
// 'search_distance' => 1000,
// 'search_units' => 'mile',
);
$view->set_item('default', 'filter', 'distance', $item);
// This removes the exposed form from the display handler,
// because we want behind the scenes filtering
$view->display_handler->options['filters']['distance']['exposed'] = FALSE;
$output = $view->render();
return $output;
}
?>
Then call from your template:
<?phpprint get_location_proximity_view('proximity_search', 45.67, 9.66);
?>
#28
what filename did you put this code in? (for #26 and #27)
Also, tagging with the tag: location useful code
#29
I basically just used this in *my* site utility module, which in my case is modules/d6dev. Just a generic module to run site-specific module functions. I suppose you could use this in template.php as well
#30
The attached patch solves this in a manner that doesn't involve the need to create a separate wrapper block as in #26 and #27, but still is not the ideal solution which would be an argument type or perhaps a relationship (or both?).
Anyway, this patch adds a new setting in the proximity filter titled "Obtain origin from url". Check this, leaving lat/long empty but filling in distance. Then, when viewing a node, if that node has a location, then that location's lat/long will be used as the origin. I have a placeholder in there if anybody wants to make this work with users.
#31
Subscribing
#32
location.357295.patch from #30 works awesome! This is just what I needed!
Thank you jhedstrom!
Marked as reviewed and tested by the community (I hope that is the right thing to do).
#33
For those reading along, jbizzay's suggested workaround in #27 worked perfectly for me. Just one note: you don't need to expose the filter to use this, which means you don't need to hide it again either.
#34
Patch in #30 does not work for mepatching file location_views_handler_filter_proximity.inc
Hunk #1 FAILED at 130.
Hunk #2 FAILED at 188.
2 out of 2 hunks FAILED
#35
thanks jhedstrom, your patch worked perfectly for me!
#36
mswaringen, what exact date/version are you patching against?
#37
I was using dev, changing to rc1 allowed the patch to work with no problems.
It would be nice to pass the zipcode and the distance as arguments, anybody know how to do this?
#38
looks like a re-roll for dev might be needed.
#39
re #37, open a new issue for that, and link to that issue from here. :)
That way, it will make it easier to get this patch in, because the scope of change is smaller.
(I might be miss reading this issue history, but I think it is for getting lat/long to work via views arguments.)
Hmm and after re-reading things, it looks like #30 gets lat/long from the url, but uses "filters" in the views UI instead of arguments. Can anyone confirm that statement?
Looks like we could use a general "status of this patch" review here. What works, which patch, what still needs to be done.
#40
re #37, open a new issue for that, and link to that issue from here. :)
That way, it will make it easier to get this patch in, because the scope of change is smaller.
(I might be miss reading this issue history, but I think it is for getting lat/long to work via views arguments.)
Hmm and after re-reading things, it looks like #30 gets lat/long from the url, but uses "filters" in the views UI instead of arguments. Can anyone confirm that statement?
Looks like we could use a general "status of this patch" review here. What works, which patch, what still needs to be done.
Maybe what we need are two new issues that can link back to this one for related history.
1) get views arguments to work with location generally, The Right Way
2) add types of arguments (like lat, long, zip, city?)
and mark 2) postponed on 1)
#41
#30 is it possible to get this result (distance node to node) as result?
#42
sklausing,
Sure, add the field
"Location: Distance / Proximity"
and for the option select
"Use Distance / Proximity filter"
#43
thats what I tried, but I dont get a result. I patched location 3rc1 maybe this is the wrong one? Are there other things todo, i thought tht patch is enoug to get this information. It doesnt get lat/long from the node.
#44
Sklausing, did you try using info from comment #30?
Maybe describe node-to-node in more detail using an example.
#45
subscribing
#46
looks like we need a re-roll against the 6.x dev version for this.
#47
Subscribing
Any chance of getting the patch in #30 committed? http://drupal.org/node/357295#comment-1561280
Using content_profile and storing the user location with location_cck seems to be the future http://groups.drupal.org/node/23030#comment-80112
Is there another way to find the proximity to the user?
#48
If i understand correctly, the patch in #30 works against rc1, but doesn't work against dev. I rolled the patch against rc1, and followed the instructions, but my proximity views showed up empty. I'll give a $50 bounty to get this working against dev in a version that works on my site.
#49
+1 subscribe
#50
subscribing
#51
I would really like to see the ability to pass lat/lon as arguments. I'm willing to pay for this feature. Currently I'm using the location/proximity filter but I will be calling this view through the services module for display in an external application. Feel free to reply/contact me if interested.
Thanks!
#52
+1 subscribe
#53
As far as I have been able to determine, #30 only works if the filter is exposed. There's no sense in exposing a filter with zip codes or lat/long to the user for their ability to search by proximity, because for most places, 1. A user will not know the zip code, and 2. Coordinates are effectively useless as nobody will know coordinates to search from unless they have a GPS and/or are in the military.
The way to do it really would be rendering a form that accepts city and state, querying the "zipcodes" table by city and state, and returning the lat/long for use for searching. I've successfully done this, but I am having trouble getting it to work further.
After applying the patch in #30, the "obtain origin from url" option is avaliable, but it seems to only take it from the node/user page, which effectively renders it useless for searching nodes by location. So say, attempting to search for all nodes of x type within y miles of z location using views at this point doesen't seem possible with the fixes. Furthermore, you can't run multiple views of different content types in panels using this system, so I can't have one view of users that have a location matching specified lat/long, another one of all groups, another of all pages, etc, etc, and so on.
As I see it, I think the best way to handle this is by providing lat/long arguments, especially because it can be combined with taxonomy arguments. So you could have all nodes matching %term as a url, but putting lat/long as auxiliary arguments after %term could get you all nodes matching %term within x distance of lat/long. It would be impossible to overstate the usefulness of this feature.
In light of this, I am proposing a bounty:
I will pay $100.00 to someone who can successfully create stable lat/long arguments with distance filtration system in views.
The terms are as follows:
1. This functionality must be created in a way that can be committed into all future releases of location, so that the community can benefit from it's continued use. If a maintainer needs to approve, thats cool with me, but theres no use in building something that is only going to work for one release of location and not for others.
2. The arguments must be able to accept a lat/long from the URL and from from php code is fine with me, because I am deriving the lat/long from a function anyway.
3. There must be a method for the user to set the distance easily and quickly. I ideally plan on creating a form item allowing the user to select distance, and passing that value as code as an argument. So perhaps creating a third argument in addition to lat/long for distance would work.
4. Adding in zipcode argument in addition to lat/long wouldn't hurt.
Note: This bounty is void if the maintainers have been planning this functionality for a while and just happen to finish it 2 min after I post this note! (You know what I mean!). ; ). If that is the case I'll be tossing said maintainers some $ for their efforts.
Otherwise, I will be talking to other users who offered bounties for this service, as I am the latest too. I will see if they are still in the running for the bounty, and thus this would be combined. I'll ask nickbn if he'll match my $100 to make the total bounty to $200.
Please reply in this queue instead of to me directly as this functionality needs to be extended to the community as per stipulation #1.
EDIT: Unfortunately this bounty has been cancelled as of Aug 15, as I am putting a private developer on the job. If I can get it done in the sense that it will work on all installations I'll release it to the community, but it would likely be tailored to my installations.
#54
I agree that getting this to work without exposed filters is ideal.
In terms of the requirements of #53, if it's really going to be useful to the module in the long term then point 2 should probably involve using views argument interface to easily match up with current node or something like that.
#55
This geo location arguments mod would be very useful indeed. I have been trying to figure out how to do this for the last couple of hours and have come to realise that currently it isn't possible. Subscribed.
#56
subscribe... this would be great
#57
Yeah, I just spent an evening coming to that conclusion too.
Subscribe.
#58
subscribing. I agree, this functionality would be great.
#59
Update:
As earlier noted, I hired a developer to make this functionality happen, however, instead of using views arguments, we essentially hacked the lat/long/distance fields in the proximity filter to accept php code (and module-defined functions!). At first, this might not seem like much, but because of it's ability to execute module defined functions and access values from $_POST or $_GET, you can make simple HTML forms and use a views page as the form action to show results. The forms API on drupal could do the same thing probably, but it's significantly more complex than HTML forms for simple city/state searches. NOTE: Of course, this takes into account that the form values run through check_plain() or some other type of code stripper so some jerkface isn't injecting pure SQL into the forms and ruining your day!
The thing is, I'm not sure what maintainers think about committing a patch if I write one. To me, a few html snippets in a module allows me to get great search by location and nodes nearby by writing some fairly simple functions, and solves my purposes. This isn't going to fix everyone's problems, but it will definitely be a good 'holdover' in the mean time. But I'm probably not going to write a patch if there's no interest among the community, and if someone's in need I'll just attach the modified .inc file. If maintainers could let me know what they'd like to do, I'll make it happen.
Thanks!
#60
#61
I agree that it would indeed be better to have this work correctly (as an argument), but for the record, the solution posted in #27 worked well for me. There is a typo in the naming of the longitude variable. It's named 'lon' in one place and 'lng' in the other. Otherwise, this works well. I used this to pull a location name from the url, geocode it, and use the coordinates as the filter for the view.
#62
+1 subscribe
#63
Arguments are still essential to provide values from a form, so you can geocode a lat/long. I hacked the views proximity filter, but until views arguments are provided all solutions are going to be inferior hackjobs for the majority of users running production enviornments.
#64
subscribe
#65
This might be a solution
http://drupal.org/node/606342#comment-2160156
#66
@activelyOUT: Awesome Find! I have yet to test this, but if this works properly...whats the process involved in getting this committed?