PHP Classes

How Can PHP Manipulate Data Stored in Tables of MySQL with Fields that Store Spatial Data Types Using the Package Laravel MySQL Spatial: Manipulate objects with spatial data using Laravel

Recommend this page to a friend!
  Info   Documentation   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2026-06-16 (26 days ago) RSS 2.0 feedNot yet rated by the usersTotal: Not yet counted Not yet ranked
Version License PHP version Categories
laravel-mysql-spatia 1.0MIT/X Consortium ...8Databases, Geography, Data types, PHP 8
Description 

Author

This package can manipulate objects with spatial data using Laravel.

It is a fork of the package Laravel MySQL Spatial extension by Joseph Estefane to access data stored in MySQL database tables that have spatial data.

Currently it can:

- Define the creation of table fields of geometric types to perform migrations

- Define models with spatial fields

- Create and save model objects with spatial fields, like polygons, points, lines, to MySQL database tables

- Retrieving geographic coordinates from points stored in model objects

- Add indexes to tables with spatial data types

- Iterate over objects with spatial data like lines with multiple points

- Convert text with known spatial data formats like WKT

- Convert spatial data to GeoJSON format

Picture of Bhavin Gajjar
  Performance   Level  
Name: Bhavin Gajjar <contact>
Classes: 4 packages by
Country: India India
Innovation award
Innovation award
Nominee: 2x

Instructions

Please read this document to learn how to set up and access MySQl spatial data using Laravel model classes.

Documentation

Laravel MySQL Spatial extension

Packagist Version Packagist Downloads license

Laravel package to easily work with MySQL Spatial Data Types and MySQL Spatial Functions.

Maintainer: Bhavin Gajjar (gajjarbhavin22@gmail.com) Packagist: bhavingajjar/laravel-mysql-spatial Repository: github.com/bhavingajjar/laravel-mysql-spatial

Fork of grimzy/laravel-mysql-spatial with Laravel 8?13 and PHP 8.3 support. The Grimzy\LaravelMysqlSpatial\ namespace is unchanged ? drop-in replacement with only a Composer package name change.

Please check the documentation for your MySQL version. MySQL's Extension for Spatial Data was added in MySQL 5.5 but many Spatial Functions were changed in 5.6 and 5.7.

Versions (this package)

  • 1.0.x: Laravel 8?13, PHP 7.3+, MySQL 8.0 with SRID support [Current]

For the original grimzy package versioning history, see grimzy/laravel-mysql-spatial.

This package also works with MariaDB. Please refer to the MySQL/MariaDB Spatial Support Matrix for compatibility.

Installation

Add the package using Composer:

composer require bhavingajjar/laravel-mysql-spatial:^1.0

This installs the latest 1.0.x release from Packagist.

Migrating from grimzy/laravel-mysql-spatial: replace the package name in composer.json only. No application code or namespace changes are required.

composer remove grimzy/laravel-mysql-spatial
composer require bhavingajjar/laravel-mysql-spatial:^1.0

For Laravel versions before 5.5 or if not using auto-discovery, register the service provider in config/app.php:

'providers' => [
  /*
   * Package Service Providers...
   */
  Grimzy\LaravelMysqlSpatial\SpatialServiceProvider::class,
],

Quickstart

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. For Laravel versions prior to 5.5, you can use the Blueprint provided by this package (Grimzy\LaravelMysqlSpatial\Schema\Blueprint):

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

// For Laravel < 5.5
// use Grimzy\LaravelMysqlSpatial\Schema\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', 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();
        // });
    }

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

Run the migration:

php artisan migrate

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 MySQL Spatial Data field(s) created in the migration:

namespace App;

use Illuminate\Database\Eloquent\Model;
use Grimzy\LaravelMysqlSpatial\Eloquent\SpatialTrait;

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

    protected $fillable = [
        'name'
    ];

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

Saving a model

use Grimzy\LaravelMysqlSpatial\Types\Point;
use Grimzy\LaravelMysqlSpatial\Types\Polygon;
use Grimzy\LaravelMysqlSpatial\Types\LineString;

$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 Grimzy\LaravelMysqlSpatial\Types\Point;
use Grimzy\LaravelMysqlSpatial\Types\Polygon;
use Grimzy\LaravelMysqlSpatial\Types\LineString;

$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

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

Geometry classes

Available Geometry classes

| Grimzy\LaravelMysqlSpatial\Types | OpenGIS Class | | ------------------------------------------------------------ | ------------------------------------------------------------ | | Point($lat, $lng, $srid = 0) | Point | | MultiPoint(Point[], $srid = 0) | MultiPoint | | LineString(Point[], $srid = 0) | LineString | | MultiLineString(LineString[], $srid = 0) | MultiLineString | | Polygon(LineString[], $srid = 0) (exterior and interior boundaries) | Polygon | | MultiPolygon(Polygon[], $srid = 0) | MultiPolygon | | GeometryCollection(Geometry[], $srid = 0) | GeometryCollection |

Check out the Class diagram.

Using Geometry classes

In order for your Eloquent Model to handle the Geometry classes, it must use the Grimzy\LaravelMysqlSpatial\Eloquent\SpatialTrait trait and define a protected property $spatialFields as an array of MySQL Spatial Data Type column names (example in Quickstart).

IteratorAggregate and ArrayAccess

The collection Geometries (LineString, Polygon, MultiPoint, MultiLineString, and GeometryCollection) implement IteratorAggregate and ArrayAccess; making it easy to perform Iterator and Array operations. For example:

$polygon = $multipolygon[10];	// ArrayAccess

// IteratorAggregate
for($polygon as $i => $linestring) {
  echo (string) $linestring;
}

Helpers

From/To Well Known Text (WKT)

// fromWKT($wkt, $srid = 0)
$point = Point::fromWKT('POINT(2 1)');
$point->toWKT();	// POINT(2 1)

$polygon = Polygon::fromWKT('POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))');
$polygon->toWKT();	// POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))

From/To String

// fromString($wkt, $srid = 0)
$point = new Point(1, 2);	// lat, lng
(string)$point			// lng, lat: 2 1

$polygon = Polygon::fromString('(0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)');
(string)$polygon;	// (0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)

From/To JSON (GeoJSON)

The Geometry classes implement JsonSerializable and Illuminate\Contracts\Support\Jsonable to help serialize into GeoJSON:

$point = new Point(40.7484404, -73.9878441);

json_encode($point); // or $point->toJson();

// {
//   "type": "Feature",
//   "properties": {},
//   "geometry": {
//     "type": "Point",
//     "coordinates": [
//       -73.9878441,
//       40.7484404
//     ]
//   }
// }

To deserialize a GeoJSON string into a Geometry class, you can use Geometry::fromJson($json_string) :

$location = Geometry::fromJson('{"type":"Point","coordinates":[3.4,1.2]}');
$location instanceof Point::class;  // true
$location->getLat();  // 1.2
$location->getLng()); // 3.4

Scopes: Spatial analysis functions

Spatial analysis functions are implemented using Eloquent Local Scopes.

Available scopes:

  • `distance($geometryColumn, $geometry, $distance)`
  • `distanceExcludingSelf($geometryColumn, $geometry, $distance)`
  • `distanceSphere($geometryColumn, $geometry, $distance)`
  • `distanceSphereExcludingSelf($geometryColumn, $geometry, $distance)`
  • `comparison($geometryColumn, $geometry, $relationship)`
  • `within($geometryColumn, $polygon)`
  • `crosses($geometryColumn, $geometry)`
  • `contains($geometryColumn, $geometry)`
  • `disjoint($geometryColumn, $geometry)`
  • `equals($geometryColumn, $geometry)`
  • `intersects($geometryColumn, $geometry)`
  • `overlaps($geometryColumn, $geometry)`
  • `doesTouch($geometryColumn, $geometry)`
  • `orderBySpatial($geometryColumn, $geometry, $orderFunction, $direction = 'asc')`
  • `orderByDistance($geometryColumn, $geometry, $direction = 'asc')`
  • `orderByDistanceSphere($geometryColumn, $geometry, $direction = 'asc')`

Note that behavior and availability of MySQL spatial analysis functions differs in each MySQL version (cf. documentation).

Migrations

For Laravel versions prior to 5.5, you can use the Blueprint provided with this package: Grimzy\LaravelMysqlSpatial\Schema\Blueprint.

use Illuminate\Database\Migrations\Migration;
use Grimzy\LaravelMysqlSpatial\Schema\Blueprint;

class CreatePlacesTable extends Migration {
    // ...
}

Columns

