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.
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.
Installing in my Drupal local deploy
- 1 Access Token
- 5,000 request/day
- 2 request/second
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
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 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
What about Drupal
// 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() . ', ' .
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:
There are some public resources opened to connections, like:
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.
$ 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 \
And using its own API for get data: