PHPackages                             tarfin-labs/laravel-spatial - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. tarfin-labs/laravel-spatial

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

tarfin-labs/laravel-spatial
===========================

Laravel package to work with geospatial data types and functions.

3.2.0(2mo ago)75103.1k↓54.5%21[7 issues](https://github.com/tarfin-labs/laravel-spatial/issues)[2 PRs](https://github.com/tarfin-labs/laravel-spatial/pulls)MITPHPPHP ^8.2|^8.3|^8.4|^8.5CI passing

Since Jan 18Pushed 2mo ago5 watchersCompare

[ Source](https://github.com/tarfin-labs/laravel-spatial)[ Packagist](https://packagist.org/packages/tarfin-labs/laravel-spatial)[ Docs](https://github.com/tarfin-labs/laravel-spatial)[ RSS](/packages/tarfin-labs-laravel-spatial/feed)WikiDiscussions main Synced 4d ago

READMEChangelog (10)Dependencies (8)Versions (43)Used By (0)

Laravel Spatial
===============

[](#laravel-spatial)

[![Latest Version on Packagist](https://camo.githubusercontent.com/9bbdd6bdcfbfef07def2bbc50165fe3c3742a5063661b940869b7eeedb74fb87/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f74617266696e2d6c6162732f6c61726176656c2d7370617469616c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tarfin-labs/laravel-spatial)[![Total Downloads](https://camo.githubusercontent.com/caee0d71b0e3858f65e19dd6adce5f5ee75eb262c15dd6dcdc0771072eb71bf5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f74617266696e2d6c6162732f6c61726176656c2d7370617469616c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tarfin-labs/laravel-spatial)[![GitHub Actions](https://github.com/tarfin-labs/laravel-spatial/actions/workflows/main.yml/badge.svg)](https://github.com/tarfin-labs/laravel-spatial/actions/workflows/main.yml/badge.svg)

This is a Laravel package to work with geospatial data types and functions.

It supports only MySQL Spatial Data Types and Functions, other RDBMS is on the roadmap.

### Laravel Compatibility

[](#laravel-compatibility)

VersionSupported Laravel Versions`3.x``^11.0`, `^12.0`, `^13.0``2.x``^8.0, ^9.0, ^10.0`**Supported data types:**

- `Point`

**Available Scopes:**

- `withinDistanceTo($column, $coordinates, $distance)`
- `selectDistanceTo($column, $coordinates)`
- `orderByDistanceTo($column, $coordinates, 'asc')`

---

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

[](#installation)

You can install the package via composer:

```
composer require tarfin-labs/laravel-spatial
```

Usage
-----

[](#usage)

Generate a new model with a migration file:

```
php artisan make:model Address --migration
```

### 1- Migrations:

[](#1--migrations)

```
### For Laravel 11 and Above Versions

From Laravel 11 onwards, migrations are created as follows:

```php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {

    public function up(): void
    {
        Schema::create('addresses', function (Blueprint $table) {
            $table->geography('location', subtype: 'point');
        })
    }

}

```

In Laravel 11, the methods **point**, **lineString**, **polygon**, **geometryCollection**, **multiPoint**, **multiLineString**, and **multiPolygon** have been removed. Therefore, we are updating to use the **geography** method instead. The `geography` method sets the default SRID value to 4326.

#### Issue with adding a new location column with index to an existing table:

[](#issue-with-adding-a-new-location-column-with-index-to-an-existing-table)

When adding a new location column with an index in Laravel, it can be troublesome if you have existing data. One common mistake is trying to set a default value for the new column using `->default(new Point(0, 0, 4326))`. However, `POINT` columns cannot have a default value, which can cause issues when trying to add an index to the column, as indexed columns cannot be nullable.

To solve this problem, it is recommended to perform a two-step migration like following:

### For Laravel 11 and Above Versions

[](#for-laravel-11-and-above-versions)

```
public function up()
{
    // Add the new location column as nullable
    Schema::table('table', function (Blueprint $table) {
        $table->geography('location', 'point')->nullable();
    });

    // In the second go, set 0,0 values, make the column not null and finally add the spatial index
    Schema::table('table', function (Blueprint $table) {
        DB::statement("UPDATE `addresses` SET `location` = ST_GeomFromText('POINT(0 0)', 4326);");

        DB::statement("ALTER TABLE `table` CHANGE `location` `location` POINT NOT NULL;");

        $table->spatialIndex('location');
    });
}
```

---

### 2- Models:

[](#2--models)

Fill the `$fillable`, `$casts` arrays in the model:

```
use Illuminate\Database\Eloquent\Model;
use TarfinLabs\LaravelSpatial\Casts\LocationCast;
use TarfinLabs\LaravelSpatial\Traits\HasSpatial;

class Address extends Model {

    use HasSpatial;

    protected $fillable = [
        'id',
        'name',
        'address',
        'location',
    ];

    protected array $casts = [
        'location' => LocationCast::class
    ];

}
```

### 3- Spatial Data Types:

[](#3--spatial-data-types)

#### ***Point:***

[](#point)

`Point` represents the coordinates of a location and contains `latitude`, `longitude`, and `srid` properties.

At this point, it is crucial to understand what SRID is. Each spatial instance has a spatial reference identifier (SRID). The SRID corresponds to a spatial reference system based on the specific ellipsoid used for either flat-earth mapping or round-earth mapping. A spatial column can contain objects with different SRIDs.

> For details about SRID you can follow the link: [https://en.wikipedia.org/wiki/Spatial\_reference\_system](https://en.wikipedia.org/wiki/Spatial_reference_system)

- Default value of `latitude`, `longitude` parameters is `0.0`.
- Default value of `srid` parameter is `0`.

```
use TarfinLabs\LaravelSpatial\Types\Point;

$location = new Point(lat: 28.123456, lng: 39.123456, srid: 4326);

$location->getLat(); // 28.123456
$location->getLng(); // 39.123456
$location->getSrid(); // 4326
```

You can override the default SRID via the `laravel-spatial` config file. To do that, you should publish the config file using `vendor:publish` artisan command:

```
php artisan vendor:publish --provider="TarfinLabs\LaravelSpatial\LaravelSpatialServiceProvider"
```

After that, you can change the value of `default_srid` in `config/laravel-spatial.php`

```
return [
    'default_srid' => 4326,
];
```

---

#### Configuring WKT options

[](#configuring-wkt-options)

By default, this package uses the `longitude latitude` order for the coordinate values in the WKT format used by spatial functions. This is necessary for some versions of MySQL, which will interpret coordinate pairs as lat-long unless the `axis-order` option is explicitly set to `long-lat`.

However, MariaDB reads WKT values as `long-lat` by default, and its spatial functions like `ST_GeomFromText` and `ST_DISTANCE` do not accept an `options` parameter like their MySQL counterparts. This means that using the package with MariaDB will result in a `Syntax error or access violation: 1582 Incorrect parameter count in the call to native function 'ST_GeomFromText'` exception.

To address this issue, we have added a `with_wkt_options` parameter to the config file that can be used to override the default options. This property can be set to `false` to remove the options parameter entirely, which fixes the errors when using MariaDB.

```
return [
    'with_wkt_options' => true,
];
```

---

#### Bulk Operations

[](#bulk-operations)

In order to insert or update several rows with spatial data in one query using the `upsert()` method in Laravel, the package requires a workaround solution to avoid the error `Object of class TarfinLabs\LaravelSpatial\Types\Point could not be converted to string`.

The solution is to use the `toGeomFromText()` method to convert the `Point` object to a WKT string, and then use `DB::raw()` to create a raw query string.

Here's an example of how to use this workaround in your code:

```
use TarfinLabs\LaravelSpatial\Types\Point;

$points = [
    ['external_id' => 5, 'location' => DB::raw((new Point(lat: 40.73, lng: -73.93))->toGeomFromText())],
    ['external_id' => 7, 'location' => DB::raw((new Point(lat: -37.81, lng: 144.96))->toGeomFromText())],
];

Property::upsert($points, ['external_id'], ['location']);
```

---

### 4- Scopes:

[](#4--scopes)

#### ***withinDistanceTo()***

[](#withindistanceto)

You can use the `withinDistanceTo()` scope to filter locations by given distance:

To filter addresses within the range of 10 km from the given coordinate:

```
use TarfinLabs\LaravelSpatial\Types\Point;
use App\Models\Address;

Address::query()
       ->withinDistanceTo('location', new Point(lat: 25.45634, lng: 35.54331), 10000)
       ->get();
```

#### ***selectDistanceTo()***

[](#selectdistanceto)

You can get the distance between two points by using `selectDistanceTo()` scope. The distance will be in meters:

```
use TarfinLabs\LaravelSpatial\Types\Point;
use App\Models\Address;

Address::query()
       ->selectDistanceTo('location', new Point(lat: 25.45634, lng: 35.54331))
       ->get();
```

#### ***orderByDistanceTo()***

[](#orderbydistanceto)

You can order your models by distance to given coordinates:

```
use TarfinLabs\LaravelSpatial\Types\Point;
use App\Models\Address;

// ASC
Address::query()
       ->orderByDistanceTo('location', new Point(lat: 25.45634, lng: 35.54331))
       ->get();

// DESC
Address::query()
       ->orderByDistanceTo('location', new Point(lat: 25.45634, lng: 35.54331), 'desc')
       ->get();
```

#### Get latitude and longitude of the location:

[](#get-latitude-and-longitude-of-the-location)

```
use App\Models\Address;

$address = Address::find(1);
$address->location; // TarfinLabs\LaravelSpatial\Types\Point

$address->location->getLat();
$address->location->getLng();
```

#### Create a new address with location:

[](#create-a-new-address-with-location)

```
use App\Models\Address;

Address::create([
    'name'      => 'Bag End',
    'address'   => '1 Bagshot Row, Hobbiton, Shire',
    'location'  => new Point(lat: 25.45634, lng: 35.54331),
]);
```

#### Usage in Resource:

[](#usage-in-resource)

To get an array representation of a location-casted field from a resource, you can return `parent::toArray($request)`.

If you need to return a custom array from a resource, you can use the `toArray()` method of the `Point` object.

```
class LocationResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'location' => $this->location->toArray(),
        ];
    }
}
```

Either way, you will get the following output for the location casted field:

```
{
    "lat": 25.45634,
    "lng": 35.54331,
    "srid": 4326
}
```

### Testing

[](#testing)

```
composer test
```

### Changelog

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information 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)

- [Turan Karatug](https://github.com/tarfin-labs)
- [All Contributors](../../contributors)

License
-------

[](#license)

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

###  Health Score

62

—

FairBetter than 99% of packages

Maintenance81

Actively maintained with recent releases

Popularity48

Moderate usage in the ecosystem

Community19

Small or concentrated contributor base

Maturity80

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 72.3% 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 ~77 days

Recently: every ~82 days

Total

21

Last Release

88d ago

Major Versions

v1.7.0 → v2.0.02024-04-09

v2.2.0 → v3.1.02025-05-14

2.x-dev → 3.2.02026-04-08

PHP version history (6 changes)v1.0.0PHP ^8.0

v1.2.0PHP ^8.0|^8.1

v1.7.0PHP ^8.0|^8.1|^8.2

v2.0.0PHP ^8.0|^8.1|^8.2|^8.3

v2.1.0PHP ^8.2|^8.3|^8.4

3.2.0PHP ^8.2|^8.3|^8.4|^8.5

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/4394344?v=4)[Turan Karatuğ](/maintainers/tkaratug)[@tkaratug](https://github.com/tkaratug)

---

Top Contributors

[![tkaratug](https://avatars.githubusercontent.com/u/4394344?v=4)](https://github.com/tkaratug "tkaratug (102 commits)")[![frkcn](https://avatars.githubusercontent.com/u/374634?v=4)](https://github.com/frkcn "frkcn (16 commits)")[![YunusEmreNalbant](https://avatars.githubusercontent.com/u/29780061?v=4)](https://github.com/YunusEmreNalbant "YunusEmreNalbant (13 commits)")[![deligoez](https://avatars.githubusercontent.com/u/3030815?v=4)](https://github.com/deligoez "deligoez (6 commits)")[![boryn](https://avatars.githubusercontent.com/u/807297?v=4)](https://github.com/boryn "boryn (4 commits)")

---

Tags

tarfin-labslaravel-spatial

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/tarfin-labs-laravel-spatial/health.svg)

```
[![Health](https://phpackages.com/badges/tarfin-labs-laravel-spatial/health.svg)](https://phpackages.com/packages/tarfin-labs-laravel-spatial)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[illuminate/pagination

The Illuminate Pagination package.

12234.1M1.0k](/packages/illuminate-pagination)[illuminate/pipeline

The Illuminate Pipeline package.

9349.2M282](/packages/illuminate-pipeline)[illuminate/redis

The Illuminate Redis package.

8314.6M377](/packages/illuminate-redis)[illuminate/cookie

The Illuminate Cookie package.

244.6M137](/packages/illuminate-cookie)

PHPackages © 2026

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