Postgis extensions for laravel. Aims to make it easy to work with geometries from laravel models.

Overview

Laravel Wrapper for PostgreSQL's Geo-Extension Postgis

Build Status

Features

  • Work with geometry classes instead of arrays.
$model->myPoint = new Point(1,2);  //lat, long
  • Adds helpers in migrations.
$table->polygon('myColumn');

Warning

This Package has been moved to a new owner and aims for Laravel 6/7/8 and PHP 7 support only soon!

Replace all your references to the new namespace:

MStaack\LaravelPostgis

Thanks to :

Fluent in Laravel Packages and Postgres/Postgis? Consider contributing! We are looking for anyone that wants to help out!

Installation

  • Use 3.* for Laravel 5
composer require "mstaack/laravel-postgis:3.*"
  • Use 5.* for Laravel 6/7/8
composer require mstaack/laravel-postgis

For laravel >=5.5 that's all. This package supports Laravel new Package Discovery.

If you are using Laravel < 5.5, you also need to add the DatabaseServiceProvider to your config/app.php file.

'MStaack\LaravelPostgis\DatabaseServiceProvider',

Usage

To start, ensure you have PostGIS enabled in your database - you can do this in a Laravel migration or manually via SQL.

Enable PostGIS via a Laravel migration

Create a new migration file by running

php artisan make:migration enable_postgis

Update the newly created migration file to call the enablePostgisIfNotExists() and disablePostgisIfExists() methods on the Schema facade. For example:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema;

class EnablePostgis extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::enablePostgisIfNotExists();
    }

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

These methods are safe to use and will only enable / disable the PostGIS extension if relevant - they won't cause an error if PostGIS is / isn't already enabled.

If you prefer, you can use the enablePostgis() method which will throw an error if PostGIS is already enabled, and the disablePostgis() method twhich will throw an error if PostGIS isn't enabled.

Enable PostGIS manually

Use an SQL client to connect to your database and run the following command:

CREATE EXTENSION postgis;

To verify that PostGIS is enabled you can run:

SELECT postgis_full_version();

Migrations

Now create a model with a migration by running

php artisan make:model Location

If you don't want a model and just a migration run

php artisan make:migration create_locations_table

Open the created migrations with your editor.

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

class CreateLocationsTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('locations', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('name');
            $table->string('address')->unique();
            $table->point('location'); // GEOGRAPHY POINT column with SRID of 4326 (these are the default values).
            $table->point('location2', 'GEOGRAPHY', 4326); // GEOGRAPHY POINT column with SRID of 4326 with optional parameters.
            $table->point('location3', 'GEOMETRY', 27700); // GEOMETRY column with SRID of 27700.
            $table->polygon('polygon'); // GEOGRAPHY POLYGON column with SRID of 4326.
            $table->polygon('polygon2', 'GEOMETRY', 27700); // GEOMETRY POLYGON column with SRID of 27700.
            $table->timestamps();
        });
    }

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

}

Available blueprint geometries:

  • point
  • multipoint
  • linestring
  • multilinestring
  • polygon
  • multipolygon
  • geometrycollection

other methods:

  • enablePostgis
  • disablePostgis

Models

All models which are to be PostGis enabled must use the PostgisTrait.

You must also define an array called $postgisFields which defines what attributes/columns on your model are to be considered geometry objects. By default, all attributes are of type geography. If you want to use geometry with a custom SRID, you have to define an array called $postgisTypes. The keys of this assoc array must match the entries in $postgisFields (all missing keys default to geography), the values are assoc arrays, too. They must have two keys: geomtype which is either geography or geometry and srid which is the desired SRID. Note: Custom SRID is only supported for geometry, not geography.

use Illuminate\Database\Eloquent\Model;
use MStaack\LaravelPostgis\Eloquent\PostgisTrait;
use MStaack\LaravelPostgis\Geometries\Point;

class Location extends Model
{
    use PostgisTrait;

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

    protected $postgisFields = [
        'location',
        'location2',
        'location3',
        'polygon',
        'polygon2'
    ];

