Implementing location proximity search (for Belgium) with Drupal and Google Maps

tags:

This tutorial will show you how create a Google Map with location pinpoints in Drupal 6, and how to let your users filter the map based on postalcode.

This walkthrough was written to create a map for Belgium, as I encountered some gotchas while doing so. However most of it will apply to other countries as well, and you might even skip some steps that are only required for the Belgium use case.

Imagine you would want to create a Google Map showing all shops in Belgium, and let your users enter their postal code and a distance range (in kilometers or miles) to filter the results to. This would allow a user to search for shops nearby his location. As you can see in the screenshot below our map shows only shops that are within a 20 kilometer range of Brussels.

To build this functionality you will need to download and install the following modules:

Some of these packages come with multiple modules, so these are the ones you'll need to enable: Location, GMap, GMap Location, Views and Views UI.

1Step 1: First, we will configure the GMap module. Go to admin/settings/gmap to do so.
Here you can configure how you want your Google Map to look and behave. Make sure to enter your Google API key. You might also want to check the autozoom option in the "Map behaviour flags" fieldset. Most of the other settings can be left at their default value for now.

2Step 2: Next we will configure the Location module settings at admin/settings/location.
You can adjust the settings so they match the following:

You can leave the other tabs of the Location settings pages untouched.

3Step 3: Now we have to assign location based data to a content type. You can either use an already existing content type, or create a new one specifically for this purpose. I created a content type "Shop", so we can create a node for each shop we want to show on the map.
To configure our content type to collection location data, go to the content type edit page (at admin/content/node-type/shop) and find the fieldset "Locative information".
Configure the first two included fieldsets as shown in the screenshots below:

We configure our content type to have one location assigned with it.
Next, we will define which location fields a user adding a shop node will be allowed or forced to enter. In my case I made the basic address fields required to make sure to have a complete address.

You can configure the other location settings as you wish, or leave them as they are. Now save your content type and go ahead and create some shop nodes. You will have the ability to enter location data on the node submission form.

4Step 4: Now we're going to make the Location module aware of the Belgian zipcodes and their latitude - longitude coordinates. The Location module already comes with this data, so all we need to do is import the file sites/all/modules/location/database/zipcodes.be.mysql into our database (e.g. use PHPMyAdmin to import this file).

Important: at the moment of writing there is still an issue with this file: latitude and longitude values are switched. You will need to run the following SQL query to fix this:

UPDATE zipcodes SET latitude =(@temp:=latitude), latitude = longitude, longitude = @temp

More information on this issue: http://drupal.org/node/566792

5Step 5: Now we will create a View which will show our shops on the map. I assume you have at least some basic knowledge on how to create and configure a View.

First of all, create a new View, and make sure to create a Page display. Also assign a path to this page, so your users can browse to the map.

A. Add fields

Add at least the following fields to your View, and make sure to exclude them from display (unless you have a reason to show this information in the Gmap marker):

  • Location: Distance / Proximity
    configuration options:
    Exclude from display: checked
    Units: Kilometers
    Origin: Use Distance / Proximity Filter
  • Location: Latitude
    configuration options:
    Label: Latitude
    Exclude from display: checked
    Display style: Decimal degrees
  • Location: Longitude
    configuration options:
    Label: Longitude
    Exclude from display: checked
    Display style: Decimal degrees
  • Any optional fields
    Any optional fields you add and don't exclude from display will show in the marker.
    I suggest adding at least "Node: Title".

B. Save the view

It is probably necessary to save the View now, so the Latitude and Longitude labels are stored, as we need them in the following step.

C. Basic settings

Configure the basic settings in your View as follows:

  • Style: GMap
    • configuration: Data source = Choose latitude and longitude fields
    • Latitude field: select "Latitude" from list
    • Longitude field: select "Longitude" from list
      Note: if the select list shows only blank items, you didn't set a label for the latitude / longitude fields! See A. Add fields.
  • Row style: fields
  • Use pager: No
  • Items to display: 0

D. Add filters

Add at least the following filters:

  • Node: Published = yes
  • Node: Type = [your content type] (e.g. Shop)
  • Location: Distance / Proximity
    • Expose this filter
    • Operator = Proximity (Circular)
    • Form mode = Postal code (assume default country)
    • Optional = checked

E. Save the save (again)

This should give you a basic working map, with proximity search exposted filters. You can come back and tweak your view some more to fit your specific needs.

For an alternate resource on creating this View, check out http://drupal.org/node/359463

6Step 6: This is the point where things are getting a bit dirty, as we're going to have to make changes to a file in the Location module. This is not considered good practice, so you should make sure you document this step properly or create a patch file, so you can reproduce this step if you should update your copy of the Location module.

Browse to sites/[all]/modules/location/supported/location.be.inc and add the function location_latlon_rough_be to this file, as described in this comment (step 2/): http://drupal.org/node/326749#comment-1235822

