【问题标题】:Handling Mysql Spatial datatypes in Laravel Eloquent ORM在 Laravel Eloquent ORM 中处理 Mysql 空间数据类型
【发布时间】:2015-08-21 08:22:32
【问题描述】:

如何在 eloquent ORM 中处理 mysql 空间数据类型?,这包括如何创建迁移、插入空间数据和执行空间查询。如果不存在实际的解决方案,是否有任何解决方法?

【问题讨论】:

标签: php laravel eloquent laravel-5 geospatial


【解决方案1】:

我前段时间实施的一种解决方法是在模型上使用纬度和经度字段并进行以下验证(请参阅Validator class):

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

神奇的是模型的boot method,它设置了空间点字段的正确值:

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

【讨论】:

  • 您现在可以在 Innodb 引擎的 Spatial 数据类型上创建索引。 (来自 Mysql 5.7)
  • geoToPoint() 是从哪里来的?
  • geoToPoint 只是一个连接纬度和经度的辅助函数,它返回以下内容: $latitude 。 “”。 $经度;
【解决方案2】:

可以使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    相关资源
    最近更新 更多