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

Coordinates, queries & enums

Coordinates is an immutable value object that validates its range on construction and computes great-circle distance:

use RoundlyConsulting\Geolocation\DataTransferObjects\Coordinates;

$here = new Coordinates(48.1486, 17.1077);   // validates lat ∈ [-90,90], lng ∈ [-180,180]
$same = Coordinates::make(48.1486, 17.1077); // static constructor, same validation

$metres = $here->distanceTo(new Coordinates(50.0755, 14.4378)); // Haversine, ≈ 290 km

$here->latitude;    // 48.1486
$here->toArray();   // ['latitude' => 48.1486, 'longitude' => 17.1077]

new Coordinates(91.0, 17.1077); // throws InvalidCoordinatesException

Queries

GeolocationQuery has forIp(), forAddress() and forCoordinates(); DistanceQuery has between(), with Driving as the default travel mode:

use RoundlyConsulting\Geolocation\DataTransferObjects\DistanceQuery;
use RoundlyConsulting\Geolocation\DataTransferObjects\GeolocationQuery;
use RoundlyConsulting\Geolocation\Enum\DistanceType;

$query = GeolocationQuery::forCoordinates($here);
$query->coordinates();   // ?Coordinates — null for IP and address queries
$query->ipAddress;       // ?string
$query->address;         // ?string

$trip = DistanceQuery::between(from: $here, to: $there, type: DistanceType::Walking);
$trip->from();           // Coordinates
$trip->to();             // Coordinates

// Positional constructors work too:
new GeolocationQuery('203.0.113.7');
new DistanceQuery(48.1, 17.1, 50.0, 14.4, DistanceType::Driving);

Enums

DistanceType (Walking, Driving) and GeolocationType (Default, IP, Geolocation) are string-backed and use the Helpers trait from enums-for-laravel, so values(), labels(), options() / toOptions(), validationRule(), tryFromName(), is() / isIn() and the when* guards come for free:

use RoundlyConsulting\Geolocation\Enum\DistanceType;
use RoundlyConsulting\Geolocation\Enum\GeolocationType;

DistanceType::values()->all();        // ['Walking', 'Driving']
DistanceType::validationRule();       // 'in:Walking,Driving'
DistanceType::toOptions()->all();     // ['Walking' => 'Walking', 'Driving' => 'Driving'] — ready for <select>
DistanceType::tryFromName('Driving'); // DistanceType::Driving

GeolocationType::values()->all();     // ['Default', 'IP', 'Geolocation']
GeolocationType::Ip->value;           // 'IP' (wire value is preserved)
GeolocationType::Ip->readable();      // 'IP'

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.