You would think by now that maps would be all sorted out in Drupal 7, you would be wrong. Maps in Drupal, or anywhere, have never really been sorted out. Maps are a complicated tangle of moving parts. Starting a new project that needs maps can be a challenge. Fortunately, there is a solution with OpenLayers.
On one of our latest projects we where expecting to use Gmap (a Drupal 6 favourite). However, with no Drupal 7 release available (beta-1 was made available in November 2012) and the Views and Solr integrations in a state of disarray we had to try out something different.
Enter OpenLayers. As expected with maps, what sounds like the small task of showing some nodes on a map with a couple of filters turned into the following stack of modules and dependencies:
- Address Field to hold address data in our content.
- Geofield to hold geographic data in our content, in this case a point.
- Geocoder converts the address data into geographic data.
- geoPHP a geocoder dependancy.
With the addition of the ever present dependancies:
The first step was to install and enable the above modules, being sure to also install the modules included with OpenLayers:
- OpenLayers UI (openlayers_ui)
- OpenLayers Views (openlayers_views)
Next we setup the content, adding the following fields:
- Address: Postal Address, Dynamic Address Form
- Location: Geofield, Geocode from another field
The Address field allows a content editor to provide the street address of water recycling projects. The Location field stores the map location, it is populated automatically by geocoding the Address field:
The Water Sources and Water Uses fields are taxonomy term references that are used to filter the water recycling project nodes that are included on the maps.
Creating a map
Openlayers lets you do all sorts of things, I will not go into too much detail, but the key points are:
- You need a base layer - this is the map, we picked Google Maps Normal.
- You need overlay layer(s) - this is the content, we set this up later with views.
We start by altering the OpenLayer's settings:
We alter the suggested OpenLayers library to version 2.12:
This removes a Google Copyright message. However in the administration pages you are going to see the "Not suggested compatible version" warning on every page. If you miss this step you will see the following on your Google Map, another option is to pick another base layer such as OpenStreetMap:
Now to create the map, click the Maps tab then Add. On the Basic horizontal tab, you need to provide the Map Machine Name, Title and Description; otherwise used the default values:
Ignore the Center & Bounds and go to the Layers & Styles horizontal tab, select the base layer you want to use, in our case Google Maps Normal:
We will return to this page later to add the overlay layer. Have a look at the Behaviors horizontal tab once you have a map working, it provides integration with some of the Openlayers library of functions. The Displays horizontal tab provides some help for our next step.
Creating a map view
Once we had defined the map we created a view that will filter and display the content on a page, The view needs two parts:
- Openlayers Data Overlay - the content to display
- Page or Block - the map to be displayed
On the Administration » Structure » Views page we created a new view, we filtered the content to a Water Recycling Project. This is the content type that contains the locations:
Editting the view we changed the Format to Openlayers Map, selecting the map we created earlier, Recycling Project Map.
Then we changed the Show to Fields and added the Location field. We added exposed filters for our Water Sources and Water Uses.
In the Format: OpenLayers Data Overlay | Settings we selected the Map Data Source of WKT, the Location field, and the Title:
With the OpenLayers Data Overlay created we added a Page to display the map, the only change here was the page path:
The last step was to the OpenLayers map that we defined earlier, we needed to select the data layer.
- We edited our map from the Administration » Structure » OpenLayers » Maps page
- Selected the Layers & Styles horizontal tab and scrolled to the bottom
- Enabled and activated our new overlay layer
When OpenLayers is used with Features you may not see the map edit link, click the export link and then the Edit map tab.
At this point we had a page available containing the basic map, with a bit more work adding styling and behaviours we got to:
As you can see from our map you can add a lot more details, styling and behaviours:
- We had initially planned to use the location search abilities of Search API and Apache Solr however we ended up using OpenLayers Proximity for distance filtering.
- We started with the build in OpenLayers behaviours for clustering, markers, zoom, and popup. We quickly hit the limit of what worked and could be themed and wrote a custom OpenLayers Behaviour, the clustering part can be found in a Sandbox project.
I was using OpenLayers module as well and one thing that annoyed me was the file size of the OpenLayers JS lib. Did you find any way to optimize that?
Personally I will probably try out the Leaflet module for the next project involving maps, because of that http://drupal.org/project/leaflet
Or you can just use the OpenLayers Locator feature module that sets this all up for you out of the box. www.drupal.org/project/ol_locator
thanks for this very nice write-up! i have some questions in addition:
- do you have a live-demo of your final implementation?
- did you use a custom openlayers build for performance reasons? (http://docs.openlayers.org/library/deploying.html)
- have you considered using leaflet instead of openlayers? (i find it more lightweight and in most cases feature-sufficient)
- have you considered using views_geojson to serve the data dynamically? (bounding box strategy)
This is great, thanks for sharing! Mapping in D7 is (was) sadly not as easy as in D6 but this stack looks like a winner!
This is a great writeup. Some of this exists in the "Getting Started with OpenLayers in Drupal 7" documentation page...
...but I think a lot of this could be added to make it better. Would you consider editing that page and adding in some of this wisdom?
You could also opt to add this information, or some of this information, to a separate page within the OpenLayers D7 documentation:
I wrote and heavily edited a lot of the D6 documentation after struggling through the process (this was back in 2010-11), so I know how important this kind of walk-through is to have. Thanks again for sharing!
"Maps are a complicated tangle of moving parts. Starting a new project that needs maps can be a challenge."
Too right! Thanks for these instructions -- OpenLayers certainly needs them.
So if you're a beginner in the area of maps and/or you're keen to get decent performance on a mobile device, my suggestion would be the trio of Leaflet, Leaflet More Maps and Leaflet MarkerCluster.
Check out this comparison table http://drupal.org/node/1704948 to untangle all these moving parts scattered across Drupalland.
Thanks for great tutorial, works nice!
My tip for anyone trying to do the same is to be carefull when creating views. Start with 'Page' display, then 'OpenLayers Data Overlay' and be carefull to apply changes to correct display and not both of them, as default in Views ;)
Thanks for the write up on OpenLayers. How did you use or configure the site for the clustering?
I don't have any problems creating maps with points but how about polygons or lines? Please give us some clues for displaying them using views.
Hi I have the same problem with line I have created a map with lines but want to get markers at the start of the line. I cant seem to find any sites describing how you do this. Any help appreciated? Thanks Ben