Handling Mysql Spatial datatypes in Laravel Eloquent ORM

孤人 提交于 2019-12-21 06:57:59

问题


How to handle mysql spatial datatypes in eloquent ORM?, This include how to create migration, insert spatial data and performing spatial query's. If there is not actual solutions exists, is there any workarounds?


回答1:


A workaround I have implemented a while ago is to have a latitude and longitude fields on the model with the following validations (see Validator class):

$rules = array('latitude' => 'required|numeric|between:-90,90',
                            'longitude'=>'required|numeric|between:-180,180',)

The magic comes on the boot method of the model, which sets the correct value of the spatial point field:

/**
 * Boot method
 * @return void
 */
public static function boot(){
    parent::boot();
    static::creating(function($eloquentModel){

        if(isset($eloquentModel->latitude, $eloquentModel->longitude)){
            $point = $eloquentModel->geoToPoint($eloquentModel->latitude, $eloquentModel->longitude);
            $eloquentModel->setAttribute('location',  DB::raw("GeomFromText('POINT(" . $point . ")')") );
        }

    });

    static::updated(function($eloquentModel){

        if(isset($eloquentModel->latitude, $eloquentModel->longitude)){
            $point = $eloquentModel->geoToPoint($eloquentModel->latitude, $eloquentModel->longitude);
            DB::statement("UPDATE " . $eloquentModel->getTable() . " SET location = GeomFromText('POINT(" . $point . ")') WHERE id = ". $eloquentModel->id);
        }

    });
}

About migrations, like @jhmilan says you can always use the Schema::create and DB::statement methods to customize the migration.

Schema::create('locations', function($table){
        $table->engine = "MYISAM";
        $table->increments('id')->unsigned();
        $table->decimal('latitude', 10, 8); 
        $table->decimal('longitude', 11, 8);
        $table->timestamps();
    });

    /*Espatial Column*/
    DB::statement('ALTER TABLE locations ADD location POINT NOT NULL' );
    /*Espatial index (MYISAM only)*/
    DB::statement( 'ALTER TABLE locations ADD SPATIAL INDEX index_point(location)' );



回答2:


It is available to use https://github.com/grimzy/laravel-mysql-spatial

you may use:

namespace App;

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

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

    protected $fillable = [
        'name',
    ];

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

then you are able to run queries on the 'location' field.

to store model you may use:

$place1 = new Place();
$place1->name = 'Empire State Building';
$place1->location = new Point(40.7484404, -73.9878441);
$place1->save();

to retrieving a model you should use:

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


来源:https://stackoverflow.com/questions/30682538/handling-mysql-spatial-datatypes-in-laravel-eloquent-orm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!