Finished!

After following the steps above, you should now have a map showing your shops at the URL path you specified in the View we created, with the ability to search for pinpoints in the area near a given postalcode.

If you have suggestions or questions about this tutorial, feel free to add a comment below.

Submitted by Sven on Wed, 28/10/2009 - 21:37 10 comments

Dutch postcode database

First of all i would like to say that this is a very clear tutorial. I'm trying to make something simular for a Dutch site. I'm running into some problems tough.

First of all the Dutch postcode db wasn't freely available. You can buy it at <a href="http://www.postcode.nl" title="www.postcode.nl">www.postcode.nl</a> for an insaine amount of money.

So i googled some more and found this site: <a href="http://kvdb.net/projects/6ppdev/" title="http://kvdb.net/projects/6ppdev/">http://kvdb.net/projects/6ppdev/</a>

It's a project where ppl make their own database.

My question: would it be possible to convert it so i can be used in Drupal?

Thanks in advance :)

grtz Remco

Hi Remco, I'm not sure

Hi Remco,

I'm not sure whether this will be possible, since Dutch postal codes are a bit particular with the 2 letter extension. But looking at the CSV/XLS file fields, I guess you could get them into the DB structure the Location module needs (zipcode, name, lat, long & country).

I noticed there is some work being done in the Location issue queue to get this working. You might want to give the attached patch(es) there a try:
http://drupal.org/node/73714

Thanks Sven :)

Fist of all.. thank you for your respond.

I managed to convert the db i found with a small python i made. All is in the drupal db now tough i cannot seem to get the search function to work. I guess it still needs some more work. Let's see where things go wrong :)

Cant get it working

Hey Sven,

I tried it over and over for a couple of times now but for some reason i cannot get it working.

I'm using:

Location: 6.x-3.1-rc1
GMap: 6.x-1.x-dev
Views: 6.x-2.7

This is how my settings are:

<a href="http://img8.imageshack.us/img8/3980/locator1.jpg" title="http://img8.imageshack.us/img8/3980/locator1.jpg">http://img8.imageshack.us/img8/3980/locator1.jpg</a>

The next picture shows the preview output:

<a href="http://img195.imageshack.us/img195/9749/locator2.jpg" title="http://img195.imageshack.us/img195/9749/locator2.jpg">http://img195.imageshack.us/img195/9749/locator2.jpg</a>

What wonders me is this line:

'Unknown' AS location_distance_0,

Im not sure if that is correct.

The last picture i will send you shows the output that i'll see on my page:

<a href="http://img195.imageshack.us/img195/8990/locator3.jpg" title="http://img195.imageshack.us/img195/8990/locator3.jpg">http://img195.imageshack.us/img195/8990/locator3.jpg</a>

I hope you can help me sinds this is turning my head up-side-down :P

Thanks in advance

Grtz Remco

Got it working :) Seemed it

Got it working :) Seemed it was an error on my side. Great tutorial and thanks for the info :)

Just one last question. Would

Just one last question. Would it be possible that the filtered locations are being displayed right under the map?

I guess you could create an

I guess you could create an attachment display for that, that inherits the exposed filter values. That should work if I recall correctly.

How did you get this working?

How did you get this working? I'm getting exactly the same problem as you (i.e. no map or results being shown, if I remove the Location: Distance / Proximity filter I do get a map with all locations pinned).

Not sure what version of Views you are using on this tutorial (mine is 6.x-3.1-rc1), but when I go to the options of the Location: Distance / Proximity filter, underneath 'Form mode' it says FIXME, which leaves with no confidence this will actually work.
Might try a few other versions of Location.

Question for anyone... how do

Question for anyone... how do you make it so the map shows before you enter a zipcode? Currently I need to enter a zipcode and then the map shows.

Also, it would be helpful if you included what versions of modules this tutorial is for. I followed this to a 't' but the map would not show after entering a zipcode. I'm using Dupal 6.15, Location 6.x-3.0, GMap 6.x-1.0 and Views 6.x-2.8. I found that for this to work properly, the Data Source of Style: GMap needed to be "Location.module" vs. "Fields Latitude and Longitude".

In any event, thanks for this post... very helpful.

Have you put your "Location:

Have you put your "Location: Distance / Proximity" filter as optional (i.e. check the "Optional" checkbox in the filter configuration form)?

I have updated the post with the exact versions of the mentioned modules I used to build this.

Hope that helps

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

More information about formatting options

  • Search

  • On the web

      • Sven Decabooter on Twitter
      • Sven Decabooter on LinkedIn
      • Sven Decabooter on Facebook
      • Sven Decabooter on Delicious
      • Sven Decabooter on LastFM
      • Sven Decabooter on FriendFeed
  • Drupal

    • Individual member of Drupal Association

      View Sven Decabooter's profile on drupal.org