PHPackages                             gowelle/laravel-route-matrix - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. gowelle/laravel-route-matrix

ActiveLibrary[API Development](/categories/api)

gowelle/laravel-route-matrix
============================

A Laravel wrapper package for Google Routes API (Compute Routes)

v2.0.1(3mo ago)1451↑45.3%MITPHPPHP ^8.3CI passing

Since Jan 11Pushed 3mo agoCompare

[ Source](https://github.com/gowelle/laravel-route-matrix)[ Packagist](https://packagist.org/packages/gowelle/laravel-route-matrix)[ Docs](https://github.com/gowelle/laravel-route-matrix)[ RSS](/packages/gowelle-laravel-route-matrix/feed)WikiDiscussions master Synced yesterday

READMEChangelog (5)Dependencies (18)Versions (6)Used By (0)

Laravel Route Matrix
====================

[](#laravel-route-matrix)

[![Latest Version on Packagist](https://camo.githubusercontent.com/14443e3d3160fa49d7f1cd7f91e22b2b9361d502313aebb126eadbb30e1bd386/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f676f77656c6c652f6c61726176656c2d726f7574652d6d61747269782e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gowelle/laravel-route-matrix)[![GitHub Tests Action Status](https://camo.githubusercontent.com/48b41069c534443c4a669ca1ef69afa6902b6c3dcde0c0d33ec0a477173ef12d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f676f77656c6c652f6c61726176656c2d726f7574652d6d61747269782f74657374732e796d6c3f6272616e63683d6d6173746572266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/gowelle/laravel-route-matrix/actions?query=workflow%3Atests+branch%3Amaster)[![Total Downloads](https://camo.githubusercontent.com/dc987a6ecd5c44ada56f4a17d8ab712777414db131b8f8413b78adb30ab0f46c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f676f77656c6c652f6c61726176656c2d726f7574652d6d61747269782e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gowelle/laravel-route-matrix)

A Laravel wrapper for the [Google Routes API](https://developers.google.com/maps/documentation/routes) with support for route calculation, distance matrices, and waypoint optimization.

Table of Contents
-----------------

[](#table-of-contents)

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Usage](#usage)
    - [Basic Route Calculation](#basic-route-calculation)
    - [Travel Modes](#travel-modes)
    - [Traffic-Aware Routing](#traffic-aware-routing)
    - [Route Modifiers](#route-modifiers)
    - [Alternative Routes](#alternative-routes)
    - [Waypoint Optimization](#waypoint-optimization)
- [Route Matrix](#route-matrix-distance-matrix)
    - [One to Many](#one-origin-to-multiple-destinations)
    - [Many to One](#multiple-origins-to-one-destination)
    - [Many to Many](#many-to-many-full-matrix)
    - [Courier Example](#real-world-example-courier-pickup--delivery)
- [Response Objects](#response-objects)
- [Eloquent Integration](#eloquent-integration-routable-trait)
- [Configuration](#configuration)
- [Exception Handling](#exception-handling)
- [Testing](#testing)
- [License](#license)

Features
--------

[](#features)

- 🚗 **Multiple Travel Modes** - Driving, walking, bicycling, two-wheeler, transit
- 🚦 **Traffic-Aware Routing** - Real-time and historical traffic data
- 📍 **Flexible Waypoints** - Coordinates, Place IDs, or addresses
- 📊 **Distance Matrix** - Calculate N×M origin-destination pairs
- 🎯 **Find Closest** - Get closest/fastest destination helpers
- ⚡ **Fluent API** - Elegant, chainable method calls
- 🧪 **Fully Tested** - 125+ tests with Pest PHP

Requirements
------------

[](#requirements)

- PHP 8.3+
- Laravel 11.x, 12.x, or 13.x
- Google Cloud API key with Routes API enabled

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require gowelle/laravel-route-matrix
```

Publish the configuration file:

```
php artisan vendor:publish --tag=google-routes-config
```

Add your Google API key to your `.env` file:

```
GOOGLE_ROUTES_API_KEY=your-api-key-here
```

Quick Start
-----------

[](#quick-start)

```
use Gowelle\LaravelRouteMatrix\Facades\GoogleRoutes;

// Posta -> Mlimani City Mall
$response = GoogleRoutes::from(['lat' => -6.8163, 'lng' => 39.2807])
    ->to(['lat' => -6.7724, 'lng' => 39.2083])
    ->get();

$route = $response->first();

echo "Distance: {$route->getDistanceInKilometers()} km";
echo "Duration: {$route->getFormattedDuration()}";
```

Usage
-----

[](#usage)

### Basic Route Calculation

[](#basic-route-calculation)

```
use Gowelle\LaravelRouteMatrix\Facades\GoogleRoutes;

$response = GoogleRoutes::from(['lat' => -6.8163, 'lng' => 39.2807])
    ->to(['lat' => -6.7724, 'lng' => 39.2083])
    ->get();

// Access the first (recommended) route
$route = $response->first();
echo $route->distanceMeters;      // 8200
echo $route->duration;            // "900s"
echo $route->getDurationInSeconds(); // 900
```

### Using Addresses

[](#using-addresses)

```
$response = GoogleRoutes::from('Julius Nyerere International Airport, Dar es Salaam')
    ->to('Mlimani City Mall, Dar es Salaam')
    ->get();
```

### Using Place IDs

[](#using-place-ids)

```
use Gowelle\LaravelRouteMatrix\ValueObjects\Waypoint;

// Example with Place IDs
$response = GoogleRoutes::from(Waypoint::fromPlaceId('ChIJ...' /* Posta */))
    ->to(Waypoint::fromAddress('Mlimani City Mall, Dar es Salaam'))
    ->get();
```

### With Intermediate Waypoints

[](#with-intermediate-waypoints)

```
// Posta -> Kariakoo -> Magomeni -> Mlimani City
$response = GoogleRoutes::from(['lat' => -6.8163, 'lng' => 39.2807])
    ->via(['lat' => -6.8235, 'lng' => 39.2695]) // Kariakoo
    ->via(['lat' => -6.8059, 'lng' => 39.2536]) // Magomeni
    ->to(['lat' => -6.7724, 'lng' => 39.2083])
    ->get();

// Access individual legs
foreach ($route->legs as $leg) {
    echo "Leg distance: {$leg->distanceMeters}m\n";
}
```

### Travel Modes

[](#travel-modes)

```
use Gowelle\LaravelRouteMatrix\Enums\TravelMode;

// Using enum
$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->travelMode(TravelMode::DRIVE)
    ->get();

// Using shortcuts
$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->driving()  // or walking(), bicycling(), transit()
    ->get();
```

### Traffic-Aware Routing

[](#traffic-aware-routing)

```
use Gowelle\LaravelRouteMatrix\Enums\RoutingPreference;

$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->routingPreference(RoutingPreference::TRAFFIC_AWARE_OPTIMAL)
    ->get();

// Or use the shortcut
$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->withOptimalTraffic()
    ->get();
```

### Route Modifiers

[](#route-modifiers)

```
$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->avoidTolls()
    ->avoidHighways()
    ->avoidFerries()
    ->get();
```

### Alternative Routes

[](#alternative-routes)

```
$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->withAlternatives()
    ->get();

// Get the main route
$mainRoute = $response->first();

// Get alternative routes
$alternatives = $response->getAlternatives();

foreach ($alternatives as $route) {
    echo "Alternative: {$route->getFormattedDuration()}\n";
}
```

### Fuel-Efficient Routes

[](#fuel-efficient-routes)

```
$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->withFuelEfficientRoute()
    ->get();

$fuelEfficientRoute = $response->getFuelEfficientRoute();
```

### Waypoint Optimization

[](#waypoint-optimization)

```
$response = GoogleRoutes::from($origin)
    ->via($waypoint1)
    ->via($waypoint2)
    ->via($waypoint3)
    ->to($destination)
    ->optimizeWaypointOrder()
    ->get();

// Get the optimized order
$optimizedOrder = $response->first()->optimizedIntermediateWaypointIndex;
```

### Departure Time

[](#departure-time)

```
use Carbon\Carbon;

$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->departureTime(Carbon::now()->addHour())
    ->get();

// Or depart now
$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->departNow()
    ->get();
```

### Extra Computations

[](#extra-computations)

```
$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->withTolls()
    ->withFuelConsumption()
    ->withTrafficOnPolyline()
    ->get();
```

### Custom Field Mask

[](#custom-field-mask)

Specify which fields to include in the response:

```
$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->fields([
        'routes.duration',
        'routes.distanceMeters',
        'routes.polyline.encodedPolyline',
        'routes.legs.steps',
        'routes.viewport',
    ])
    ->get();
```

### High Quality Polylines

[](#high-quality-polylines)

```
use Gowelle\LaravelRouteMatrix\Enums\PolylineEncoding;

$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->highQualityPolyline()
    ->get();

// Or use GeoJSON format
$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->geoJsonPolyline()
    ->get();
```

### Localization

[](#localization)

```
use Gowelle\LaravelRouteMatrix\Enums\Units;

$response = GoogleRoutes::from($origin)
    ->to($destination)
    ->language('es-ES')
    ->region('ES')
    ->units(Units::METRIC)  // or imperial()
    ->get();
```

### Complete Example

[](#complete-example)

```
use Gowelle\LaravelRouteMatrix\Facades\GoogleRoutes;
use Gowelle\LaravelRouteMatrix\Enums\TravelMode;
use Gowelle\LaravelRouteMatrix\Enums\RoutingPreference;
use Carbon\Carbon;

// Posta to Mlimani City with waypoints and options
$response = GoogleRoutes::from(['lat' => -6.8163, 'lng' => 39.2807])
    ->to(['lat' => -6.7724, 'lng' => 39.2083])
    ->via(['lat' => -6.8235, 'lng' => 39.2695]) // Kariakoo
    ->travelMode(TravelMode::DRIVE)
    ->routingPreference(RoutingPreference::TRAFFIC_AWARE_OPTIMAL)
    ->avoidTolls()
    ->departureTime(Carbon::now()->addHour())
    ->withAlternatives()
    ->withFuelEfficientRoute()
    ->language('en-US')
    ->metric()
    ->fields([
        'routes.duration',
        'routes.distanceMeters',
        'routes.polyline.encodedPolyline',
        'routes.legs',
        'routes.routeLabels',
    ])
    ->get();

// Process the response
$route = $response->first();

echo "Distance: " . $route->getDistanceInKilometers() . " km\n";
echo "Duration: " . $route->getFormattedDuration() . "\n";
echo "Polyline: " . $route->polyline?->encodedPolyline . "\n";

// Check for warnings
if (!empty($route->warnings)) {
    foreach ($route->warnings as $warning) {
        echo "Warning: {$warning}\n";
    }
}
```

Eloquent Integration (Routable Trait)
-------------------------------------

[](#eloquent-integration-routable-trait)

You can make your Eloquent models "routable" by implementing the `Routable` contract and using the `HasRoute` trait. This allows you to pass models directly to the API headers.

1. Implement the interface and trait:

```
use Illuminate\Database\Eloquent\Model;
use Gowelle\LaravelRouteMatrix\Contracts\Routable;
use Gowelle\LaravelRouteMatrix\Traits\HasRoute;

class Store extends Model implements Routable
{
    use HasRoute;

    // Optional: Customize how the waypoint is resolved
    // (Defaults to looking for lat/lng, latitude/longitude, or address attributes)
}
```

2. Use models in route requests:

```
$store = Store::find(1);
$customer = User::find(5); // Assuming User also implements Routable

$response = GoogleRoutes::from($store)
    ->to($customer)
    ->get();
```

3. Or initiate directly from the model:

```
$response = $store->routeTo($customer)
    ->driving()
    ->get();
```

Response Caching
----------------

[](#response-caching)

To reduce API costs and improve performance, you can enable built-in caching.

1. Configure caching in `config/google-routes.php`:

```
'cache' => [
    'enabled' => true,
    'store' => 'redis', // or 'file', 'database'
    'ttl' => 3600,      // Cache duration in seconds
],
```

When enabled, identical requests (same origin, destination, and options) will be served from the cache for the specified TTL duration.

Route Matrix (Distance Matrix)
------------------------------

[](#route-matrix-distance-matrix)

The Route Matrix API allows you to calculate distances and travel times between multiple origins and destinations efficiently.

### One Origin to Multiple Destinations

[](#one-origin-to-multiple-destinations)

```
use Gowelle\LaravelRouteMatrix\Facades\GoogleRoutes;

$response = GoogleRoutes::matrix()
    ->addOrigin(['lat' => -6.8163, 'lng' => 39.2807]) // Posta (Your location)
    ->addDestination(['lat' => -6.8235, 'lng' => 39.2695]) // Kariakoo
    ->addDestination(['lat' => -6.7724, 'lng' => 39.2083]) // Mlimani City
    ->addDestination(['lat' => -6.7567, 'lng' => 39.2772]) // Masaki
    ->driving()
    ->get();

// Find the closest destination
$closest = $response->getClosestDestination(0);
echo "Closest: {$closest->getDistanceInKilometers()} km";

// Find the fastest destination
$fastest = $response->getFastestDestination(0);
echo "Fastest: {$fastest->getFormattedDuration()}";
```

### Multiple Origins to One Destination

[](#multiple-origins-to-one-destination)

```
// Find which store/warehouse is closest to a customer
$response = GoogleRoutes::matrix()
    ->addOrigin(['lat' => -6.8163, 'lng' => 39.2807]) // Store A (Posta)
    ->addOrigin(['lat' => -6.8235, 'lng' => 39.2695]) // Store B (Kariakoo)
    ->addOrigin(['lat' => -6.7724, 'lng' => 39.2083]) // Store C (Mlimani City)
    ->addDestination(['lat' => -6.7567, 'lng' => 39.2772]) // Customer (Masaki)
    ->driving()
    ->get();

$closestStore = $response->getClosestOrigin(0);
echo "Ship from store at origin index: {$closestStore->originIndex}";
```

### Many to Many (Full Matrix)

[](#many-to-many-full-matrix)

```
$response = GoogleRoutes::matrix()
    ->origins([
        ['lat' => -6.8163, 'lng' => 39.2807], // Posta
        ['lat' => -6.8235, 'lng' => 39.2695], // Kariakoo
    ])
    ->destinations([
        ['lat' => -6.7724, 'lng' => 39.2083], // Mlimani City
        ['lat' => -6.7567, 'lng' => 39.2772], // Masaki
    ])
    ->driving()
    ->withTraffic()
    ->get();

// Access specific element (origin 0 → destination 1)
$element = $response->get(0, 1);
echo "Distance: {$element->getDistanceInKilometers()} km";
echo "Duration: {$element->getFormattedDuration()}";

// Convert to 2D matrix format
$matrix = $response->toMatrix();
// $matrix[originIndex][destinationIndex] = RouteMatrixElement
```

### Sorting Results

[](#sorting-results)

```
// Get all destinations sorted by distance (closest first)
$sortedByDistance = $response->sortedByDistance();

// Get all destinations sorted by duration (fastest first)
$sortedByDuration = $response->sortedByDuration();

// Get only elements where a route was found
$validRoutes = $response->withRoutes();
```

### RouteMatrixElement Properties

[](#routematrixelement-properties)

Each element in the matrix contains:

- `originIndex` - Index of the origin (0-based)
- `destinationIndex` - Index of the destination (0-based)
- `distanceMeters` - Distance in meters
- `duration` - Duration string (e.g., "1234s")
- `condition` - Route condition (ROUTE\_EXISTS, ROUTE\_NOT\_FOUND)

Helper methods:

- `routeExists()` - Check if a route was found
- `getDurationInSeconds()` - Get duration as integer
- `getDistanceInKilometers()` - Get distance in km
- `getDistanceInMiles()` - Get distance in miles
- `getFormattedDuration()` - Get human-readable duration

### Real-World Example: Courier Pickup &amp; Delivery

[](#real-world-example-courier-pickup--delivery)

A courier needs to pick up packages from multiple stores and deliver to customers (some packages share the same destination):

```
use Gowelle\LaravelRouteMatrix\Facades\GoogleRoutes;

// Courier's current location (Dar es Salaam - Posta)
$courierLocation = ['lat' => -6.8160, 'lng' => 39.2803];

// Stores to pickup from
$stores = [
    ['id' => 'store_1', 'name' => 'Kariakoo Market', 'lat' => -6.8235, 'lng' => 39.2695],
    ['id' => 'store_2', 'name' => 'Mlimani City Mall', 'lat' => -6.7724, 'lng' => 39.2083],
    ['id' => 'store_3', 'name' => 'Slipway Shopping', 'lat' => -6.7488, 'lng' => 39.2656],
];

// Packages with destinations (some share same customer)
$packages = [
    ['id' => 'pkg_1', 'store_id' => 'store_1', 'customer' => 'Masaki Customer', 'lat' => -6.7567, 'lng' => 39.2772],
    ['id' => 'pkg_2', 'store_id' => 'store_2', 'customer' => 'Masaki Customer', 'lat' => -6.7567, 'lng' => 39.2772],
    ['id' => 'pkg_3', 'store_id' => 'store_2', 'customer' => 'Mikocheni Customer', 'lat' => -6.7651, 'lng' => 39.2451],
    ['id' => 'pkg_4', 'store_id' => 'store_3', 'customer' => 'Kinondoni Customer', 'lat' => -6.7735, 'lng' => 39.2401],
];

// Get unique destinations (consolidate packages to same location)
$uniqueDestinations = collect($packages)
    ->unique(fn($pkg) => $pkg['lat'] . ',' . $pkg['lng'])
    ->values()
    ->all();

// STEP 1: Find optimal pickup order
$pickupRoute = GoogleRoutes::from($courierLocation);
foreach ($stores as $store) {
    $pickupRoute->via(['lat' => $store['lat'], 'lng' => $store['lng']]);
}

$lastStore = end($stores);
$response = $pickupRoute
    ->to(['lat' => $lastStore['lat'], 'lng' => $lastStore['lng']])
    ->optimizeWaypointOrder()
    ->driving()
    ->withTraffic()
    ->get();

$optimizedOrder = $response->first()->optimizedIntermediateWaypointIndex ?? [];
echo "Pickup order: " . implode(' → ', array_map(fn($i) => $stores[$i]['name'], $optimizedOrder));

// STEP 2: Calculate delivery matrix from last pickup
$deliveryMatrix = GoogleRoutes::matrix()
    ->addOrigin(['lat' => $lastStore['lat'], 'lng' => $lastStore['lng']])
    ->driving()
    ->withTraffic();

foreach ($uniqueDestinations as $dest) {
    $deliveryMatrix->addDestination(['lat' => $dest['lat'], 'lng' => $dest['lng']]);
}

$matrixResponse = $deliveryMatrix->get();

// Find closest delivery from last pickup
$firstDelivery = $matrixResponse->getClosestDestination(0);
echo "First delivery: {$uniqueDestinations[$firstDelivery->destinationIndex]['customer']}";
echo "ETA: {$firstDelivery->getFormattedDuration()}";

// STEP 3: Build full optimized route (pickups + deliveries)
$allStops = array_merge(
    array_map(fn($s) => ['lat' => $s['lat'], 'lng' => $s['lng'], 'type' => 'pickup', 'name' => $s['name']], $stores),
    array_map(fn($d) => ['lat' => $d['lat'], 'lng' => $d['lng'], 'type' => 'delivery', 'name' => $d['customer']], $uniqueDestinations)
);

$fullRoute = GoogleRoutes::from($courierLocation);
foreach ($allStops as $stop) {
    $fullRoute->via(['lat' => $stop['lat'], 'lng' => $stop['lng']]);
}

$optimizedResponse = $fullRoute
    ->to($courierLocation) // Return to base
    ->optimizeWaypointOrder()
    ->driving()
    ->withTraffic()
    ->get();

$route = $optimizedResponse->first();
echo "Total distance: {$route->getDistanceInKilometers()} km";
echo "Total time: {$route->getFormattedDuration()}";

// Display optimized route
$finalOrder = $route->optimizedIntermediateWaypointIndex ?? [];
foreach ($finalOrder as $index => $stopIndex) {
    $stop = $allStops[$stopIndex];
    $icon = $stop['type'] === 'pickup' ? '📦' : '🚚';
    echo ($index + 1) . ". {$icon} {$stop['name']}";
}
```

**Output:**

```
Pickup order: Kariakoo Market → Mlimani City Mall → Slipway Shopping

First delivery: Masaki Customer
ETA: 12 min

Total distance: 32.4 km
Total time: 1h 8m

1. 📦 Kariakoo Market
2. 📦 Mlimani City Mall
3. 🚚 Mikocheni Customer
4. 🚚 Kinondoni Customer
5. 📦 Slipway Shopping
6. 🚚 Masaki Customer (2 packages)

```

Response Objects
----------------

[](#response-objects)

### RoutesResponse

[](#routesresponse)

The main response object containing:

- `routes` - Collection of Route objects
- `fallbackInfo` - Information about routing fallback (if any)
- `geocodingResults` - Geocoding information for address waypoints

### Route

[](#route)

Individual route containing:

- `distanceMeters` - Total distance in meters
- `duration` - Duration string (e.g., "165s")
- `polyline` - Encoded polyline or GeoJSON
- `legs` - Collection of RouteLeg objects
- `viewport` - Map bounding box
- `routeLabels` - Route type labels
- `warnings` - Route warnings

Helper methods:

- `getDurationInSeconds()` - Get duration as integer
- `getDistanceInKilometers()` - Get distance in km
- `getDistanceInMiles()` - Get distance in miles
- `getFormattedDuration()` - Get human-readable duration
- `isDefaultRoute()` - Check if default route
- `isFuelEfficient()` - Check if fuel-efficient route

Configuration
-------------

[](#configuration)

The configuration file (`config/google-routes.php`) includes:

```
return [
    'api_key' => env('GOOGLE_ROUTES_API_KEY'),
    'base_url' => env('GOOGLE_ROUTES_BASE_URL', 'https://routes.googleapis.com'),
    'timeout' => env('GOOGLE_ROUTES_TIMEOUT', 30),
    'defaults' => [
        'travel_mode' => env('GOOGLE_ROUTES_TRAVEL_MODE', 'DRIVE'),
        'language_code' => env('GOOGLE_ROUTES_LANGUAGE', 'en-US'),
        'units' => env('GOOGLE_ROUTES_UNITS', 'METRIC'),
        'routing_preference' => env('GOOGLE_ROUTES_ROUTING_PREFERENCE', 'TRAFFIC_AWARE'),
    ],
    'default_field_mask' => [
        'routes.duration',
        'routes.distanceMeters',
        'routes.polyline.encodedPolyline',
    ],

    /*
    |--------------------------------------------------------------------------
    | Response Caching
    |--------------------------------------------------------------------------
    |
    | Configure response caching to reduce API costs and improve performance.
    |
    */
    'cache' => [
        'enabled' => env('GOOGLE_ROUTES_CACHE_ENABLED', false),
        'store' => env('GOOGLE_ROUTES_CACHE_STORE', null),
        'ttl' => env('GOOGLE_ROUTES_CACHE_TTL', 3600),
    ],
];
```

Exception Handling
------------------

[](#exception-handling)

The package throws specific exceptions:

```
use Gowelle\LaravelRouteMatrix\Exceptions\GoogleRoutesException;
use Gowelle\LaravelRouteMatrix\Exceptions\InvalidApiKeyException;
use Gowelle\LaravelRouteMatrix\Exceptions\InvalidRequestException;
use Gowelle\LaravelRouteMatrix\Exceptions\NoRouteFoundException;

try {
    $response = GoogleRoutes::from($origin)
        ->to($destination)
        ->get();
} catch (InvalidApiKeyException $e) {
    // API key is missing or invalid
} catch (InvalidRequestException $e) {
    // Request parameters are invalid
} catch (NoRouteFoundException $e) {
    // No route could be found
} catch (GoogleRoutesException $e) {
    // Other API errors
}
```

Testing
-------

[](#testing)

Run the test suite:

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security-related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Gowelle](https://github.com/gowelle)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance80

Actively maintained with recent releases

Popularity19

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~17 days

Total

5

Last Release

104d ago

Major Versions

v1.2.0 → v2.0.02026-03-21

PHP version history (2 changes)v1.1.0PHP ^8.2

v2.0.0PHP ^8.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/87917924?v=4)[Gowelle John](/maintainers/gowelle)[@gowelle](https://github.com/gowelle)

---

Top Contributors

[![gowelle](https://avatars.githubusercontent.com/u/87917924?v=4)](https://github.com/gowelle "gowelle (24 commits)")

---

Tags

apilaravelroutesgooglemapsdirectionscompute-routes

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/gowelle-laravel-route-matrix/health.svg)

```
[![Health](https://phpackages.com/badges/gowelle-laravel-route-matrix/health.svg)](https://phpackages.com/packages/gowelle-laravel-route-matrix)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M345](/packages/psalm-plugin-laravel)[laravel/socialite

Laravel wrapper around OAuth 1 &amp; OAuth 2 libraries.

5.7k108.5M885](/packages/laravel-socialite)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5021.9k](/packages/simplestats-io-laravel-client)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

816333.6k3](/packages/defstudio-telegraph)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M131](/packages/roots-acorn)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