    protected $postgisTypes = [
        'location' => [
            'geomtype' => 'geography',
            'srid' => 4326
        ],
        'location2' => [
            'geomtype' => 'geography',
            'srid' => 4326
        ],
        'location3' => [
            'geomtype' => 'geometry',
            'srid' => 27700
        ],
        'polygon' => [
            'geomtype' => 'geography',
            'srid' => 4326
        ],
        'polygon2' => [
            'geomtype' => 'geometry',
            'srid' => 27700
        ]
    ]
}

$linestring = new LineString(
    [
        new Point(0, 0),
        new Point(0, 1),
        new Point(1, 1),
        new Point(1, 0),
        new Point(0, 0)
    ]
);

$location1 = new Location();
$location1->name = 'Googleplex';
$location1->address = '1600 Amphitheatre Pkwy Mountain View, CA 94043';
$location1->location = new Point(37.422009, -122.084047);
$location1->location2 = new Point(37.422009, -122.084047);
$location1->location3 = new Point(37.422009, -122.084047);
$location1->polygon = new Polygon([$linestring]);
$location1->polygon2 = new Polygon([$linestring]);
$location1->save();

$location2 = Location::first();
$location2->location instanceof Point // true

Available geometry classes:

  • Point
  • MultiPoint
  • LineString
  • MultiLineString
  • Polygon
  • MultiPolygon
  • GeometryCollection
