This article will show step by step guide on how to setup a View that shows list of Drupal 7 site contents that are filtered and sorted based on your visitor's location with the use of Smart IP and OpenLayers Proximity contributed modules. Basically, we use Smart IP module to identify Drupal site visitor's geographical location based on his IP address and OpenLayers Proximity module responsible in geographical proximity search for the OpenLayers module.
The OpenLayers Proximity module exposes a filter to the Views module where users can specify address of a location as starting point and radius of the proximity search and it also enables users to sort the results using the defined proximity filter as point of reference. The Smart IP module extends these Views filter and sort handlers of OpenLayers Proximity module where the Smart IP's extended handlers uses the visitor's geographical location as starting point instead of hardcoded address of a location in the Views filter criteria.
This step by step guide is tested on a clean installed Drupal 7.41 with the following modules enabled which are required to make this application work:
- Smart IP 7.x-2.x-dev
- Openlayers 7.x-3.0-beta
- OpenLayers Proximity 7.x-2.x-dev
- Libraries 7.x-2.2
- Service Container 7.x-1.0-beta5
- Registry Autoload 7.x-1.3
- jQuery Update 7.x-2.7
- Geofield 7.x-2.3
- geoPHP 7.x-1.7
As of this writing, the version number of each module listed above are the latest. If you find there's version higher than listed above, feel free to use it (just in case the higher version does not work in this application you can always follow and use the version number above).
Lets assume we have a Drupal site with database of barbershops. Each barbershop is stored as a node with its geolocation details. In our front page, we want to display list of barbershops 30 miles nearest to our visitors. The following will guide you to accomplish this task:
Enable the modules listed above.
Setup a content type or use an existing content type (in this example the content type's name is "Barbershop") and add a new field with Geofield field type. Select the "Latitude / Longitude" widget type for this field and use the default values for succeeding setup settings of this field.
Create some contents and populate their Geofield field with different coordinate locations. Note: If your site has existing contents with their Geofield fields already populated, execute the "Rebuild Index" at http://yoursite.com/admin/structure/openlayers/proximity to build the openlayers proximity index table for the existing nodes.
Setup a new Views that will display the nodes under the content type with Geofield field you have setup earlier.
Add a filter criteria using "Smart IP: Openlayers proximity great-circle" filter. Under "Operator" select "Is less than", type "30" in "Value" field, select "Miles" in "Unit of measurement" dropdown field and in "Location" field populate it with Smart IP tokens: "smart_ip][location][country, smart_ip][location][region, smart_ip][location][city, smart_ip][location][zip" (these tokens will actually be replaced with visitor's country, region, city, zip code on the fly and the openlayers proximity module will geocode this address).
Remove the existing "Content: Post date (desc)" sort criteria which was auto created by Views.
Add "Smart IP: Openlayers proximity distance" as our sort criteria for this View. Select "Sort ascending". You may have noticed that "Location provider" is populated with the "Smart IP: Openlayers proximity great-circle" filter criteria we have created earlier, this is because the Openlayers proximity views sort handler requires at least Openlayers proximity great-circle filter present as point of reference for sorting.
Lets add a field in our Views that will display the distance of the barbershop from the visitor. Add "Smart IP: Openlayers proximity distance" field, change the label to "Distance" and leave the other options to their default values. Again this field requires at least Openlayers proximity great-circle filter present as point of reference for measuring the distance that will be displayed.
Save your Views. The Views result should look something like this: