Consistent support of addresses, coordinates, maps and searching for places is definitely the Achilles’ heel of most modern CMS. It is a complicated matter and it requires integrating a large number of independent solutions. The topic of geolocation has also been raised in many large projects implemented by Droptica. I will show you some best practices on their basis.
I will start by presenting the top 10 geolocation modules for Drupal. Familiarise yourself with them and choose the ones that best suit your needs. At the end, we will build together a sample places database, convenient to edit and eye-catching.
Modules for address support
Address
https://www.drupal.org/project/address
This module provides a field necessary to save the address, working for every country in the world. Thanks to it, you do not have to create separate fields for a street name, apartment number, city, and post code. The module’s capabilities will be especially appreciated by people who need to address support for different countries. Its configuration is very simple: just select the address elements that you want to be visible or required. The set includes ready-made validators (including the ones for postal codes) and additional “Country” and “Zone” fields.
The Address module displays the saved addresses in their basic form; customising the appearance of these fields requires having knowledge of building your own templates and CSS coding. Alternatively, it is possible to combine address fields with other modules, which will be discussed later in the article.
Modules from the geolocation family
Geolocation Field
https://www.drupal.org/project/geolocation
It is a module that adds a field with latitude and longitude to Drupal. Its basis is simple, but it also contains over 20 accompanying modules. In its simplest version, it contains a field definition, two types of controls for editing it (coordinates and an HTML5 widget that retrieves the location from the browser), and formatters that display the location as text (decimal, sexagesimal – in the form of degrees, minutes and seconds, and using tokens).
If you want to use fields with coordinates in the views, you gain some interesting features. You can, e.g. use distances in kilometres from a given point. This allows you to create a list of places within a given radius from the user. You can determine the position of the website visitor using the location service provided by the browser or based on the IP address.
Geolocation shows its full potential after running the secondary modules. Additional capabilities include:
- A map widget working both with commercial suppliers (Google Maps, Baidu, Yandex, Here) and with the Open Leaflet library (with OpenStreetMap map layers running by default). There are many configuration options here, and no additional modules are required.
- Support for static Google maps in the form of a standard PNG file.
- Experimental support for geometric shapes on maps – both simple and complex ones. Ready-made contours of countries and states of the USA and Canada are provided together with the Geolocation module.
- Integration with the Address module, providing access to a formatter with a map for address fields. It allows for showing a postal address on the map, without the need to enter geographic coordinates. Automatic conversion of a physical address into coordinates is done using the selected geocoding service (e.g. paid Google API or free Nominatom). The Geocoder module offers similar functionality.
- Integration with the Geofield module, adding a formatter with a map to fields with coordinates.
- Integration with the Search API module, adding the ability to limit the search to a given rectangular area.
It is worth mentioning that the architecture of the Geolocation module is open and well-refined, so you can easily add your functionality based on those listed above.
Modules from the Geofield family
Geofield
https://www.drupal.org/project/geofield
An alternative to the Geolocation Field module, being a somewhat competitive “ecosystem” of geographical modules. Geofield in its basic form is very simple and practical. In relation to the functionalities offered by Geolocation, Geofield also includes:
- Possibility to add the “Find my location” button to a standard widget with latitude and longitude.
- Widget with coordinate fields divided into degrees, minutes, seconds (but it does not support the “Find my location” button).
- Widget supporting the WKT (Well-known text) format describing vector objects on maps. Using WKT you can define an area of any shape instead of a specific point.
- Widget allowing you to define a bounding box – that is an area bounded by a rectangle.
Regarding the integration of Geofield with Views – fields and filters based on the distance to a given point are available, but their configuration options do not include automatic detection of the user’s location.
There are not many field display options in the basic Geofield version. You can either choose one of the popular formats (WKT, EWKT, WKB, EWKB, GeoJSON, KML, GPX, GeoRSS, GeoHash) or simply presenting the coordinates as decimal or sexagesimal numbers. It is not possible to display the position on a map.
It would seem that the Geolocation module is a better choice, but the real strength of Geofield lies in the external add-on modules:
Geofield Map
https://www.drupal.org/project/geofield_map
This module provides integration with the paid Google Maps API. It is very easy to configure, it contains a form widget for selecting locations (with address-based coordinate search), a formatter showing a given place on Google Maps, and a new view display mode that allows displaying results in the form of pins on a map. Advanced users have a lot to choose from, starting with a map layer and ending with their own icons.
The biggest disadvantage of the Geofield Map module is the inevitable cost of using Google API. This is important for websites with a high number of pageview hits. The creators of the module have implemented three mechanisms that allow for significant savings:
- Support for the free OpenStreetView service via the Leaflet.js library. This applies only to the edit form widget.
- Support for static maps, i.e. generated by Google in the form of a PNG file. They are not interactive, but they are sufficient for some applications.
- Support for simple Google maps available without limits for free. They are interactive, but their configuration options are very limited.
Leaflet
https://www.drupal.org/project/leaflet
An alternative to Geofield Map, based on the open Leaflet.js library. By default, it includes support for the free OpenStreetMap website. The most important functionalities of the module are:
- Solid Geofield field formatter that allows you to configure every aspect of the map.
- Views support – map display mode or using the Views GeoJSON module to show structures more complex than individual points.
- Built-in support for the Leaflet.markercluster library grouping pins when zooming a map out.
- Ability to define map layers using a hook.
- Support for form widgets supported by the external Leaflet Widgetmodule. It is a highly advanced functionality, including drawing geometric shapes and placing various types of icons. For basic applications, it is better to use the Leaflet.js widget provided by Geofield Map that has been described earlier.
To sum up – you have a fully free solution here, which should be enough for most needs.
Geocoder
https://www.drupal.org/project/geocoder
When describing the modules from the Geofield ecosystem, I have not yet mentioned the conversion of a postal address into coordinates. This is the domain of the perfectly designed Geocoder module. It expands widgets, formatters, and views with the possibility of geocoding based on several paid and free providers. The selection of a supplier is carried out separately for every element being configured, which allows for planning the possible costs very accurately.
With the help of Geocode you can, e.g.:
- Show coordinates as a postal address (through a separate dedicated formatter).
- Include a location search by address in edit forms.
- Read an address from fields of any type (also those defined by the Address module) and replace it with the position on a map (and vice versa – replace coordinates with an address). Later in the article, I will present a sample configuration for such a solution.
- It is also worth to use the Geocoder AJAX Prepopulate module allowing for finding coordinates based on an address, without leaving the editing form. This is because the standard implementation contained in Geocoder allows for geocoding only when the form is being saved. If there is a need to make corrections to a map location, you must enter the edit option again.
Other modules
Simple Google Maps
https://www.drupal.org/project/simple_gmap
There is a possibility that you do not need extensive geolocation options at all. The Simple Google Maps module is a significant simplification of what I have described so far. It just provides a map formatter that can be set for any text field. When you enter an address in this field, the end-user will see a Google map generated based on their address. It is free and you do not have to obtain the API key. For obvious reasons, it does not offer the integration with Views or a widget to mark the position on a map in a form.
Sample places database
You have already learned about the basic modules for geolocation. Now it is time to use them on a specific example. We will create a places database where every entry will have a title, description, address, and coordinates. We will display the list of places in the form of pins on a map. We often encounter this type of solution when creating corporate websites, for example when publishing information about events or facilities of a given company.
We will need to install the following modules for the needs of our places database (I recommend doing it using Composer because external libraries are required):
- Address (https://www.drupal.org/project/address)
- Geofield (https://www.drupal.org/project/geofield)
- Geofield Map (https://www.drupal.org/project/geofield_map)
- Leaflet (https://www.drupal.org/project/leaflet) – including Leaflet Views and Leaflet Markercluster
- Geocoder (https://www.drupal.org/project/geocoder) – including Geocoder Address, Geocoder Field and Geocoder Geofield.
- Geocoder AJAX Prepopulate (https://www.drupal.org/project/geocoder_ajax_prepopulate)
Editing
Editing the places will definitely be the biggest challenge. We want the address to apply to any country. Every place must have coordinates, but they can be filled out based on the address. The address can also be filled out based on the coordinates. Such an approach will greatly simplify the work of content creators. An additional assumption is using only free tools
In the beginning, we create a new type of the Place content. We add the following fields to it:
- New Address field named field_address (hide name, surname, and company name in field settings)
- New Geofield field named field_coordinates
Then we determine the relationship between these two fields. We want the address field to be filled out based on the map if the user has not entered the address. And vice versa – for the place on the map to be filled out based on the address after pressing the button. In order to do this:
We enter the field_address field settings and in the Geocode section, we select the “Reverse Geocode” option (conversion of coordinates into an address). We choose “Coordinates” from the field list and also select “Skip Geocode/Reverse Geocode if the target value is not empty”. We choose free Nominatim on the list of suppliers.
We enter the field_coordinates field settings and in the Geocode section, we choose the option “Prepopulate by geocoding an existing field” (conversion of an address into coordinates). We choose “Address” from the field list and also select “Skip Geocode/Reverse Geocode if the target value is not empty”. We also choose Nominatim on the list of suppliers.
When we try to create a new place, we will quickly conclude that using latitude and longitude is inconvenient. It is much easier to use the map for this purpose. We go then to the form settings for the Place type of content and select the Geofield Map widget for the field_coordinates field. A warning about the unconfigured Google API key will appear, but we can ignore it. This is because we will use the free Leaflet.js library.
The last step is to configure the aforementioned Nominatim website. We go to the address /admin/config/system/geocoder and enter The root URL https://nominatim.openstreetmap.org and Locale pl. That is all!
Now let us try to add a new place. After filling out the address fields, we click the Populate from the Address field button, and with any luck, we should get the location of the address on the map. If we will not add the address at all, just a place on the map – the address will be read based on coordinates.
Display
Now it is time to display the place. We go to display modes for our type of Place content and set a formatter for the field_coordinates field. Now let us check out the page with a functional map created just now:
Views
Displaying a list of places is just as easy. We create a new view in which we show only the nodes with the Place content type. We set the Leaflet Map as the display format.
For the map to work, we need to add the field_coordinates field.
Then, in the Leaflet Map format settings, we select Grouping field No. 1 as “Content Coordinates”.
We save the view, add a few places, go to the /places address. We get an interactive map with marked pins. We can quickly expand it with other functionalities, such as displaying only the places located 30 km from our location.
Final thoughts
As you can see, the support for geolocation in Drupal requires a lot of knowledge, but it also allows you to create perfectly working solutions for your clients. The possibilities are almost limitless, while the time of implementation is relatively short. In our example, we have barely scratched the surface of the topic of maps and geocoding – it is actually much more extensive. I encourage you to experiment on your own, also trying out the paid components from Google!