Comments
  • Add Geometry and Custom SRID

    Add Geometry and Custom SRID

    This PR is based on #35

    Additionally I fixed a broken test and added a new exception (if an unsupported geomtype or illegal srid is given). Based on @phaza s comments I tried to fix the models, but could not figure out what exactly needs to be fixed. To check what's wrong I created a model (Location) based on the example and tried to set it's column location3 (which is type geometry) to $location->location3 = new Point(37.422009, -122.084047);. But this throws an error, because in the PostgisTrait.php file it uses ST_GeogFromText if the following check is true if ($value instanceof GeometryInterface && ! $value instanceof GeometryCollection). My idea was to also check the geomtype parameter which is added in the Blueprint.php. Unfortunately I couldn't find a method to perform this check. Could anyone confirm that this is the correct idea or help me what to do ( @phaza @njbarrett ) ? Thanks!

    opened by v1r0x 26
  • Add 3D coordinates

    Add 3D coordinates

    Fix #18

    I (hopefully) added a third dimension as optional paramter to all neccessary constructors/create functions. In functions that return the content have a 3d check as well. The 3d check is implemented as is3d() which does a simple check on the first element in the geometry (e.g. first LineString in Polygon or first Polygon in MultiPolygon, ...). I don't know if there is a better check. Any idea/suggestion is much appreciated :)

    cc @njbarrett

    opened by v1r0x 11
  • PostGIS with sqlite for unit testing purposes

    PostGIS with sqlite for unit testing purposes

    Hello,

    I use database memory for unit testing but obviously sqlite don't know public.ST_GeogFromText what is it.

    It is possible to mock this call or something like that? Thanks for reply.

    opened by loic-lopez 10
  • Add Geometry and Custom SRID

    Add Geometry and Custom SRID

    Added the ability to specify additional $geomtype and $srid parameters to geom/geog types. Both parameters have default values to ensure backward compatibbility.

    Additional tests added.

    opened by stevegoddard 10
  • Float formating under locale

    Float formating under locale

    Following https://github.com/njbarrett/laravel-postgis/pull/90, here is a patch proposal to deal with float formating. WKT is actually a string representation, but should remain independant from any locale format.

    An other approcah would have been to skip the WKT layer and to bind directly the float values in a prepared statement. I cannot say for now how it might be done with Eloquent (several bindings for one column).

    opened by challet 9
  • Laravel v5.1.39 Declaration of Bosnadev createConnection() Error

    Laravel v5.1.39 Declaration of Bosnadev createConnection() Error

    PHP 5.6 , Laravel 5.1 .39

    Error Exception in ConnectionFactory.php line 14 Declaration of Bosnadev\Database\Connectors \ConnectionFactory::createConnection() should be compatible with Illuminate\Database\Connectors\ConnectionFactory::c reateConnection($driver, PDO $connection, $database, $prefix = '', array $config = Array)

    Any solution?

    opened by Dagiral 9
  • PostgresBuilder Fix

    PostgresBuilder Fix

    This fixes the Builder to extend Laravel’s new PostgresBuilder class, and should therefore fix issue#48. Also makes small changes to composer.json and .travis.yml.

    Specifically make it so composer install doesn’t can resolve the dependencies by using a tagged release of codeclimate/php-test-reporter, and letting composer install satooshi/php-coveralls as a dependency for the code climate package. Also bumps a the minor version for phoenixgao/laravel-postgres-extended-schema.

    As for TravisCI, we now test against php7 and nightly.

    opened by jonnybarnes 9
  • Distance, containment, etc. implementations

    Distance, containment, etc. implementations

    @phaza, I'd like to implement these for you. However, what structure would you like these to have, and how would like me to lay out tests for those things?

    For distance, Euclidean distance fails on the surface of the earth, so you'd probably need something like the Haversine formula or better yet, Vincenty's which more accurate, but also more computationally expensive. Would the distance method live on the Point class and take another Point though?

    For polygon containment, there's plenty of algorithms there, and ray-casting is the fastest I know of (Github folks, correct me). I would think both Polygon and MultiPolygon would have an implementation that takes a single Point.

    What are you thoughts?

    opened by chipbell4 9
  • Framework v5.2.7 breaks with `createFactory()` compatability error

    Framework v5.2.7 breaks with `createFactory()` compatability error

    Specifically the error is with bosnadev/database package, I get the error:

    [2016-01-12 20:56:09] local.ERROR: ErrorException: Declaration of Bosnadev\Database\Connectors
    \ConnectionFactory::createConnection($driver, PDO $connection, $database, $prefix = '', array
    $config = Array) should be compatible with Illuminate\Database\Connectors\ConnectionFactory::c
    reateConnection($driver, $connection, $database, $prefix = '', array $config = Array) in /User
    s/jonny/Development/git/jbl5/vendor/bosnadev/database/src/Connectors/ConnectionFactory.php:13
    

    How can we work out what the incompatibility is?

    opened by jonnybarnes 8
  • Geometry vs Geography?

    Geometry vs Geography?

    Thx for your great extension. I just used it to make some migrations and seeding some data to it.

    I just ran into an issue where some stuff from the backend wont work and i then realized thats because of the geom field (multipolygon) which was generated through the migrations wasnt a geometry field. instead an geography field was made.

    Meanwhile i convert the geom field to a geometry in my queries cause of the need of some postgis functions.

    So my question here is, how to generate geometry fields for my migration? or am i missing something here?

    thx a lot though

    opened by magnolo 8
  • 3 dimensional coordinates

    3 dimensional coordinates

    Hi, I'm needing to store and access points with x y and z coordinates. Would it be too difficult to add the ability to store altitude in addition to lat and long? Or do I need to fork it and use my own modifications?

    opened by rogue780 8
  • Feature Store vs Feature Update

    Feature Store vs Feature Update

    Why I can't update database column of type geography for example point. it show me this error parse error - invalid geometry\nHINT: \"35.5298 4\" <-- parse error at position 9 within geometry\nCONTEXT: unnamed portal parameter $1 = '...' (SQL: update \"points\" set \"location\" = 35.5298 45.4324, \"updated_at\" = 2022-11-14 02:55:17 where \"id\" = 184)", I am using new Point(lat,lng);

    it's working when creating row in first time. put when you update the Point field not working.

    I actually find a sulation but is not really good, it say use: toWKT() function $point->update([ "location" => (new \MStaack\LaravelPostgis\Geometries\Point(($request['lng'] ,$request['lat']))->toWKT()]); it works put when I return value of point it return in string form not in json

    opened by Noraddeen 0
  • Support measure

    Support measure

    For a project in postgis I do have the need to include the 4th/measure dimension and for that reason I did create the following pull request:

    https://github.com/mstaack/laravel-postgis/pull/177

    opened by verplicht 0
  • Add 3dm and 4d points and linestrings

    Add 3dm and 4d points and linestrings

    For a project we had a need to save a point in time for which we want to use the point zm and linestring m.

    Changes

    • Updated Blueprint, Geometries and Grammar to support point m, point zm, linestring m and linestring zm
    • Updated GeometryTest to also assert 3dm and 4d point collections
    • Added PointM class extending Points. This way measure can be added without breaking any older version
    • Added tests for PointM matching Point's tests
    • Added LineStringM and LineStringM tests
    • Updated Factory to determine if 'measure' is included and returning PointM/LinestringM in those cases

    Because PointM can only be used as geometry, I changed the constructor to refer to X, Y and Z instead of Lat and Long

    opened by verplicht 0
  • Coordinate precision lost

    Coordinate precision lost

    Original data

    {
        "geom": [
            [
                [
                    110.749065316,
                    37.751257808
                ],
                [
                    110.748651558,
                    37.7512603870001
                ],
                ...
                [
                    110.749065316,
                    37.751257808
                ],
            ]
        ]
    }
    

    Saved data

    MULTIPOLYGON(((110.749065 37.751258, 110.748652 37.75126, ... , 110.749065 37.751258)))
    

    How can I save the original data into database?


    Update

    mstaack/laravel-postgis/src/Geometries/Point.php:65

    private static function stringifyFloat($float)
    {
        // normalized output among locales
        return rtrim(rtrim(sprintf('%F', $float), '0'), '.');
    }
    

    sprintf() function format

    echo sprintf('%F', 110.749065316);
    
    // 110.749065
    

    image

    opened by leslieeilsel 0
  • Illuminate Schema Blueprint

    Illuminate Schema Blueprint

    Similar to #81 Similar to #109

    I'm getting this issue in 2022.

    laravel.ERROR: MyMigration::{closure}(): Argument 1 ($table) must be of type MStaack\LaravelPostgis\Schema\Blueprint, Illuminate\Database\Schema\Blueprint given,

    called in /opt/site/vendor/illuminate/database/Schema/Blueprint.php on line 95

    [stacktrace]

    1. /opt/site/vendor/illuminate/database/Schema/Blueprint.php(95): MyMigration->{closure}()
    2. /opt/site/vendor/illuminate/database/Schema/Builder.php(385): Illuminate\Database\Schema\Blueprint->__construct()
    3. /opt/site/vendor/illuminate/database/Schema/Builder.php(212): Illuminate\Database\Schema\Builder->createBlueprint()
    4. /opt/site/vendor/illuminate/support/Facades/Facade.php(261): Illuminate\Database\Schema\Builder->table()
    5. /opt/site/database/migrations/2022_02_24_000000_my_migration.php(26): Illuminate\Support\Facades\Facade::__callStatic()

    Line 19 is the first line of this code block

    Schema::table( 'my_table', function( Blueprint $table ) {
        $table->geometrycollection( 'geometry' );
    });
    

    The issue seems to be that the illuminate schema facade calls the illuminate blueprint constructor which calls the callback with $this (which is the illuminate Blueprint class itself rather than the MStaack Blueprint class.

    I'm uncertain how to fix this.

    Here is the use block from the top of my migration file

    
    use Illuminate\Database\Migrations\Migration;
    use MStaack\LaravelPostgis\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    opened by treehousetim 12
Releases(5.4.2)
Owner
Max
Software Developer Web/Electronics
Max
This package allows you to easily work with NanoID in your Laravel models.

Laravel Model UUIDs Introduction Huge thanks to Micheal Dyrynda, whose work inspired me to create this package based on laravel-model-nanoid but uses

Parables Boltnoel 3 Jul 27, 2022
laravel-wallet - Easy work with virtual wallet.

laravel-wallet - Easy work with virtual wallet. [Documentation] [Get Started] [Документация] [Как начать] Vendor: bavix Package: laravel-wallet Versio

bavix 789 Dec 29, 2022
This package aims to help you standardize all your API responses in a simple and structured way.

Laravel API Response This package aims to help you standardize all your API responses in a simple and structured way. By default, the stucture of the

Kode Pandai 6 Dec 6, 2022
Easy creation of slugs for your Eloquent models in Laravel

Eloquent-Sluggable Easy creation of slugs for your Eloquent models in Laravel. NOTE: These instructions are for the latest version of Laravel. If you

Colin Viebrock 3.6k Dec 30, 2022
🏭 An easy way to generate populated factories for models.

Laravel Populated Factory provides an easy way to generate populated factories for models according to types & names of their columns. Install You can

Coderello 241 Nov 25, 2022
Simple Arabic Laravel Dashboard , has basic settings and a nice layout . to make it easy for you to create fast dashboard

Simple Arabic Laravel Dashboard ✅ Auto Seo ✅ Optimized Notifications With Images ✅ Smart Alerts ✅ Auto Js Validations ✅ Front End Alert ✅ Nice Image V

Peter Tharwat 254 Dec 19, 2022
A package that makes it easy to have the `artisan make:` commands open the newly created file in your editor of choice.

Open On Make A package that makes it easy to have the artisan make: commands open the newly created file in your editor of choice. Installation compos

Andrew Huggins 94 Nov 22, 2022
A collection of extensions for Laravel development in Visual Studio Code

Laravel Extension Pack for Visual Studio Code Includes the basic extensions to get started with Laravel development in Visual Studio Code. Laravel Ext

Winnie Lin 24 Dec 25, 2022
A simple to use opinionated ERP package to work with Laravel

Laravel ERP A simple to use opinionated ERP package to work with Laravel Installation You can install the package via composer: composer require justs

Steve McDougall 16 Nov 30, 2022
An extended laravel eloquent WHERE method to work with sql LIKE operator.

Laravel Eloquent WhereLike An extended laravel eloquent WHERE method to work with sql LIKE operator. Inspiration The idea of this package comes from o

Touhidur Rahman 33 Aug 6, 2022
Laravel package to work with geospatial data types and functions.

Laravel Spatial Laravel package to work with geospatial data types and functions. For now it supports only MySql Spatial Data Types and Functions. Sup

Tarfin 47 Oct 3, 2022
Localization Helper - Package for convenient work with Laravel's localization features and fast language files generation

Localization Helper Package for convenient work with Laravel's localization features and fast language files generation. Installation Via Composer $ c

Galymzhan Begimov 0 Jul 13, 2019
Laravel-Mediable is a package for easily uploading and attaching media files to models with Laravel 5.

Laravel-Mediable Laravel-Mediable is a package for easily uploading and attaching media files to models with Laravel. Features Filesystem-driven appro

Plank Design 654 Dec 30, 2022
An Eloquent Way To Filter Laravel Models And Their Relationships

Eloquent Filter An Eloquent way to filter Eloquent Models and their relationships Introduction Lets say we want to return a list of users filtered by

Eric Tucker 1.5k Jan 7, 2023
Record the change log from models in Laravel

This package will help you understand changes in your Eloquent models, by providing information about possible discrepancies and anomalies that could

Owen IT Services 2.5k Dec 30, 2022
Automatically validating Eloquent models for Laravel

Validating, a validation trait for Laravel Validating is a trait for Laravel Eloquent models which ensures that models meet their validation criteria

Dwight Watson 955 Dec 25, 2022
Laravel Ban simplify blocking and banning Eloquent models.

Laravel Ban Introduction Laravel Ban simplify management of Eloquent model's ban. Make any model bannable in a minutes! Use case is not limited to Use

cybercog 879 Dec 30, 2022
cybercog 996 Dec 28, 2022
The package lets you generate TypeScript interfaces from your Laravel models.

Laravel TypeScript The package lets you generate TypeScript interfaces from your Laravel models. Introduction Say you have a model which has several p

Boris Lepikhin 296 Dec 24, 2022