geocoder-php/openrouteservice-provider
OpenRouteService provider for Geocoder PHP. Integrates ORS geocoding into the Geocoder ecosystem via a simple provider class, supporting forward and reverse geocoding through the OpenRouteService API with configurable HTTP client and API key.
Installation
composer require geocoder-php/openrouteservice-provider
Ensure geocoder-php/geocoder is also installed (core dependency).
Basic Configuration Add the provider to your Geocoder client:
use Geocoder\ProviderManager;
use GeocoderPhp\OpenrouteserviceProvider;
$provider = new OpenrouteserviceProvider('YOUR_OPENROUTE_SERVICE_API_KEY');
$client = new ProviderManager();
$client->addProvider('openrouteservice', $provider);
First Use Case: Geocoding
$geocode = $client->geocodeQuery('Berlin, Germany');
foreach ($geocode as $hit) {
echo $hit->getCoordinates(); // Output: [longitude, latitude]
}
First Use Case: Routing
$route = $client->route([
'coordinates' => [[13.404954, 52.520008], [13.388860, 52.517037]],
'profile' => 'driving-car'
]);
OpenrouteserviceProvider in src/OpenrouteserviceProvider.php for method signatures.$results = $client->geocodeQuery('1600 Amphitheatre Parkway, Mountain View, CA');
$firstResult = $results->first();
$coordinates = $firstResult->getCoordinates();
$formattedAddress = $firstResult->getFormattedAddress();
$reverse = $client->reverseQuery([13.404954, 52.520008]);
foreach ($reverse as $hit) {
echo $hit->getStreetNumber() . ' ' . $hit->getStreetName();
}
$route = $client->route([
'coordinates' => [[lon1, lat1], [lon2, lat2]],
'profile' => 'cycling-regular', // Other options: 'foot-walking', 'driving-hgv'
'options' => ['elevation' => true] // Additional OpenRouteService options
]);
$addresses = ['Berlin', 'Paris', 'Tokyo'];
$results = $client->geocodeBatch($addresses);
// In a service provider or config file
$client = new ProviderManager();
$client->addProvider('openrouteservice', new OpenrouteserviceProvider(config('services.openrouteservice.key')));
// Bind to Laravel container
app()->singleton('geocoder', function () use ($client) {
return $client;
});
Then inject geocoder into controllers/services:
public function __construct(private ProviderManager $geocoder) {}
Use Laravel's cache to avoid hitting API limits:
$cacheKey = 'geocode_' . md5($query);
$results = Cache::remember($cacheKey, now()->addHours(1), function () use ($client, $query) {
return $client->geocodeQuery($query);
});
Wrap calls in try-catch:
try {
$route = $client->route($coordinates);
} catch (\Geocoder\Exception\UnsupportedProviderException $e) {
Log::error('OpenRouteService provider error: ' . $e->getMessage());
// Fallback to another provider
}
OpenRouteService has rate limits. Implement exponential backoff:
use Symfony\Component\RateLimiter\RateLimiter;
$rateLimiter = new RateLimiter(10, 'minute'); // 10 requests/minute
if (!$rateLimiter->isAllowed()) {
sleep($rateLimiter->getWaitTime());
}
Store API keys in .env:
OPENROUTESERVICE_KEY=your_api_key_here
Then load in config/services.php:
'openrouteservice' => [
'key' => env('OPENROUTESERVICE_KEY'),
],
.env and config/services.php. Add .env to .gitignore.options['timeout'] parameter to avoid hanging:
$client->route([...], ['timeout' => 5]); // 5-second timeout
[longitude, latitude] (not [latitude, longitude]).$coordinates = [13.404954, 52.520008]; // Correct: [lon, lat]
driving-hgv may not support elevation.$provider->setDebug(true); // Enable HTTP request logging
Logs will show the raw API response for troubleshooting.
OpenRouteService returns structured JSON. Validate responses:
$route = $client->route($coordinates);
if (isset($route['routes'][0]['geometry'])) {
// Success
} else {
// Handle error (e.g., invalid coordinates)
}
Wrap the provider in a custom class to log HTTP errors:
use GuzzleHttp\Exception\RequestException;
$provider->setHttpClient(new \GuzzleHttp\Client([
'on_request' => function ($request) {
Log::debug('OpenRouteService Request:', [
'method' => $request->getMethod(),
'uri' => (string) $request->getUri(),
]);
},
'on_response' => function ($response) {
Log::debug('OpenRouteService Response:', [
'status' => $response->getStatusCode(),
'body' => (string) $response->getBody(),
]);
},
'on_error' => function (RequestException $e) {
Log::error('OpenRouteService Error:', [
'message' => $e->getMessage(),
'response' => $e->getResponse() ? (string) $e->getResponse()->getBody() : null,
]);
},
]));
Override the default Guzzle client for retries, middleware, or proxies:
$client = new \GuzzleHttp\Client([
'timeout' => 10,
'headers' => [
'Accept' => 'application/json',
'User-Agent' => 'MyApp/1.0',
],
]);
$provider->setHttpClient($client);
Include custom headers (e
How can I help you explore Laravel packages today?