Search by

opengeocoding / opengeocoding-provider

Mokto

Geocoder OpenGeocoding adapter

Package info

github.com/Mokto/geocoder-php-opengeocoding-provider

Homepage

pkg:composer/opengeocoding/opengeocoding-provider

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-10-28 19:14 UTC

This package is auto-updated.

Last update: 2026-10-29 07:44:20 UTC


README

CI Latest Stable Version Total Downloads Software License

A Geocoder PHP provider for OpenGeocoding, a hosted geocoding API built on open data (OpenStreetMap, Overture Maps, OpenAddresses, GeoNames). The engine is source-available.

This is a third-party package, not one of the Geocoder core team's providers. I run OpenGeocoding and maintain this package.

Install

You need a PSR-18 HTTP client, for example Guzzle:

composer require opengeocoding/opengeocoding-provider guzzlehttp/guzzle

Create an API key in the OpenGeocoding dashboard. The provider sends it in the x-api-key header, never in the URL.

Usage

use Geocoder\Provider\OpenGeocoding\OpenGeocoding;
use Geocoder\Query\GeocodeQuery;
use Geocoder\Query\ReverseQuery;
use Http\Discovery\Psr18Client;

$provider = new OpenGeocoding(new Psr18Client(), getenv('OPENGEOCODING_API_KEY'));

$address = $provider->geocodeQuery(GeocodeQuery::create('10 Rue de Rivoli, Paris'))->first();
echo $address->getCoordinates()->getLatitude();  // 48.8555
echo $address->getPostalCode();                   // 75004
echo $address->getDisplayName();                  // 10, Rue de Rivoli, Paris, Ile-de-France, France

$results = $provider->reverseQuery(ReverseQuery::fromCoordinates(55.676, 12.568)->withLimit(3));
foreach ($results as $address) {
    printf("%s (%.0f m)\n", $address->getDisplayName(), $address->getDistance());
}

The provider works with the rest of Geocoder PHP, such as StatefulGeocoder, ProviderAggregator, the Chain provider and the cache plugin.

Behaviour

  • Search returns at most one result, the best match, whatever the query's limit. An address that matches nothing returns an empty collection.
  • Reverse returns the nearest results first, up to the query's limit (at most 10). Pass a search radius in metres with ->withData('radiusM', 200) (the API accepts up to 2000 and defaults to 500).
  • The locale is ignored: the API has no language parameter.
  • IP addresses are not supported (UnsupportedOperation).
  • Admin levels come from the address's regions, ordered from the largest; their codes are the ISO 3166-2 subdivision codes (IDF for Île-de-France). Country codes are upper case.
  • Results are OpenGeocodingAddress objects, with getDisplayName(), isGoodMatch() (false for a partial match, such as the street when the house number was not found) and, for reverse results, getDistance() in metres and getLayer() (address, street or locality).

Errors

HTTP status Exception
401, 403 Geocoder\Exception\InvalidCredentials
429 (rate limit or no credits left) Geocoder\Exception\QuotaExceeded
400 Geocoder\Exception\InvalidArgument, with the API's message
anything else Geocoder\Exception\InvalidServerResponse

Pricing

The Free plan includes 50,000 requests a month at 2 requests per second, and commercial use is allowed. Paid plans are on the pricing page.

Data attribution

Results come from open data under the ODbL and other open-data licences. When you show results, or data derived from them, to others, credit the sources, for example:

Data © OpenStreetMap contributors (ODbL 1.0), Overture Maps Foundation, OpenAddresses contributors, GeoNames (CC BY 4.0, modified). Details: https://opengeocoding.com/legal/attributions

Some countries' sources need their own credit line; see the data attributions page.

Development

composer update
composer test      # unit tests and the shared Geocoder integration tests, from cached responses
composer analyse   # PHPStan
composer cs        # PHP CS Fixer

The tests replay the responses in Tests/.cached_responses. To record a new one, delete the matching file and run the tests with OPENGEOCODING_API_KEY set. The key is sent in a header, so it never reaches the cached files. Check that a recorded file holds a real result, not an error, before you commit it.

License

MIT. See LICENSE.