Community Documentation

Howto: Zip/postal code proximity search using views and location

Last updated August 1, 2011. Created by glass.dimly on January 15, 2009.
Edited by pfrenssen, peggysmouse, rooby, kiamlaluno. Log in to edit this page.

Note: There is currently a bug in Location module that causes searches for large distances to not include results past a certain distance. This distance changes depending on the latitude of the origin point. You can find an estimate of these distances here. Be warned and test within those distances.

This is a tutorial on how to use the Location module to create a view to search by zip code proximity in Drupal 6.
The example is simple so that it can be easily reproduced with these minimal module requirements:

  • Drupal
  • Views
  • Location

Note: It requires at least location version 6.x-3.1 as the proximity views functionality was overhauled for that release.

This view will ultimately accept a user in-putted zip code and distance and return a listing of content within that distance of the zip code, sorted by distance from that zip code.

First, you must install the Location and Views modules and configure Location fields for whatever content type you desire.

Note: This example uses node locations, not CCK location fields (ie. using the Node Locations module instead of the Location CCK module).

The gmap module is also a good addition because it allows the view to be displayed as location markers on a map instead of as a text-based list.
This tutorial will not cover use of the gmap module.

Next, import the zip codes from the country of your choice as per the location module installation guide (you can also find information in this in the INSTALL.TXT file found in the location module).
Note: Proximity searches by post code will not work without this step because those database files contain the latitude/longitude values of the post codes.

Steps to create the view (this assumes basic views knowledge):

  1. Create new view of type Node (you can also use other types if they better suit your requirements).
  2. Select Fields for the Row style setting (you can use any row style that suits your requirements).
  3. Add any Fields you want for you view (this example uses the Node: Title and Location: Address fields).
  4. Add any non-proximity Filters that you want for your view (this example uses Node: Type = 'page' and Node: Published = Yes.
  5. Add the Location: Distance / Proximity filter, expose it and give it the following settings (see attached files for a screenshot of these settings):
    • Operator: Choose what type of proximity search you want. This example uses Proximity (Circular)
    • Origin: Postal Code (assume default country). You could also use Postal Code / Country if you want the user to also select the country.
    • Postal code: You can leave this blank or provide a post code, which will be used as the default value. In this example it is left blank.
    • Distance: You can leave this blank or provide a post code, which will be used as the default value. Also select whether you want to use miles or kilometres for the distance. This example uses 100 miles.
    • Unlock operator: Unchecked in this example but can be checked if you require.
    • Optional: Checked in this example but can be check if you require.
    • Remember: Unchecked in this example but can be checked if you require.
    • Filter identifier: distance in this example but can be anything you require.
    • Label: Proximity in this example but can be anything you require.
    • Allow choice of user location: Unchecked. This option has no affect on the post code related Origins.
  6. Add the Location: Distance / Proximity sort and give it the following settings:
    • Origin: Use Distance / Proximity filter (this links the sort criteria to the filter that collected the user's entered zip code).
    • Sort order: Ascending

(see attached files for a screenshot of the whole view's settings.)

I have also attached a text file containing an export of my example view to use as a starting point if you desire.

AttachmentSize
location_pc_prox_view_filter.png66.51 KB
location_pc_prox_view_whole.png84.72 KB
location_pc_prox_view_export.txt3.42 KB

Comments

I am afraid this solution is

I am afraid this solution is not working at the moment. The postcode is not geocoded on user input, so location can not calculate the distance between the search position and the targets.

The query will be

SELECT location.lid AS lid,
   'Unknown' AS location_distance_1,
   node.title AS node_title,
   node.nid AS node_nid
FROM location location
LEFT JOIN location_instance location_instance ON location.lid = location_instance.lid
LEFT JOIN node node ON location_instance.vid = node.vid
WHERE 0

Relevant issues:
- #357295: Proximity Search based on lat/lon, using views arguments
- #321114: Fixing exposed filters in Views for UK and US postal code proximity search (not cck location)
- #662892: (1=0) in query and Reworking of proximity filter handler to automatically geocode zipcodes

Followed the tut and patched

Followed the tut and patched the geocoding problem where it only shows when you search a 0mile proximity. It's all running great, i've even attached a second view to show the results in nice field display underneath, but i still have a problem

The info window that pops up when you click a marker contains the labels for the fields i'm displaying, but doesn't have the actual values, i.e. they all say

Name:
Roles:
Distance / Proximity:

regardless of the values of said fields for the user that marker represents. I need the values to show as the field settings are. i.e. re-written like they are in the fields display, and linked like they're meant to be 'Name' to the user page.

`

tom-knox i''m having the

tom-knox i''m having the same issue, the map only shows the record if i search for 0 proximity, also empty fields at the marker.
How did you fixed the first issue?

This tutoral's configuration

This tutoral's configuration works with the latest dev version of gmap, and displays the nodes' fields in your view. I followed this tut step by step, too.

I am always leery of using dev versions of anything- but this particular release is OK- as far as I know....

I only want to search for

I only want to search for nodes based on the zip code that has been entered into it. I don't want users to see these nodes on a google map I want them to see results based from there entered zip code to the node's zip code in miles distance.

I only want to search for

I only want to search for nodes based on the zip code that has been entered into it. I don't want users to see these nodes on a google map I want them to see results based from there entered zip code to the node's zip code in miles distance.

my mistake I didn't mean to

my mistake I didn't mean to post my comment here

Possible with Arguments yet?

Use case: I'm looking at one node with a Location. I want to see other nearby nodes.

As far as I can tell this is not yet possible. I see both a sort order and a filter based on proximity, but no arguments yet. What's the best way to re-run my query and reset my map's center based on the location of another node?

*edit* Howto: zoom center etc based on a views argument and use proximity filter from an argument may also be helpful to others.

Don't forget to import the zip codes!

Works fine for me... now I've imported the zip codes table.

Using dev location & gmap.

I did the same thing but it's

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?

Hi, Could you export the view

Hi,
Could you export the view here please?
And isn't the problem solved using: http://drupal.org/node/343487#comment-3128786

greetings, Martijn

Huh?

You can simply open the file of your choice with a text editor, copy all, and paste into a PHPmyAmin SQL execute window.

Simply doing the above gives an error.
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use

I suspect one must do something more than "simply paste". Would anyone care to enlighten me?

Rather than copy and paste

Rather than copy and paste the whole list, just do a small sample first to see if it works. I ran into a little trouble, too, with copy and pasting the entire directory--

turned out that one of the entries wasn't properly closed with a semicolon, giving me the same error you received.

Make sure every entry--especially the last one is-- is closed. That is mist likely th
e cause of your syntax error.

The last row requires a semi-colon for for SQL

To use the SQL insert code, you need to either copy and past the entire list and run the query [usually will lag out and crash because of too many entries but worth a shot] or you can copy and past the insert code and break up the rest of the list into 3k-5k rows.

As another poster stated, you have to have a "," at the end of all the rows with a ":" at the end of the last one or you will get an error and no entries will be placed.

Dave

I realize this is an older thread...

But, was recently working on a project requiring this configuration. If you're using phpmyadmin via godaddy, you may receive a bunch of different error messages with copy/paste and sql/csv imports. I found that executing sql queries allows you to build the tables - but it's a L-O-N-G process as the queries need to be (in my experience) 60 or fewer rows.

The query language is in the zipcodes.##.mysql file (## = country abreviation)

Steps:
1. open the file in the locations module /modules/location/database
2. copy all to text editor (wordpad is easiest as it delineates row data)
3. log into your database
4. from the homescreen, select 'SQL'
5. in the query window type/paste: INSERT INTO zipcodes (zip, city, state, latitude, longitude, timezone, dst, country) VALUES
6. paste from wordpad row data in the format
('01002', 'Amherst', 'MA', '42.377651', '-72.503230', -5, 1, 'us'),
('01003', 'Amherst', 'MA', '42.369562', '-72.635990', -5, 1, 'us'),
('01004', 'Amherst', 'MA', '42.384494', '-72.513183', -5, 1, 'us');
7. note semicolon at the end of the query - do not omit this!

Hope this helps... more helpful advice: avoid godaddy like the plague.

confuses about cck locations

In your tutorial you write:

"Note:The actual Location fields I am using are not CCK Location fields, but are Node Location fields, that is, Locations attached to the nodes themselves (which one adds to the nodes via CCK) rather than locations attached to a CCK field on that node. Some of the confusions below may have arisen from this difference."

I'm confused about the difference. I have a node (contentprofile) on wich i added the CCK field location. Is this the right way to attach a location to a node? Finally i want to show a proximity map based on a exposed postal code. Thanks for your help.

BleuBiRTH

Using GMap and centering on Zip Entered

This was a great instructional. Really appreciate it.

I got this working, and am using the gmap module for displaying. However, it always centers on the Default Center Location that is set in the GMap settings. Do you know of a way to make the map center on the zipcode that is entered?

Thanks in advance - rh

Check this

Check this http://drupal.org/node/417142#comment-1545136
For me option 2 worked very well!

[RESOLVED] with Check this

I enabled option 2 and now it works!
THANKS!

The tut dont work for me. It

The tut dont work for me.

It give so many Issues and tips/tuts but nothing works correct.

I sit here - 5 hours but nothing run!

I finally got zip code proximity search working...

At first I couldn't figure out why I wasn't getting any results for my proximity search, and tried several different settings in Views to get it working. Turns out there was no latitude/longitude information for my nodes in the "location" db table - they were both set to 0.0000! In other words, my nodes were getting geocoded when I created them. Here's how I got it working:

I entered a Google Maps API Key for my country (US) on Site Configuration > Location > Geocoding Options, checked the "Use a Google Map to set latitude and longitude" option on Site Configuration > Location > Main Settings, then created a new node with location data. After verifying that the lat/long were set in the "location" table, I checked my view again - now it worked great!

compare the long / lat in location v zipcode table

Based on your comment I checked the location table and zipcode table.

Turns out the google map was picking up the wrong location, a place in Europe, while the zip was for New Hampshire, so the long/lat coordinates did not match. Added a street address to the node and it worked.

I would still prefer to not have to import the mysql database, if there are proximity filters which avoid it, anyone please advise.

EDIT Openlayers does not require a zip code table, and got it to work. Proximity alerts is not working for me yet however in Openlayers.

My experience

Thanks very much for the tutorial. Really useful.

I fell into all the traps
1) Not having co-ordinates set for nodes
2) not importing postcode database
3) needing to update to lates dev version

But having following tut to the letter, the only way I could get anything to return was to put 0 in the distance field (as noted above). I didn't apply any of the patches mentioned in location issues but solved the problem by reading this: http://drupal.org/node/739694 and adding the function listed.

Now everything works perfectly.

Thanks again,
Crom

Is there a how-to for

Is there a how-to for searching Locations based on just country +/ province ?
Panels keeps flipping out on exposed filters; and I cannot get this to work.

Join a legion of Nerds in the Minneapolis Area: http://nerdery.com/

Unknown column 'location.vid'

Just in case anyone runs into this error when adding an exposed filter of for example taxonomy, to the list of filters, this link helped me out: http://drupal.org/node/571066

It comes down to choosing the view type as "node" rather than "location", as you need the view to be using the node table as a base table.

Maybe someone smarter than me can figure out if this has any other implications but it had me stumped for a while and I am sure that adding a taxonomy filter to the search block is pretty common for say business listing sites etc.

How to return nothing until submitted?

I have the opposite problem, it seems, than others. I am getting everything returned and shown UNTIL I input a zip code and submit. Is there a way to show nothing until the submit button is pressed?

Drupal 6.19
Location 6.x-3.x-dev
Gmap 6.x-1.x-dev
Views 6.x-2.11

I am actually having the same

I am actually having the same problem. did you ever fix this?

I did

However, it was so long ago, I can't remember which steps I took to fix. I can send you the View that I used if you want.

Same..

Word. I've got everything working, am narrowed down to the issue described above. Subscribing. :]

I've followed this tutorial

I've followed this tutorial exactly: and successfully!
Thank you for taking the time to document this, very useful. I would have never worked it out, some of the required Distance/Proximity settings aren't exactly intuitive...

Creating a simple and neat Postcode search field and button

After following this, and using Exposed Form in Block module for Views to generate a 'Search Block' I was left a little annoyed that proximity still wanted to find 1) the radius & 2)units. It made the block a little unwieldy and not user friendly.

It was very simple to then create my own block with the following code, to create a simply 'Enter Postcode' and 'Search' button to do everything and make the user experience better. The only real trick is using hidden fields to pass the variable through:

<form accept-charset="UTF-8" action="/dealerlocatorpostcode" id="views-exposed-form-dealerlocatorblock-block-1" method="get">
<label for="edit-distance-postal-code">Enter your Postcode: </label> <input class="form-text" id="edit-distance-postal-code" maxlength="4" name="distance[postal_code]" size="4" type="text" value="" /> <input name="distance[search_distance]" type="hidden" value="50" /> <input name="distance[search_units]" type="hidden" value="km" /> <input class="form-submit" id="edit-submit-dealerlocatorblock" type="submit" value="Search" />&nbsp;</form>

Note the "distance[search_distance]" value is set to 50 (km). I also set the 'search_units' to km. The views name is 'dealerlocatorpostcode'. I also generated a block but didn't activate it.

Hope this helps someone...

Filter by Date

Hi - I'm using the Zip Code Locator Module and it really works great. My nodes have a date cck field and I need to filter by that date field, but it's not available for the location view. Any thoughts?

Here's the site: www.choralexpress.com. It's a site where choirs can post their concerts with date/time and location. What I'm trying to do is filter down the zip code search results to only show concerts that are greater than or equal to 'now' in a date filter.

Thank you for this great module!

Tom

Are you using the Date

Are you using the Date module? It has a Views filter for this. You might also have luck by adding a Relationship

—Matt

Great tutorial - thank

Great tutorial - thank you.

Could someone provide some guidance in making the following change to my installation:

I'm trying to change then field label of the exposed "postal code" filter to make it "zip code" as I will only be operating within the US.

Could someone tell me the file that would needed to be changed as well as how I would go about making such a change.

Thank you in advance

Rather than hack the core or

Rather than hack the core or the module, it might be better to use the String Override module - which can be configured to replace the word 'Postal Code' with 'Zip Code'. Hopefully it will work in this situation.

or use jquery replace() method

to find the label and change the HTML. just put the jquery in a FULL HTML or better yet an unfiltered block and set visibility for that page.

there is probably a more efficient way to do this with jQuery but this at least works

<script>
$("label[for='edit-distance-postal-code']").each(function() {
    var text = $(this).text();
    text = text.replace("Postal code:", "Your ZIP Code:");
    $(this).text(text);
});
</script>

CiviCRM specialist

wonderful tutorial

If only more people could be a clear as you are. And SCREENSHOTS? Wow, bonus. thx

CiviCRM specialist

Can't Get It!

I can't seem to get it working. I have business listings as a content type with the Location fields in them and it will not bring anything up when I search. I even tried the export text file you have. I have the US zips in my database and everything. Not sure what's gone wrong?

Permissions?

Check permissions to make sure they're set correctly.

If you still need help, let me know!

Awesome! Subscribing.

Awesome! Subscribing.

subscribing

subscribing

Almost there --

I'm almost up & running, but having the proximity issue described in the first few posts where it won't display results more than zero miles away. I tried to patch it, but to no avail. Is anybody else still having this issue? Also, nodes with no locative information are being displayed with the results.

+1 subscribing..

+1 subscribing..

Internet Explorer issues

Custom view has been working correctly for several months but in the last week no longer works in Internet Explorer 6-9. Works correctly in Chrome, FF, Safari and Android but not IE.

http://burgerpocketpress.com/view-stores-zip

IE produces this long string now after form is submitted:

http://burgerpocketpress.com/view-stores-zip?distance%5Bpostal_code%5D=&...

Any thoughts would be great...this has me really stumped.

Open this view in a colorbox/lightbox?

I think my zip code search is all gravy as of right now. 1 MILLION points if anybody knows how to open this view in a colorbox.

UK Postcodes?

Will this work with UK postcodes as well, or just US zipcodes?

Page status

No known problems

Log in to edit this page

About this page

Drupal version
Drupal 6.x
Audience
Developers and coders, Site administrators, Themers
Drupal’s online documentation is © 2000-2012 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.