---
title: "Coordinates, queries & enums — Geolocation for Laravel | Roundly"
description: "The validated Coordinates value object, Haversine distance, the GeolocationQuery and DistanceQuery named constructors, and both enums."
url: https://roundly-consulting.com/open-source/docs/geolocation-for-laravel/coordinates
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Geolocation for Laravel](https://roundly-consulting.com/open-source/docs/geolocation-for-laravel.md)

# Coordinates, queries & enums

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

```php
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:

```php
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:

```php
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](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## 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.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/geolocation-for-laravel.md)
