PHPackages                             matanyadaev/laravel-eloquent-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. [Database &amp; ORM](/categories/database)
4. /
5. matanyadaev/laravel-eloquent-spatial

ActiveLibrary[Database &amp; ORM](/categories/database)

matanyadaev/laravel-eloquent-spatial
====================================

Spatial library for Laravel

4.8.0(3w ago)4103.5M↓29.3%52[3 issues](https://github.com/MatanYadaev/laravel-eloquent-spatial/issues)11MITPHPPHP ^8.1CI passing

Since Feb 23Pushed 3w ago4 watchersCompare

[ Source](https://github.com/MatanYadaev/laravel-eloquent-spatial)[ Packagist](https://packagist.org/packages/matanyadaev/laravel-eloquent-spatial)[ Docs](https://github.com/matanyadaev/laravel-eloquent-spatial)[ RSS](/packages/matanyadaev-laravel-eloquent-spatial/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (10)Dependencies (25)Versions (48)Used By (11)

Laravel Eloquent Spatial
========================

[](#laravel-eloquent-spatial)

[![Latest Version on Packagist](https://camo.githubusercontent.com/fcb4033b6a50bfdbfab2a55f9525fa9a596cef7774bcce9a5b45e42921a0f8b3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6174616e7961646165762f6c61726176656c2d656c6f7175656e742d7370617469616c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/matanyadaev/laravel-eloquent-spatial)[![Tests](https://github.com/matanyadaev/laravel-eloquent-spatial/actions/workflows/pest.yml/badge.svg)](https://github.com/matanyadaev/laravel-eloquent-spatial/actions/workflows/pest.yml/badge.svg)[![Static code analysis](https://github.com/matanyadaev/laravel-eloquent-spatial/actions/workflows/phpstan.yml/badge.svg)](https://github.com/matanyadaev/laravel-eloquent-spatial/actions/workflows/phpstan.yml/badge.svg)[![Lint](https://github.com/matanyadaev/laravel-eloquent-spatial/actions/workflows/pint.yml/badge.svg)](https://github.com/matanyadaev/laravel-eloquent-spatial/actions/workflows/pint.yml/badge.svg)[![Total Downloads](https://camo.githubusercontent.com/cf480f9f918a93034e310fb025fdf388ee30464c61cdf5e9a1751cae9ea4f88e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6174616e7961646165762f6c61726176656c2d656c6f7175656e742d7370617469616c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/matanyadaev/laravel-eloquent-spatial)

**This package allows you to easily work with spatial data types and functions in Laravel and standalone Eloquent projects.**

Supported databases:

- MySQL 8.4
- MariaDB 10.11
- Postgres 14/15/16/17/18 with PostGIS 3.4/3.5/3.6

Getting Started
---------------

[](#getting-started)

### Installing the Package

[](#installing-the-package)

You can install the package via composer:

```
composer require matanyadaev/laravel-eloquent-spatial
```

### Setting Up Your First Model

[](#setting-up-your-first-model)

1. First, generate a new model along with a migration file by running:

    ```
    php artisan make:model {modelName} --migration
    ```
2. Next, add some spatial columns to the migration file. For instance, to create a "places" table:

    ```
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;

    class CreatePlacesTable extends Migration
    {
        public function up(): void
        {
            Schema::create('places', static function (Blueprint $table) {
                $table->id();
                $table->string('name')->unique();
                $table->geometry('location', subtype: 'point')->nullable();
                $table->geometry('area', subtype: 'polygon')->nullable();
                $table->timestamps();
            });
        }

        public function down(): void
        {
            Schema::dropIfExists('places');
        }
    }
    ```
3. Run the migration:

    ```
    php artisan migrate
    ```
4. In your new model, fill the `$fillable` and `$casts` arrays and use the `HasSpatial` trait:

    ```
    namespace App\Models;

    use Illuminate\Database\Eloquent\Model;
    use MatanYadaev\EloquentSpatial\Objects\Point;
    use MatanYadaev\EloquentSpatial\Objects\Polygon;
    use MatanYadaev\EloquentSpatial\Traits\HasSpatial;

    /**
     * @property Point $location
     * @property Polygon $area
     */
    class Place extends Model
    {
        use HasSpatial;

        protected $fillable = [
            'name',
            'location',
            'area',
        ];

        protected $casts = [
            'location' => Point::class,
            'area' => Polygon::class,
        ];
    }
    ```

### Interacting with Spatial Data

[](#interacting-with-spatial-data)

After setting up your model, you can now create and access spatial data. Here's an example:

```
use App\Models\Place;
use MatanYadaev\EloquentSpatial\Objects\Polygon;
use MatanYadaev\EloquentSpatial\Objects\LineString;
use MatanYadaev\EloquentSpatial\Objects\Point;
use MatanYadaev\EloquentSpatial\Enums\Srid;

// Create new records

$londonEye = Place::create([
    'name' => 'London Eye',
    'location' => new Point(51.5032973, -0.1217424),
]);

$whiteHouse = Place::create([
    'name' => 'White House',
    'location' => new Point(38.8976763, -77.0365298, Srid::WGS84->value), // with SRID
]);

$vaticanCity = Place::create([
    'name' => 'Vatican City',
    'area' => new Polygon([
        new LineString([
              new Point(12.455363273620605, 41.90746728266806),
              new Point(12.450309991836548, 41.906636872349075),
              new Point(12.445632219314575, 41.90197359839437),
              new Point(12.447413206100464, 41.90027269624499),
              new Point(12.457906007766724, 41.90000118654431),
              new Point(12.458517551422117, 41.90281205461268),
              new Point(12.457584142684937, 41.903107507989986),
              new Point(12.457734346389769, 41.905918239316286),
              new Point(12.45572805404663, 41.90637337450963),
              new Point(12.455363273620605, 41.90746728266806),
        ]),
    ]),
])

// Access the data

echo $londonEye->location->latitude; // 51.5032973
echo $londonEye->location->longitude; // -0.1217424

echo $whiteHouse->location->srid; // 4326

echo $vacationCity->area->toJson(); // {"type":"Polygon","coordinates":[[[41.90746728266806,12.455363273620605],[41.906636872349075,12.450309991836548],[41.90197359839437,12.445632219314575],[41.90027269624499,12.447413206100464],[41.90000118654431,12.457906007766724],[41.90281205461268,12.458517551422117],[41.903107507989986,12.457584142684937],[41.905918239316286,12.457734346389769],[41.90637337450963,12.45572805404663],[41.90746728266806,12.455363273620605]]]}
```

### Standalone Eloquent Usage (without Laravel)

[](#standalone-eloquent-usage-without-laravel)

This package also works in projects that use Eloquent on its own, without the full Laravel framework.

Just boot Eloquent — for example, with `Illuminate\Database\Capsule\Manager` — and the spatial casts, scopes, and objects are ready to use:

```
use Illuminate\Database\Capsule\Manager as Capsule;

$capsule = new Capsule;
$capsule->addConnection([
    // your database configuration
]);
$capsule->bootEloquent();
```

From there, models, casts, and query scopes behave exactly as in the examples above.

Further Reading
---------------

[](#further-reading)

For more comprehensive documentation on the API, please refer to the [API](API.md) page.

Extension
---------

[](#extension)

### Extend Geometry class with macros

[](#extend-geometry-class-with-macros)

You can add new methods to the `Geometry` class through macros.

Here's an example of how to register a macro in your service provider's `boot` method:

```
class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Geometry::macro('getName', function (): string {
            /** @var Geometry $this */
            return class_basename($this);
        });
    }
}
```

Use the method in your code:

```
$londonEyePoint = new Point(51.5032973, -0.1217424);

echo $londonEyePoint->getName(); // Point
```

### Extend with custom geometry classes

[](#extend-with-custom-geometry-classes)

You can extend the geometry classes by creating custom geometry classes and add functionality. You can also override existing methods, although it is not recommended, as it may lead to unexpected behavior.

1. Create a custom geometry class that extends the base geometry class.

```
use MatanYadaev\EloquentSpatial\Objects\Point;

class ExtendedPoint extends Point
{
    public function toCustomArray(): array
    {
        return 'coordinates' => [
            'latitude' => $this->latitude,
            'longitude' => $this->longitude
        ]
    }
}
```

2. Update the geometry class mapping in a service provider file.

```
use App\ValueObjects\ExtendedPoint;
use Illuminate\Support\ServiceProvider;
use MatanYadaev\EloquentSpatial\EloquentSpatial;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        EloquentSpatial::usePoint(ExtendedPoint::class);
    }
}
```

3. Update your model to use the custom geometry class in the `$casts` property or `casts()` method.

```
use App\ValueObjects\ExtendedPoint;
use Illuminate\Database\Eloquent\Model;
use MatanYadaev\EloquentSpatial\Traits\HasSpatial;

class Place extends Model
{
    use HasSpatial;

    protected $casts = [
        'coordinates' => ExtendedPoint::class,
    ];

    // Or:

    protected function casts(): array
    {
        return [
            'coordinates' => ExtendedPoint::class,
        ];
    }
}
```

4. Use the custom geometry class in your code.

```
use App\Models\Location;
use App\ValueObjects\ExtendedPoint;

$place = Place::create([
    'name' => 'London Eye',
    'coordinates' => new ExtendedPoint(51.5032973, -0.1217424),
]);

echo $place->coordinates->toCustomArray(); // ['longitude' => -0.1217424, 'latitude' => 51.5032973]
```

Set default SRID
----------------

[](#set-default-srid)

By default, the SRID is set to 0 (EPSG:0). You can set the default SRID for your application by setting the `SRID` constant in a service provider's `boot` method:

```
use MatanYadaev\EloquentSpatial\Enums\Srid;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        // Set the default SRID to WGS84 (EPSG:4326)
        EloquentSpatial::setDefaultSrid(Srid::WGS84);
    }
}
```

Development
-----------

[](#development)

Here are some useful commands for development:

- Run tests: `composer pest:mysql`, `composer pest:mariadb`, `composer pest:postgres`
- Run tests with coverage: `composer pest-coverage:mysql`
- Perform type checking: `composer phpstan`
- Perform code formatting: `composer pint`

Before running tests, make sure to run `docker-compose up` to start the database container.

Updates and Changes
-------------------

[](#updates-and-changes)

For details on updates and changes, please refer to our [CHANGELOG](CHANGELOG.md).

License
-------

[](#license)

Laravel Eloquent Spatial is released under The MIT License (MIT). For more information, please see our [License File](LICENSE.md).

###  Health Score

71

—

ExcellentBetter than 100% of packages

Maintenance94

Actively maintained with recent releases

Popularity64

Solid adoption and visibility

Community36

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 92.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 ~46 days

Recently: every ~116 days

Total

43

Last Release

26d ago

Major Versions

1.0.4 → 2.0.02022-07-08

2.10.0 → 3.0.02023-02-03

2.10.1 → 3.2.02023-06-25

3.2.2 → 4.0.02024-01-18

PHP version history (2 changes)1.0.0PHP ^8.0

3.0.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/0615d9b6f53bf93a07af72cd5d7829f4fd73ccf055d7ddaa522477138f30cd60?d=identicon)[MatanYadaev](/maintainers/MatanYadaev)

---

Top Contributors

[![MatanYadaev](https://avatars.githubusercontent.com/u/13586343?v=4)](https://github.com/MatanYadaev "MatanYadaev (215 commits)")[![Synchro](https://avatars.githubusercontent.com/u/81561?v=4)](https://github.com/Synchro "Synchro (2 commits)")[![Riley19280](https://avatars.githubusercontent.com/u/14127031?v=4)](https://github.com/Riley19280 "Riley19280 (2 commits)")[![yinx](https://avatars.githubusercontent.com/u/1022847?v=4)](https://github.com/yinx "yinx (2 commits)")[![gdebrauwer](https://avatars.githubusercontent.com/u/22586858?v=4)](https://github.com/gdebrauwer "gdebrauwer (1 commits)")[![jobverplanke](https://avatars.githubusercontent.com/u/18289961?v=4)](https://github.com/jobverplanke "jobverplanke (1 commits)")[![ju-gow](https://avatars.githubusercontent.com/u/5887244?v=4)](https://github.com/ju-gow "ju-gow (1 commits)")[![LachlanArthur](https://avatars.githubusercontent.com/u/1870204?v=4)](https://github.com/LachlanArthur "LachlanArthur (1 commits)")[![d0m4te](https://avatars.githubusercontent.com/u/15982187?v=4)](https://github.com/d0m4te "d0m4te (1 commits)")[![nickknissen](https://avatars.githubusercontent.com/u/204970?v=4)](https://github.com/nickknissen "nickknissen (1 commits)")[![Smip](https://avatars.githubusercontent.com/u/11481452?v=4)](https://github.com/Smip "Smip (1 commits)")[![trin4ik](https://avatars.githubusercontent.com/u/839633?v=4)](https://github.com/trin4ik "trin4ik (1 commits)")[![lukevi](https://avatars.githubusercontent.com/u/5833626?v=4)](https://github.com/lukevi "lukevi (1 commits)")[![devinfd](https://avatars.githubusercontent.com/u/468399?v=4)](https://github.com/devinfd "devinfd (1 commits)")[![dzhwar-k](https://avatars.githubusercontent.com/u/73309329?v=4)](https://github.com/dzhwar-k "dzhwar-k (1 commits)")[![eschricker](https://avatars.githubusercontent.com/u/56429442?v=4)](https://github.com/eschricker "eschricker (1 commits)")

---

Tags

eloquentlaravelphpspatial

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/matanyadaev-laravel-eloquent-spatial/health.svg)

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

###  Alternatives

[api-platform/laravel

API Platform support for Laravel

58171.6k14](/packages/api-platform-laravel)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[yajra/laravel-oci8

Oracle DB driver for Laravel via OCI8

8793.2M25](/packages/yajra-laravel-oci8)[glushkovds/phpclickhouse-laravel

Adapter of the most popular library https://github.com/smi2/phpClickHouse to Laravel

2051.5M2](/packages/glushkovds-phpclickhouse-laravel)

PHPackages © 2026

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