Available MySQL Spatial Types migration blueprints:

  • `$table->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 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:

> For MyISAM 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 regarding Index Lengths in the Laravel 5.6 documentation.

For example, as a follow up to the Quickstart; 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 Illuminate\Database\Schema\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

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

Integration tests require a running MySQL database. If you have Docker installed, you can start easily start one:

$ make start_db		# starts MySQL 8.0
# or
$ make start_db V=5.7	# starts MySQL 5.7

Contributing

Recommendations and pull requests are welcome on github.com/bhavingajjar/laravel-mysql-spatial. Pull requests with tests are the best.

Credits


  Files folder image Files (67)  
File Role Description
Files folder imagesrc (2 files, 6 directories)
Files folder imagetests (2 directories)
Accessible without login Plain text file .travis.yml Data Auxiliary data
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file docker-compose.yml Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file Makefile Data Auxiliary data
Accessible without login Plain text file phpunit.xml.dist Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (67)  /  src  
File Role Description
Files folder imageConnectors (1 file)
Files folder imageDoctrine (8 files)
Files folder imageEloquent (4 files)
Files folder imageExceptions (5 files)
Files folder imageSchema (2 files, 1 directory)
Files folder imageTypes (11 files)
  Plain text file MysqlConnection.php Class Class source
  Plain text file SpatialServiceProvider.php Class Class source

  Files folder image Files (67)  /  src  /  Connectors  
File Role Description
  Plain text file ConnectionFactory.php Class Class source

  Files folder image Files (67)  /  src  /  Doctrine  
File Role Description
  Plain text file Geometry.php Class Class source
  Plain text file GeometryCollection.php Class Class source
  Plain text file LineString.php Class Class source
  Plain text file MultiLineString.php Class Class source
  Plain text file MultiPoint.php Class Class source
  Plain text file MultiPolygon.php Class Class source
  Plain text file Point.php Class Class source
  Plain text file Polygon.php Class Class source

  Files folder image Files (67)  /  src  /  Eloquent  
File Role Description
  Plain text file BaseBuilder.php Class Class source
  Plain text file Builder.php Class Class source
  Plain text file SpatialExpression.php Class Class source
  Plain text file SpatialTrait.php Class Class source

  Files folder image Files (67)  /  src  /  Exceptions  
File Role Description
  Plain text file InvalidGeoJsonException.php Class Class source
  Plain text file SpatialFieldsNotDefinedException.php Class Class source
  Plain text file UnknownSpatialFunctionException.php Class Class source
  Plain text file UnknownSpatialRelationFunction.php Class Class source
  Plain text file UnknownWKTTypeException.php Class Class source

  Files folder image Files (67)  /  src  /  Schema  
File Role Description
Files folder imageGrammars (1 file)
  Plain text file Blueprint.php Class Class source
  Plain text file Builder.php Class Class source

  Files folder image Files (67)  /  src  /  Schema  /  Grammars  
File Role Description
  Plain text file MySqlGrammar.php Class Class source

  Files folder image Files (67)  /  src  /  Types  
File Role Description
  Plain text file Factory.php Class Class source
  Plain text file Geometry.php Class Class source
  Plain text file GeometryCollection.php Class Class source
  Plain text file GeometryInterface.php Class Class source
  Plain text file LineString.php Class Class source
  Plain text file MultiLineString.php Class Class source
  Plain text file MultiPoint.php Class Class source
  Plain text file MultiPolygon.php Class Class source
  Plain text file Point.php Class Class source
  Plain text file PointCollection.php Class Class source
  Plain text file Polygon.php Class Class source

  Files folder image Files (67)  /  tests  
File Role Description
Files folder imageIntegration (4 files, 2 directories)
Files folder imageUnit (2 files, 5 directories)

  Files folder image Files (67)  /  tests  /  Integration  
File Role Description
Files folder imageMigrations (2 files)
Files folder imageModels (3 files)
  Plain text file IntegrationBaseTestCase.php Class Class source
  Plain text file MigrationTest.php Class Class source
  Plain text file SpatialTest.php Class Class source
  Plain text file SridSpatialTest.php Class Class source

  Files folder image Files (67)  /  tests  /  Integration  /  Migrations  
File Role Description
  Plain text file CreateTables.php Class Class source
  Plain text file UpdateTables.php Class Class source

  Files folder image Files (67)  /  tests  /  Integration  /  Models  
File Role Description
  Plain text file GeometryModel.php Class Class source
  Plain text file NoSpatialFieldsModel.php Class Class source
  Plain text file WithSridModel.php Class Class source

  Files folder image Files (67)  /  tests  /  Unit  
File Role Description
Files folder imageConnectors (1 file)
Files folder imageEloquent (2 files)
Files folder imageSchema (2 files, 1 directory)
Files folder imageStubs (1 file)
Files folder imageTypes (8 files)
  Plain text file BaseTestCase.php Class Class source
  Plain text file MysqlConnectionTest.php Class Class source

  Files folder image Files (67)  /  tests  /  Unit  /  Connectors  
File Role Description
  Plain text file ConnectionFactoryTest.php Class Class source

  Files folder image Files (67)  /  tests  /  Unit  /  Eloquent  
File Role Description
  Plain text file BuilderTest.php Class Class source
  Plain text file SpatialTraitTest.php Class Class source

  Files folder image Files (67)  /  tests  /  Unit  /  Schema  
File Role Description
Files folder imageGrammars (1 file)
  Plain text file BlueprintTest.php Class Class source
  Plain text file BuilderTest.php Class Class source

  Files folder image Files (67)  /  tests  /  Unit  /  Schema  /  Grammars  
File Role Description
  Plain text file MySqlGrammarTest.php Class Class source

  Files folder image Files (67)  /  tests  /  Unit  /  Stubs  
File Role Description
  Plain text file PDOStub.php Class Class source

  Files folder image Files (67)  /  tests  /  Unit  /  Types  
File Role Description
  Plain text file GeometryCollectionTest.php Class Class source
  Plain text file GeometryTest.php Class Class source
  Plain text file LineStringTest.php Class Class source
  Plain text file MultiLineStringTest.php Class Class source
  Plain text file MultiPointTest.php Class Class source
  Plain text file MultiPolygonTest.php Class Class source
  Plain text file PointTest.php Class Class source
  Plain text file PolygonTest.php Class Class source

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
 Version Control Unique User Downloads  
 100%
Total:0
This week:0