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

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

angel-source-labs/laravel-spatial
=================================

Spatial data types extension for Laravel.

v1.3.1(3mo ago)78.7k↑890.7%1[1 issues](https://github.com/Angel-Source-Labs/laravel-spatial/issues)MITPHPPHP &gt;=7.3CI passing

Since Mar 28Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/Angel-Source-Labs/laravel-spatial)[ Packagist](https://packagist.org/packages/angel-source-labs/laravel-spatial)[ RSS](/packages/angel-source-labs-laravel-spatial/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (4)Dependencies (18)Versions (7)Used By (0)

Spatial: GIS Spatial Extensions for Laravel
===========================================

[](#spatial-gis-spatial-extensions-for-laravel)

[![license](https://camo.githubusercontent.com/7123c32787e013be5a8a13598ad01f562754637ed6141e89b02e85bf16d3e63e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d6173686170652f6170697374617475732e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![PHPUnit tests](https://github.com/Angel-Source-Labs/laravel-spatial/actions/workflows/github-actions.yml/badge.svg?branch=main)](https://github.com/Angel-Source-Labs/laravel-spatial/actions/workflows/github-actions.yml)

Laravel package to easily work with GIS data types in PostGIS, MySQL 5.7, and MySQL 8.

Supported Compatibiltiy
-----------------------

[](#supported-compatibiltiy)

### Laravel

[](#laravel)

This package is tested against the following Laravel versions:

- Laravel 7.x
- Laravel 8.x
- Laravel 9.x
- Laravel 10.x
- Laravel 11.x
- Laravel 12.x

### Databases

[](#databases)

This package is tested against the following Databases

DatabasePlatformSRID SupportedGeography Type SupportedPostGIS 10.x - 14.xPostgres 10YesYesMySQL 5.7MySQL 5.7NoNoMySQL 8.xMySQL 8YesNoPercona 5.7MySQL 5.7NoNoPercona 8.xMySQL 8YesNoMariaDB 10.2 - 10.7MySQL 5.7NoNo#### Future

[](#future)

Support for these databases may be available in a future release. This package has been designed to support these databases but the work is not complete.

- SQLServer
- SQLite

History and Motivation
----------------------

[](#history-and-motivation)

We really like the [grimzy/laravel-mysql-spatial](https://github.com/grimzy/laravel-mysql-spatial) Laravel Eloquent API and we wanted to also be able to use Postgis. (See [issue 137](https://github.com/grimzy/laravel-mysql-spatial/issues/137)). The goal of this package is to provide an API compatible with the [grimzy/laravel-mysql-spatial](https://github.com/grimzy/laravel-mysql-spatial) package that also supports postgis and additional database drivers.

This package is a fork and substantial refactoring of `grimzy/laravel-mysql-spatial`:

- refactored to use `laravel-expressions` to provide database compatibility across postgis, mysql 8, and mysql 5.7
- refactored to use `orchestra/testbench` in PHPUnit tests
- PHPUnit tests updated to use PHPUnit 9.x versus PHPUnit 6.x

Historically, `grimzy/laravel-mysql-spatial` was itself a fork of `njbarrett/laravel-postgis`, which is now `mstaack/laravel-postgis`. These `laravel-postgis` pacakges provide access to postgis but do not provide the Laravel Eloquent Spatial analysis functions which were added by `grimzy/laravel-mysql-spatial`.

- March 2015: [phaza/laravel-postgres](https://github.com/phaza/laravel-postgres) Peter Haza
    - May 2016: [njbarrett/laravel-postgis](njbarrett/laravel-postgis) Nick Barrett
        - March 2017: [grimzy/laravel-mysql-spatial](https://github.com/grimzy/laravel-mysql-spatial) Joseph Estefane
            - Feb 2022: (this package) [Angel-Source-Labs/laravel-spatial](https://github.com/Angel-Source-Labs/laravel-spatial) Brion Finlay
        - March 2020: [mstaack/laravel-postgis](https://github.com/mstaack/laravel-postgis) Max Staack

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

[](#installation)

Add the package using composer:

```
$ composer require angel-source-labs/laravel-spatial
```

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

[](#installation-1)

### Laravel 8.x, 9.x, 10.x, 11.x

[](#laravel-8x-9x-10x-11x)

- Require this package directly by `composer require angel-source-labs/laravel-spatial`
- Or add this package in your composer.json and run `composer update`

    ```
    "require-dev": {
      ...
      "angel-source-labs/laravel-spatial": "^1.0",
      ...
    }

    ```

### Laravel 6.x, 7.x

[](#laravel-6x-7x)

Laravel 6.x, and 7.x require DBAL 2.x. Because DBAL is a `require-dev` dependency of laravel, its version constraint will not be resolved by composer when installing a child package. However, this is easy to solve by specifying DBAL 2.x as an additional dependency.

Note that Laravel 6.x, 7.x, 8.x, and 9.x are EOL. See . These versions will continue to be supported by this package for as long as it is reasonably easy, thanks to github actions performing the testing.

To install for Laravel 6.x, and 7.x:

- Require this package directly by `composer require angel-source-labs/laravel-spatial`
- Require the dbal package directly by `composer require doctrine/dbal:^2.6|^3.0|^4.0`
- Or add these packages in your composer.json and run `composer update`

    ```
    "require-dev": {
      ...
      "angel-source-labs/laravel-spatial": "^1.0",
      "doctrine/dbal": "^2.6|^3.0|^4.0"
      ...
    }

    ```

Quickstart
----------

[](#quickstart)

### Create a migration

[](#create-a-migration)

From the command line:

```
php artisan make:migration create_places_table
```

Then edit the migration you just created by adding at least one spatial data field.

```
use Illuminate\Database\Migrations\Migration;
// use SpatialBlueprint for Spatial features and for proper code completion
use AngelSourceLabs\LaravelSpatial\Schema\SpatialBlueprint as Blueprint;

class CreatePlacesTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('places', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('name')->unique();
            // Add a Point spatial data field named location
            $table->point('location')->nullable();
            // Add a Polygon spatial data field named area
            $table->polygon('area')->nullable();
            $table->timestamps();
        });

        // Or create the spatial fields with an SRID (e.g. 4326 WGS84 spheroid)

         Schema::create('places_with_srid', function(Blueprint $table)
         {
             $table->increments('id');
             $table->string('name')->unique();
             // Add a Point spatial data field named location with SRID 4326
             $table->point('location', 4326)->nullable();
             // Add a Polygon spatial data field named area with SRID 4326
             $table->polygon('area', 4326)->nullable();
             $table->timestamps();
         });

         // In Postgis, you can also create spatial fields that are Geography types instead of Geometry types
          Schema::create('places_with_geography', function(Blueprint $table)
         {
             $table->increments('id');
             $table->string('name')->unique();
             // Add a Point spatial data field named location with SRID 4326
             $table->point('location', 4326, Blueprint::GEOGRAPHY)->nullable();
             // Add a Polygon spatial data field named area with SRID 4326
             $table->polygon('area', 4326, Blueprint::GEOGRAPHY)->nullable();
             $table->timestamps();
         });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('places');
    }
}
```

Run the migration:

```
php artisan migrate
```

### Create a model

[](#create-a-model)

From the command line:

```
php artisan make:model Place
```

Then edit the model you just created. It must use the `SpatialTrait` and define an array called `$spatialFields` with the name of the spatial data field(s) created in the migration:

```
namespace App;

use AngelSourceLabs\LaravelSpatial\Eloquent\SpatialTrait;
use Illuminate\Database\Eloquent\Model;

/**
 * @property \AngelSourceLabs\LaravelSpatial\Types\Point   $location
 * @property \AngelSourceLabs\LaravelSpatial\Types\Polygon $area
 */
class Place extends Model
{
    use SpatialTrait;

    protected $fillable = [
        'name'
    ];

    protected $spatialFields = [
        'location',
        'area'
    ];
}
```

### Saving a model

[](#saving-a-model)

```
use AngelSourceLabs\LaravelSpatial\Types\LineString;
use AngelSourceLabs\LaravelSpatial\Types\Point;
use AngelSourceLabs\LaravelSpatial\Types\Polygon;

$place1 = new Place();
$place1->name = 'Empire State Building';

// saving a point
$place1->location = new Point(40.7484404, -73.9878441);	// (lat, lng)
$place1->save();

// saving a polygon
$place1->area = new Polygon([new LineString([
    new Point(40.74894149554006, -73.98615270853043),
    new Point(40.74848633046773, -73.98648262023926),
    new Point(40.747925497790725, -73.9851602911949),
    new Point(40.74837050671544, -73.98482501506805),
    new Point(40.74894149554006, -73.98615270853043)
])]);
$place1->save();
```

Or if your database fields were created with a specific SRID:

```
use AngelSourceLabs\LaravelSpatial\Types\LineString;
use AngelSourceLabs\LaravelSpatial\Types\Point;
use AngelSourceLabs\LaravelSpatial\Types\Polygon;

$place1 = new Place();
$place1->name = 'Empire State Building';

// saving a point with SRID 4326 (WGS84 spheroid)
$place1->location = new Point(40.7484404, -73.9878441, 4326);	// (lat, lng, srid)
$place1->save();

// saving a polygon with SRID 4326 (WGS84 spheroid)
$place1->area = new Polygon([new LineString([
    new Point(40.74894149554006, -73.98615270853043),
    new Point(40.74848633046773, -73.98648262023926),
    new Point(40.747925497790725, -73.9851602911949),
    new Point(40.74837050671544, -73.98482501506805),
    new Point(40.74894149554006, -73.98615270853043)
])], 4326);
$place1->save();
```

> **Note**: When saving collection Geometries (`LineString`, `Polygon`, `MultiPoint`, `MultiLineString`, and `GeometryCollection`), only the top-most geometry should have an SRID set in the constructor.
>
> In the example above, when creating a `new Polygon()`, we only set the SRID on the `Polygon` and use the default for the `LineString` and the `Point` objects.

### Retrieving a model

[](#retrieving-a-model)

```
$place2 = Place::first();
$lat = $place2->location->getLat();	// 40.7484404
$lng = $place2->location->getLng();	// -73.9878441
```

Geometry classes
----------------

[](#geometry-classes)

### Available Geometry classes

[](#available-geometry-classes)

AngelSourceLabs\\LaravelSpatial\\Doctrine\\TypesOpenGIS Class`Point($lat, $lng, $srid = 0)`[Point](https://dev.mysql.com/doc/refman/8.0/en/gis-class-point.html)`MultiPoint(Point[], $srid = 0)`[MultiPoint](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multipoint.html)`LineString(Point[], $srid = 0)`[LineString](https://dev.mysql.com/doc/refman/8.0/en/gis-class-linestring.html)`MultiLineString(LineString[], $srid = 0)`[MultiLineString](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multilinestring.html)`Polygon(LineString[], $srid = 0)` *([exterior and interior boundaries](https://dev.mysql.com/doc/refman/8.0/en/gis-class-polygon.html))*[Polygon](https://dev.mysql.com/doc/refman/8.0/en/gis-class-polygon.html)`MultiPolygon(Polygon[], $srid = 0)`[MultiPolygon](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multipolygon.html)`GeometryCollection(Geometry[], $srid = 0)`[GeometryCollection](https://dev.mysql.com/doc/refman/8.0/en/gis-class-geometrycollection.html)[![](ReadmeClassDiagram.svg)](ReadmeClassDiagram.svg)

PlantUML Markup

Details```
@startuml ReadmeClassDiagram
interface GeometryInterface
interface Jsonable
Interface JsonSerializable
interface Arrayable
interface IteratorAggregate
Interface Countable
Interface ArrayAccess
abstract Class Geometry
Class GeometryCollection
Class Point
abstract Class PointCollection
Class MultiLineString
Class MultiPolygon
Class MultiPoint
Class LineString
Class Polygon

Jsonable geometry(string $column_name, int $srid = 0)`
- `$table->point(string $column_name, int $srid = 0)`
- `$table->lineString(string $column_name, int $srid = 0)`
- `$table->polygon(string $column_name, int $srid = 0)`
- `$table->multiPoint(string $column_name, int $srid = 0)`
- `$table->multiLineString(string $column_name, int $srid = 0)`
- `$table->multiPolygon(string $column_name, int $srid = 0)`
- `$table->geometryCollection(string $column_name, int $srid = 0)`

Spatial type references:

- [MySQL 5.7 Spatial Types](https://dev.mysql.com/doc/refman/5.7/en/spatial-type-overview.html)
- [MySQL 8.x Spatial Types](https://dev.mysql.com/doc/refman/8.0/en/spatial-type-overview.html)
- [PostGIS types](https://postgis.net/docs/reference.html#PostGIS_Types)

### Spatial indexes

[](#spatial-indexes)

You can add or drop spatial indexes in your migrations with the `spatialIndex` and `dropSpatialIndex` blueprints.

- `$table->spatialIndex('column_name')`
- `$table->dropSpatialIndex(['column_name'])` or `$table->dropSpatialIndex('index_name')`

Note about spatial indexes from the [MySQL documentation](https://dev.mysql.com/doc/refman/8.0/en/creating-spatial-indexes.html):

> For [`MyISAM`](https://dev.mysql.com/doc/refman/8.0/en/myisam-storage-engine.html) and (as of MySQL 5.7.5) `InnoDB` tables, MySQL can create spatial indexes using syntax similar to that for creating regular indexes, but using the `SPATIAL` keyword. Columns in spatial indexes must be declared `NOT NULL`.

Also please read this [**important note**](https://laravel.com/docs/master/migrations#index-lengths-mysql-mariadb) regarding Index Lengths in the Laravel documentation.

For example, as a follow up to the [Quickstart](#user-content-create-a-migration); from the command line, generate a new migration:

```
php artisan make:migration update_places_table
```

Then edit the migration file that you just created:

```
use Illuminate\Database\Migrations\Migration;
use AngelSourceLabs\LaravelSpatial\Schema\SpatialBlueprint as Blueprint;
use Illuminate\Support\Facades\Schema;

class UpdatePlacesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        // MySQL < 5.7.5: table has to be MyISAM
        // \DB::statement('ALTER TABLE places ENGINE = MyISAM');

        Schema::table('places', function (Blueprint $table) {
            // Make sure point is not nullable
            $table->point('location')->change();

            // Add a spatial index on the location field
            $table->spatialIndex('location');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('places', function (Blueprint $table) {
            $table->dropSpatialIndex(['location']); // either an array of column names or the index name
        });

        // \DB::statement('ALTER TABLE places ENGINE = InnoDB');

        Schema::table('places', function (Blueprint $table) {
            $table->point('location')->nullable()->change();
        });
    }
}
```

Tests
-----

[](#tests)

Start MySQL 5.7, MySQL8, Postgis Docker containers for tests.

```
$ composer docker
```

run tests. Unit tests can be run without the database server docker containers.

```
$ composer test
# or
$ composer test:unit
$ composer test:integration
```

Contributing
------------

[](#contributing)

Recommendations and pull request are most welcome! Pull requests with tests are the best! There are still a lot of spatial functions to implement or creative ways to use spatial functions.

Credits
-------

[](#credits)

Originally inspired from [grimzy/laravel-mysql-spatial](https://github.com/grimzy/laravel-mysql-spatial) and [njbarrett's Laravel postgis package](https://github.com/njbarrett/laravel-postgis).

License
-------

[](#license)

Spatial for Laravel is open-sourced software licensed under the MIT license.

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance77

Regular maintenance activity

Popularity32

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 90.5% 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 ~271 days

Total

5

Last Release

107d ago

PHP version history (2 changes)v1.0PHP &gt;=7.2.5

v1.2PHP &gt;=7.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/75f4790522212e9f5588334a23ab3e4199ea8a465773eb8d7796b84b7055ff26?d=identicon)[bfinlay](/maintainers/bfinlay)

---

Top Contributors

[![bfinlay](https://avatars.githubusercontent.com/u/1757856?v=4)](https://github.com/bfinlay "bfinlay (38 commits)")[![KieranLR](https://avatars.githubusercontent.com/u/39035259?v=4)](https://github.com/KieranLR "KieranLR (3 commits)")[![carlos-andres](https://avatars.githubusercontent.com/u/5489747?v=4)](https://github.com/carlos-andres "carlos-andres (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[backpack/crud

Quickly build admin interfaces using Laravel, Bootstrap and JavaScript.

3.4k3.7M223](/packages/backpack-crud)[statamic/cms

The Statamic CMS Core Package

4.8k3.6M985](/packages/statamic-cms)[tpetry/laravel-postgresql-enhanced

Support for many missing PostgreSQL specific features

1.0k2.4M29](/packages/tpetry-laravel-postgresql-enhanced)[leantime/leantime

Open source project management system for non-project managers. Simple like Trello, powerful like Jira. Built with neurodiversity in mind.

10.2k3.5k](/packages/leantime-leantime)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.6M572](/packages/shopware-core)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135224.7k7](/packages/statamic-rad-pack-runway)

PHPackages © 2026

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