NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Geolocation for Laravel

Distance & matrix

distance() walks the pipeline for a DistanceProvider — Google, out of the box — and returns a Distance, or null when no provider can resolve the query (an unreachable provider is skipped):

use RoundlyConsulting\Geolocation\DataTransferObjects\Coordinates;
use RoundlyConsulting\Geolocation\DataTransferObjects\DistanceQuery;
use RoundlyConsulting\Geolocation\Enum\DistanceType;
use RoundlyConsulting\Geolocation\Facades\Geolocation;

$distance = Geolocation::distance(
    DistanceQuery::between(
        from: new Coordinates(48.1482, 17.1067),
        to:   new Coordinates(49.2000, 16.6068),
        type: DistanceType::Driving,
    ),
);

$distance?->humanReadableDistance; // "133 km"
$distance?->distanceInMeters;      // 133000
$distance?->durationInSeconds;     // 5400
// Skip the query object — distanceBetween() builds it for you (driving by default)
$distance = Geolocation::distanceBetween(
    new Coordinates(48.1482, 17.1067),
    new Coordinates(49.2000, 16.6068),
    DistanceType::Walking,
);

The Distance object

PropertyTypeContents
humanReadableDistancestringProvider-formatted distance, e.g. “133 km”.
distanceInMetersintDistance in metres.
humanReadableDurationstringProvider-formatted travel time.
durationInSecondsintTravel time in seconds.
typeDistanceTypeWalking or Driving.

Travel mode from user input

DistanceType’s validationRule() makes the travel mode safe to accept from a form:

$data = $request->validate([
    'mode' => ['required', DistanceType::validationRule()],   // 'in:Walking,Driving'
]);

$distance = Geolocation::distance(DistanceQuery::between(
    from: new Coordinates(48.1482, 17.1067),
    to: new Coordinates(48.1486, 17.1077),
    type: DistanceType::from($data['mode']),
));

$distance?->humanReadableDuration; // e.g. "6 mins"

Distance matrix

Resolve a grid of distances between several origins and destinations in one Distance Matrix call. Unavailable legs degrade to null, and so does every cell when Google can’t be reached:

use RoundlyConsulting\Geolocation\DataTransferObjects\Coordinates;
use RoundlyConsulting\Geolocation\Enum\DistanceType;

$matrix = Geolocation::distanceMatrix(
    origins: [new Coordinates(48.14, 17.10)],
    destinations: [new Coordinates(49.20, 16.60), new Coordinates(50.07, 14.43)],
    type: DistanceType::Driving,   // optional — Driving is the default
);

$matrix->get(0, 1)?->distanceInMeters;   // origin 0 → destination 1, null when that leg is unavailable
$matrix->origins;                        // list<Coordinates>
$matrix->rows;                           // array<int, array<int, Distance|null>>

The matrix comes from the bundled Google provider. If Google isn’t in the (scoped) pipeline, or the request fails, you get an empty grid where every get() returns null. Matrices are not cached and dispatch no events.

For a straight-line distance without any API call, use Coordinates::distanceTo().

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.