web-dev-qa-db-ja.com

Laravel EloquentORMでのMysql空間データ型の処理

雄弁なORMでmysql空間データ型を処理する方法は?、これには、移行の作成、空間データの挿入、および空間クエリの実行方法が含まれます。実際の解決策が存在しない場合、回避策はありますか?

19
Jithin Jose

しばらく前に実装した回避策は、次の検証を使用してモデルに緯度と経度のフィールドを設定することです( バリデータークラス を参照)。

$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 :: 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)' );
10
Emilio Borraz

使用可能です 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
0