This package is a simple wrapper for querying OSRM. It assumes you have an OSRM v5.x server available. It supports route, nearest, table, match, and trip services. Driving is the only profile currently supported.
You can install the package via composer:
composer require dmgctrlr/lara-osrm
Publish the config file (config/lara-osrm.config)
php artisan vendor:publish --tag="config" --provider="Dmgctrlr\LaraOsrm\LaraOsrmServiceProvider"
You can overwrite the defaults in your .env
file too:
OSRM_HOST=localhost
OSRM_PORT=5000
OSRM_VERSION=v1
There are a few ways to get the request service, depending on your preferences and situation.
You can create them directly - passing an array (including 'host' and 'port' keys if you want to overwrite reading from config()
// Create a ServiceRequest based on the service you want: RouteServiceRequest, MatchServiceRequest, TripServiceRequest
use Dmgctrlr\LaraOsrm\RouteServiceRequest;
// Pass config to overwrite the defaults and your laravel config/lara-osrm.php
$config = [
'host' => 'localhost', // Hostname of your OSRM server
'port' => 5000, // Port for your OSRM server
];
$request = new RouteServiceRequest($config);
LaraOSRM registers with Laravel's dependency injector - so if you're using LaraOSRM in a controller, job or similar
you can simply add it as a requirement. It will be setup using the config settings defined in config/lara-osrm.php
and/or .env
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Dmgctrlr\LaraOsrm\LaraOsrm;
use Dmgctrlr\LaraOsrm\Models\LatLng;
class Test extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'lara-osrm:test';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle(LaraOsrm $osrm)
{
// Create your ServiceRequest based on the method you call
// e.g. $osrm->route() creates a RouteServiceRequest
// $osrm->match(), $osrm->trip() etc.
$request = $osrm->route();
$request->setCoordinates([
new LatLng(33.712053, -112.068195),
new LatLng(33.602053, -112.065295),
new LatLng(33.626367, -112.023641)
]);
$response = $request->send();
echo $response->getStatus(); // "Ok"
}
}
See: http://project-osrm.org/docs/v5.22.0/api/#route-service
use Dmgctrlr\LaraOsrm\Models\LatLng;
// See (Getting the Request Service)[#getting-the-request-service] to get your $request
$request->setCoordinates([
new LatLng(33.712053, -112.068195),
new LatLng(33.602053, -112.065295),
new LatLng(33.626367, -112.023641)
]);
// you can override the default options for each supported service
// This is the same as calling setOptions() multiple times. Pass each option
// a parameter, use an array if you want to set the value to something other than "true"
$request->setOptions('steps', [ 'annotations' => false ], ['overview' => 'full'], ['geometries' => 'geojson']);
// `send()` returns a Dmgctrlr\LaraOsrm\Responses\RouteServiceResponse (since we made a RouteServiceRequest).
$response = $request->send();
$status = $response->getStatus(); // "Ok"
$status = $response->getMessage(); // Mostly useful for getting the error message if there's a problem.
$routes = $response->getRoutes(); // Returns an array of Dmgctrlr\LaraOsrm\Models\Route
// @var Dmgctrlr\LaraOsrm\Models\Route $recommendedRoute **/
$recommendedRoute = $response->getFirstRoute(); // Returns the first/primary route
$recommendedRoute->getDistance(); // Returns in meters
$recommendedRoute->getDistance('km'); // Returns in kilometers
$recommendedRoute->getDistance('miles', 4); // Returns in miles ronded to 4 decimal places
See: http://project-osrm.org/docs/v5.22.0/api/#match-service
use Dmgctrlr\LaraOsrm\Models\LatLng;
// See (Getting the Request Service)[#getting-the-request-service] to get your $request
$request->setCoordinates([
new LatLng(33.712053, -112.068195),
new LatLng(33.626367, -112.023641)
]);
// you can override the default options for each supported service
$request->setOptions('steps', 'annotations', ['overview' => 'full'], ['geometries' => 'geojson']);
// `send()` returns a Dmgctrlr\LaraOsrm\Responses\RouteServiceResponse (since we made a RouteServiceRequest).
$response = $request->send();
$status = $response->getStatus(); // "Ok"
$status = $response->getMessage(); // Mostly useful for getting the error message if there's a problem.
$routes = $response->getTracepoints(); // Returns an array of Dmgctrlr\LaraOsrm\Models\LatLng
// @var Dmgctrlr\LaraOsrm\Models\Route $recommendedRoute **/
$recommendedRoute = $response->getFirstRoute(); // Returns the first/primary matching.
$recommendedRoute->getDistance(); // Returns in meters
$recommendedRoute->getDistance('km'); // Returns in kilometers
$recommendedRoute->getDistance('miles', 4); // Returns in milesr ronded to 4 decimal places
Note: This is an experimental feature, your contributions are welcome
If you want to a route request with more than a few hundred waypoints you'll run into URI length limits when the library sends a GET request to OSRM.
To workaround that you can use sendChunk()
- which is an experimental and incomplete
attempt at breaking your huge request into smaller requests and combining them.
To use sendChunk()
:
- Read the SendChunk inline documentation (
src/BaseServiceRequest.php
) - Confirm that sendChunk processes and returns the information you want (it doesn't process everything)
- Simply swap
send()
withsendChunk()
on your RouteRequest object. - Test to check that the return from
sendChunk()
is accurate enough for you.
This is actually a list of things known to (probably) work. The crux of the complexity of sendChunk is in re-combining and stitching together the multiple requests we make.
Ultimately we want to be able to perform a send()
and a sendChunk()
and get exactly
the same result. We can do this by using a test list of Waypoints which is small enough
for send()
and use really small (e.g. 10 instead of 100) chunk sizes.
The tests are currently all in: RouteServiceTest::testSendChunkReturnsSameAsSend
and
towards the bottom there are a bunch of commented out asserts. The next step
is to make those asserts work, and then declare another bit of the result OK!.
- sendChunk only works with RouteServiceRequests
- sendChunk only works when 'geometries' is set to 'geojson'
- sendChunk only works for the 'waypoints' return value
- any other returned data shouldn't be trusted (it's probably only partial).
- sendChunk may not throw an error if you try and mis-use it. Please add error reporting.
If you get errors like Failed asserting that 429 matches expected 400.
or other mentions of
code 429 then the server you're using is probably busy (or rate limiting you).
By default the tests will use the OSRM demo server, to use your own or another
server cp phpunit.xml.dist phpunit.xml
and edit the environment variables.
If you're getting errors about a route not having a distance, and you're using your own server - check the server is properly configured and is not returning non-zero distances. For these tests you must have the "berlin" area installed.
composer test
or (better on Windows):
vendor/bin/phpunit
Please see CHANGELOG for more information what has changed recently.
Please see CONTRIBUTING for details.
If you discover any security related issues, please email dm@mediavariance.com instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.
This package was generated using the Laravel Package Boilerplate.