Handling Mysql Spatial datatypes in Laravel Eloquent ORM

后端 未结 2 1574
醉酒成梦
醉酒成梦 2021-02-12 12:49

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 solutio

2条回答
  •  南笙
    南笙 (楼主)
    2021-02-12 13:46

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

提交回复
热议问题