Laravel package to work with geospatial data types and functions.

Overview

Laravel Spatial

Latest Version on Packagist Total Downloads GitHub Actions

Laravel package to work with geospatial data types and functions.

For now it supports only MySql Spatial Data Types and Functions.

Supported data types:

  • Point

Available Scopes:

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

Installation

You can install the package via composer:

composer require tarfin-labs/laravel-spatial

Usage

Generate a new model with a migration file:

php artisan make:model Address --migration

To avoid Doctrine\DBAL\Exception : Unknown database type point requested, Doctrine\DBAL\Platforms\MySQL80Platform may not support it. exception, extend the migration file from TarfinLabs\LaravelSpatial\Migrations\SpatialMigration and add a spatial column. It just adds point type to Doctrine mapped types.

use TarfinLabs\LaravelSpatial\Migrations\SpatialMigration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends SpatialMigration {
    
    public function up(): void
    {
        Schema::create('addresses', function (Blueprint $table) {
            $table->point('location');
            
            $table->spatialIndex('location');
        })
    }

}

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
    ];

}

Filter addresses within 10 km of 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();

Select distance to given coordinate as meter:

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

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

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:

use App\Models\Address;

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

Testing

composer test

Todo

  • Proper documentation.
  • Missing tests.

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

Laravel Package Boilerplate

This package was generated using the Laravel Package Boilerplate.

You might also like...
webtrees module: enhanced clippings cart with more functions to add records to the clippings cart and to start actions on these records
webtrees module: enhanced clippings cart with more functions to add records to the clippings cart and to start actions on these records

webtrees module hh_clippings_cart_enhanced !!! This is an alpha version! Do not use it in a productive webtrees system! !!! This webtrees custom modul

Laravel basic Functions, eloquent cruds, query filters, constants

Emmanuelpcg laravel-basics Description Package with basic starter features for Laravel. Install If Builder Constants Install composer require emmanuel

A collection of helper functions that I use across my projects.

A collection of helper functions that I use across my projects. This package includes some of the helper functions that I tend to use in all of my pro

Smeify is a Stable Automated Solution for Airtime and Data businesses in Nigeria, this package helps you integrate smeify easily into your laravel application.

Smeify is a Stable Automated Solution for Airtime and Data businesses in Nigeria, this package helps you integrate smeify easily into your laravel application.

A PHP package that provides common Data and Value Objects, that are Laravel castable.

Common Casts A PHP package that provides common Data and Value Objects, that are Laravel castable. Installation composer require juststeveking/common-

Flow package to synchronize metadata and binary data of imported Neos.Media assets

Wwwision.AssetSync Flow package to synchronize metadata and resources of imported Neos.Media assets Installation Install this package via: composer re

An easy way to get vendor and package data from Packagist via API calls
An easy way to get vendor and package data from Packagist via API calls

Laravel Packagist Laravel Packagist (LaravelPackagist) is a package for Laravel 5 to interact with the packagist api quickly and easily. Table of cont

Data Table package with server-side processing, unlimited exporting and VueJS components
Data Table package with server-side processing, unlimited exporting and VueJS components

Data Table package with server-side processing, unlimited exporting and VueJS components. Quickly build any complex table based on a JSON template.

Save Model is a Laravel package that allows you to save data in the database in a new way.

Save Model is a Laravel package that allows you to save data in the database in a new way. No need to worry about $guarded and $fillable properties in the model anymore. Just relax an use Save Model package.

Comments
  • 1582 Incorrect parameter count in the call to native function 'ST_SRID'

    1582 Incorrect parameter count in the call to native function 'ST_SRID'

    SQLSTATE[42000]: Syntax error or access violation: 1582 Incorrect parameter count in the call to native function 'ST_SRID' (SQL: select `id`, `user_id`, `location` from `user_profiles` where `online` = 1 and `updated_at` >= 2022-02-03 15:09:51 and `location` is not null and ST_Distance( ST_SRID(location, 0), ST_SRID(Point(93.045724, -8.834381), 0) ) <= 20000)
    
    opened by Saifallak 4
  • Handling spatial indexes for NULLable POINT columns

    Handling spatial indexes for NULLable POINT columns

    👋 Hi there! As I was integrating this package with my application, I found out it's not possible to add a SPATIAL index on a POINT column if it supports NULL values. More info here and here.

    Because only some rows in my table have location data associated, querying is slow without a spatial index. It seems as though the suggested way around this is to set a default POINT(0 0) value on all records without location data.

    I can do this easily enough with an Eloquent model event:

    public static function booted(): void
    {
        // When a Model is being created, set its location field to a neutral Point(0 0) if not already set.
        static::creating(static function(Model $model) {
            foreach ($model->getLocationCastedAttributes() as $column) {
                if ($model->{$column} === null) {
                    $model->{$column} = new Point();
                }
            }
        });
    }
    

    This now allows for spatial indexing to be used. However, the package's scopes become a lot harder to use practically. For example, calling Address::withinDistanceTo('location', new Point(25.45634, 35.54331), 10000000)->get() could incorrectly include records with POINT(0 0) set (or whatever default is used).

    I appreciate the HasSpatial trait can be extended, and developers can override each method with an extra $query->whereRaw("ST_ASTEXT({$column}) = 'POINT(0 0)'") clause. Developers could also add their own scope method to their models, but would have to remember to call it every single time, which isn't ideal.

    So it would be fantastic if support for this could be built-in natively somehow — especially if more scopes are likely to be added as the roadmap progresses in future.

    Thanks for a really useful package! 🚀

    opened by JackWH 1
  • Latitude / Longitude shouldn't be cast to float values

    Latitude / Longitude shouldn't be cast to float values

    This is unlikely to affect 99% of developers, but just throwing it out there as a similar issue caught me out before 🙃

    The TarfinLabs\LaravelSpatial\Types\Point class treats latitude/longitude as a float. Most PHP installations will be able to handle up to 11 decimal places (but the precision can vary in php.ini).

    However, the POINT type in MySQL supports up to 25 bytes of resolution. So if this package is used against any existing high-precision POINT values, it would lose data when saving the model back to the database.

    I think the correct approach would be to use protected string $lat; in the Point class, and construct it with __construct(string|float $lat = 0 ...) etc... The getLat(): float method would still automatically cast as a float before returning, but the toPair() method should be changed to use the original string values of the properties. This would ensure the full precision is persisted back to the database by the LocationCast class.

    Again, unlikely to affect most people — just worth mentioning for best practice 👍

    opened by JackWH 0
  • if location is null, getting error

    if location is null, getting error

    always getting this error if location col. is null

    because of $casts in the model

    explode(): Argument #2 ($string) must be of type string, null given
    exception: "TypeError",
    "/var/www/sonbla/releases/8/vendor/tarfin-labs/laravel-spatial/src/Casts/LocationCast.php"
    line: 18,
    
    opened by Saifallak 2
Releases(v1.4.1)
Owner
Tarfin
Tarfin
cybercog 996 Dec 28, 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
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
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
This package provides new helper functions that take care of handling all the translation hassle and do it for you.

Laravel Translate Message ?? This package provides new helper functions that take care of handling all the translation hassle and do it for you. Insta

Basel Rabia 17 Feb 8, 2022
Postgis extensions for laravel. Aims to make it easy to work with geometries from laravel models.

Laravel Wrapper for PostgreSQL's Geo-Extension Postgis Features Work with geometry classes instead of arrays. $model->myPoint = new Point(1,2); //lat

Max 340 Jan 6, 2023
Collection of agnostic PHP Functions and helpers with zero dependencies to use as foundation in packages and other project

Collection of agnostic PHP Functions and helpers This package provides a lot of very usefull agnostic helpers to use as foundation in packages and oth

padosoft 54 Sep 21, 2022
Deploy and execute non-PHP AWS Lambda functions from your Laravel application.

Sidecar for Laravel Deploy and execute non-PHP AWS Lambda functions from your Laravel application. Read the full docs at hammerstone.dev/sidecar/docs.

Hammerstone 624 Dec 30, 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
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