Placing Users on a Map in Drupal 7 - with Openlayers, Addressfield and Geocoding

Mapping on Drupal 7 is still in flux but a lot can be achieved already. I really like Openlayers so I wanted to find a solution that revolved around that. It took a bit of fiddling around but in the end I have a working recipe, which I thought I'd share to help others looking for something similar. The specific problem I needed to solve is how to allow users to enter their address information, geocode and place that on a map using Openlayers.

Here is what I was trying to achieve:

Allow users to sign up, fill in their profile with various bits of information including address info - geocode that to get a longitude and latitude and place a markers on a map to show where users are in relation to each other.

You will need:

Addressfield - the state of the art in Drupal when it comes to getting address information. This module was developed to fullfil the needs of Drupal Commerce and it gets the right things right, including planned RDFa support.

Openlayers - Handles... layers - very flexible, exportable and allows you to use different tile providers. With power comes a complicated interface but it is worth the trouble!

Geofield - Geofield is a very good approach to the problem of how to get location information into Drupal and then pipe it into whatever mapping or other solution you need. You need Geofield because Openlayers does not offer a field to input data for Drupal 7. They have, rightly according to me, taken the decision to focus on what their main goal is (do maps) and leave things such as data entry fields to other modules.

Geocode - Geocode does the job of turning data into longitude and latitude and it will allow us to link up Addressfield with Geofield. (yes it is on github - yes it would be nice to have it on Drupal.org - check this issue if you want the details of why its not there yet). I am linking to my fork of Geocode because it includes a couple of fixes - in particular a fix to properly handle address data coming from a field attached to a Profile using Profile2.

Profile2 - A great module that allows us to attach different bundles of fields to user profiles and do various nice things like include them on the registration form or make them private. Lots of Drupal Entity goodness if that is your thing (we like entities).

You will also need the GeoPHP library, which does all the heavy lifting calculations.

Steps:

1. Install and activate everything and place the GeoPHP library in a libraries folder inside sites/all. Obviously, also install any modules that are dependencies to the ones above.

2. Go to admin/structure/profiles/manage and add an Addressfield field to the Profile field.

3. Also add a Geofield field and set the widget as "Geocode from another field". In the settings form for the field choose the Address field you defined above. Choose Google as the Geocoder for now.

4. Go to Openlayers API settings "openlayers/layers/settings" and set the Google API key or choose version 3.2 of the Google API which does not need a key.

At this point you can test that at least geocoding is working. Make sure to set the display settings for the Geofield to something like latitude and longitude so that you can see it producing results and then go edit your profile and add an address (you are not going to see a geocode data entry field, just the address field. Geocode is hidden as it will automatically be populated from the results of the geocoding). Once you save you should see a longitude and latitude popping up.

Ok so now we have data - the rest is easy.

5. Create a view that collects all the location data. We want to Show Profiles of Type Main (or whatever name you gave your profile type). We are not interested in a Page or a Block. Just hit save and then add an OpenLayers Data Overlay display type.

6. Add the relevant Geofield to the view and the formatter can be WKT.

7. Under the Display Format make sure to choose Openlayers Data Overlay and in settings make the data source WKT and the WKT Field the Geofield.

At this point you are aggregating location data in an Openlayers friendly format and the preview of your view should show that information (printed out in code style). Now we need to actually place this Data Overlay on a map.

8. Add another display to your view and set the format to OpenLayers Map. Save everything (we are not done yet though).

9. Go to admin/structure/openlayers/maps and add a new map. Give it a name and everything else Openlayers needs and save to move on to the configuration of the map.

10. The part we are interested is the Layers & Styles section of the map settings. You should find the Data Overlay view as an option at the bottom of that section. Enable and Activate. You are telling Openlayers to add that layer to that map.

11. Finally go back to the view - go to the Openlayers Map display and in Settings for the Format choose the map you just created.

Phew! Done. You can now collect addresses via the Addressfield, turn that data into a longitude and latitude using Geocode and Geofield and create an Openlayers Data Overlay of that data that you can place on an Openlayers map.

Comments

hi Ronald,
very nice and easy to learn article.
I use exactly the same solution successfully for nodes (entities). but I get two issues:
- where do I can choose version 3.2 of Google API? I can see "Google API Key" field only "admin/build/openlayers/layers/settings" (OpenLayers 7.x-2.0-alpha1)
- when I add new node content, I have to re-save it (add new - save it - open it for edit - save it again) to get Geofield data (Long. and Lat.) - what do you think about it?
thank you

@rob: In order to user version 3.2 of Google API, install OpenLayers 7.x-2.x-dev and there is a dropdown in Layers, Api Keys Tab If you use Google Maps v3, an API key is not necessary.

@Ronald
This is the best cocktail of modules that really unleash the power of Drupal 7. My sincere congrats!
I have a quick question: For the first view, there is no Openlayers Data Overlay option in Display Format . How can I enable it?
Thanks a lot!
Claudiu

I've done the update to Drupal 7.2, followed the tutorial and tried with most recent and also with dev modules and aren't having any luck. As of June 2011, does this tutorial - specifically the modules referenced - result in functioning geocoding?

Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of [runtime function name](). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file in C:\testserver\htdocs\WPF_lopendvuurtje\Drupal7\sites\all\modules\geocode\geocode.module on line 230

Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of [runtime function name](). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file in C:\testserver\htdocs\WPF_lopendvuurtje\Drupal7\sites\all\modules\geocode\geocode.module on line 237

@Jory @istos : You should try my own fork of Geocode here, which solve this problem by suppressing 2 '&' caracters in geocode.module. I applied for a pull request into istos' repository as I don't intend to maintain the module, just contributing !

Submitted by Robert Munoz (not verified) on Tuesday, 13th of March - 2012

I'm confused on several steps starting with the last part of step 5. So I'll start with step 5 question. Last sentence in step 5 you say "then add an OpenLayers Data Overlay display type." When you are on the Views Master Details page do you mean Format should be OpenLayers Map or Geo Field Map?

Submitted by Matthew Slater (not verified) on Friday, 6th of July - 2012

Thanks for this - 18 months after the release of D7 I can't believe there isn't more info on this. I have a problem the geofield isn't responding when the entity is saved - the geocode() API function isn't being called, and I can't see where it would be called from. I would have expected a geocode_entity_presave() hook in geocode.module. So I'm stuck! http://drupal.org/user/140053

Submitted by No Overlay Map ... (not verified) on Wednesday, 12th of December - 2012

I don't have the Overlay Map display format for the view. Do you know where I can enable it? Otherwise, its an excellent tutorial, although hard to follow for some less experienced Drupal users (a video tutorial would be awesome).

Submitted by Mikael S (not verified) on Thursday, 13th of December - 2012

Hi,

I was looking at the wrong place at first, I was looking at Format where I could set Openlayers, unformatted etc.
Then I realized it was the DISPLAY at the top (add button besides "Master) where I was supposed to add the Overlay Map display.