在 Laravel Eloquent ORM 中处理 Mysql Spatial 数据类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30682538/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Handling Mysql Spatial datatypes in Laravel Eloquent ORM
提问by Jithin Jose
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?
如何在 eloquent ORM 中处理 mysql 空间数据类型?,包括如何创建迁移、插入空间数据和执行空间查询。如果不存在实际解决方案,是否有任何解决方法?
回答by Emilio Borraz
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):
我不久前实施的一种解决方法是在模型上使用纬度和经度字段,并使用以下验证(请参阅Validator 类):
$rules = array('latitude' => 'required|numeric|between:-90,90',
'longitude'=>'required|numeric|between:-180,180',)
The magic comes on the boot methodof the model, which sets the correct value of the spatial point field:
神奇的是模型的boot 方法,它设置了空间点字段的正确值:
/**
* 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.
关于迁移,就像@jhmilan 说的,你总是可以使用 Schema::create 和 DB::statement 方法来自定义迁移。
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)' );
回答by Mohammad Nourinik
It is available to use https://github.com/grimzy/laravel-mysql-spatial
可以使用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