Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Drupal 8 || 9 - Reverse Geocoding using external Service from PHP

I was developing an external query based in long/lat values in order to get certain addresses. For do this, I was using the geocoding library for PHP and some providers. I'm gathering here the main steps and how you can execute the integrations.

Maria Arias de Reyna, @delawen and Juan Luis Rodríguez, @juanluisrp guided me. They are the greatest GIS experts I know and they were very helpful here, givin' me some ideas and links to resources. Kudos.

Author

Introduction

Reverse geocoding is the process of converting a location as described by geographic coordinates (latitude, longitude) to a human-readable address or place name. It is the opposite of forward geocoding.

More info:

Geocoding / Reverse geocoding in PHP

I'm using the classical https://geocoder-php.org library. It requires the main library and the external providers classes in order to connect to others external APIs.

In this case I'm using LocationIQ to get the addresses: https://locationiq.com in free mode. I'm getting a token API for queries.

Limitations:

  • 1 Access Token
  • 5,000 request/day
  • 2 request/second

Installing in my Drupal local deploy

DDEV I'm using DDEV in local deploys. Do you know DDEV? I put some references in a former gist. Take a look here. Learn how to launch Drupal deploys in only six steps here, in this Gist.

$ ddev composer require willdurand/geocoder
$ ddev composer require geocoder-php/locationiq-provider 

Or whithout ddev if you're out of this tooling:

$ composer require willdurand/geocoder
$ composer require geocoder-php/locationiq-provider 

Now I have now the classes available through the class loader. I can use the resources in my installation. Geocoder only requires just a pair of keyresources:

  • An external provider
  • A HTTP Client for connections.

Geocoder Providers
Geocoder has diverse providers, and you need to select and install using Composer a provider for your code. See the Geocoder Providers here: https://packagist.org/providers/geocoder-php/provider-implementation.

Drupal Http Clients
Drupal offers diverse ways to implements Http Clients. I wrote down some notes about the cases here, in another snippet.

I have the provider and I have the HTTP Client too, Guzzle library, present and available in Drupal.

Making Reverse Geocoding Queries

<?php

[...]
use Geocoder\Query\ReverseQuery;
use Http\Adapter\Guzzle6\Client;
use Geocoder\Provider\LocationIQ\LocationIQ;
use Geocoder\StatefulGeocoder; 
[...]

// You can use other options for the HTTP Client. 
// $httpClient = \Drupal::httpClient();
$httpClient = new Client();
$provider = new LocationIQ($httpClient, "MY-APIKEY-FROM-LOCATIONIQ");
$geocoder = new StatefulGeocoder($provider, 'en');

// Launch the external query.
$result = $geocoder->reverseQuery(ReverseQuery::fromCoordinates($latitude_data, $longitude_data));

// Mount the returned address like an unique string. 
$address = $result->first()->getStreetName() . ' ' . $result->first()->getStreetNumber() . ', ' .
            $result->first()->getLocality() . ' ' . $result->first()->getPostalCode() . ', ' .
            $result->first()->getCountry()->getName();

What about Drupal

In Drupal you can use the Drupal Geocoder Module, a contrib module that acting like a wrapper for geocoder library and resolves by itself the installation of the main library, as you can see in: /geocoder/composer.json.

You have to follow the instructions from its README file: geocoder/README.md.

There are some weird issues installing providers, see the Issue:
https://www.drupal.org/project/geocoder/issues/3153678

More resources

There are some public resources opened to connections, like: http://www.cartociudad.es/geocoder/api/geocoder/reverseGeocode?lon=-0.562854&lat=39.918735

And there are some heavy-weight solutions, like Nominatim:

That allows some operations for geocoding and reverse geocoding: https://operations.osmfoundation.org/policies/nominatim/.
-No heavy uses (an absolute maximum of 1 request per second)-

Maybe you can need run your own container for Nominatim: https://hub.docker.com/r/mediagis/nominatim with OSM data.

Just execute:

$ docker run -it --rm \
  -e PBF_URL=https://download.geofabrik.de/europe/monaco-latest.osm.pbf \
  -e REPLICATION_URL=https://download.geofabrik.de/europe/monaco-updates/ \
  -p 8080:8080 \
  --name nominatim \
  mediagis/nominatim:3.7

And using its own API for get data:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment