Обработка Mysql пространственных типов данных в Laravel Eloquent ORM

Как работать с пространственными типами данных mysql в красноречивом ORM ?, в том числе как создавать миграцию, вставлять пространственные данные и выполнять пространственные запросы. Если реальных решений не существует, есть ли обходные пути?

18

Решение

Обходной путь, который я реализовал некоторое время назад, состоит в том, чтобы иметь поля широты и долготы в модели со следующими проверками (см. Класс валидатора):

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

Магия приходит на метод загрузки модели, которая устанавливает правильное значение поля пространственной точки:

/**
* 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);
}

});
}

Что касается миграций, например, @jhmilan говорит, что вы всегда можете использовать методы операторов Schema :: create и DB :: для настройки миграции.

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)' );
9

Другие решения

Доступно для использования https://github.com/grimzy/laravel-mysql-spatial

Вы можете использовать:

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',
];
}

тогда вы сможете выполнять запросы в поле «местоположение».

для хранения модели вы можете использовать:

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

для извлечения модели вы должны использовать:

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

По вопросам рекламы [email protected]