ウェブアプリを開発していると、位置情報を活用した機能を追加したくなることがあります。
こういうとき、double型などで緯度・経度を格納してしまうと、データの再利用性に難が生じます。「今いる場所から半径○メートル以内を検索」とかいうことが、難しくなってしまうんですね。
MySQLにはGeometory型という位置情報を格納するためのデータ型が用意されています。Geometory型を使うと、地理的な検索機能を使用することができる。LaravelからGeometory型を扱えるようにするナイスなライブラリ「Laravel MySQL Spatial extension」を見つけましたので、備忘録を兼ねて、使い方を紹介したいと思います。
環境
Laravel 6でやってみます。
$php artisan -V
Laravel Framework 6.20.8
$sudo mysql -V
mysql Ver 15.1 Distrib 10.1.37-MariaDB, for debian-linux-gnueabihf (armv8l) using readline 5.2
ちなみに、SQLiteでも動作しました。データベースの仕様に合わせて、うまい具合にパースしてくれるようです。
インストール
Composerでgrimzy/laravel-mysql-spatial
をインストールします。
$ composer require grimzy/laravel-mysql-spatial:^3.0
LaravelとMySQLのバージョンにより、インストールすべきバージョンが異なります。環境に合わせて、適切なバージョンをインストールしてください。
1.x.x: MySQL 5.6 (also supports MySQL 5.5 but not all spatial analysis functions)
2.x.x: MySQL 5.7 and 8.0 (Laravel version < 8.0)
3.x.x: MySQL 8.0 with SRID support (Laravel version < 8.0)
4.x.x: MySQL 8.0 with SRID support (Laravel 8+) [Current branch]
5.x.x: MySQL 5.7 and 8.0 (Laravel 8+)
使用してみる
【手順1】マイグレーションファイルの作成
プラグインをインストールすると、Point型とPolygon型が使用できるようになります。
基本的にはPoint型を使用します。緯度と経度で表される1地点の位置情報を扱えます。現在地や地図上のマーカーを保存したい場合にはpoint型を使用します。Polygon型はPointの集合体で、地図上の範囲を保存したい場合に使用します。
マイグレーションファイルの作成は、通常とまったく変わりません。
$ php artisan make:migration create_samples_table
useの追加は不要です。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSamplesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('samples', function (Blueprint $table) {
$table->bigIncrements('id');
$table->point('point')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('samples');
}
}
マイグレーションします。
$php artisan migrate:fresh
【手順2】モデル作成
モデルの作成も通常通りでOKです。
$ php artisan make:model Sample
データを追加・取得してみる
マイグレーションがうまくいったら、データベースに位置情報を登録してみましょう。
データ登録
コントローラーを作成して、データをインサートしてみます。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Sample;
use Grimzy\LaravelMysqlSpatial\Types\Point;//Pointの使用に必要
class RideController extends Controller
{
public function indexRegNewRide(Request $request)
{
// インスタンス作成
$sample = new Sample();
// 緯度,経度で入力します
$sample ->point=new Point(35.6684415,139.6007843);//都庁の位置情報
// データベースに追加
$sample ->save();
// OK!と表示
return "OK!";
}
}
データ取得
インサートしたデータを取得してみます。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Sample;
use Grimzy\LaravelMysqlSpatial\Types\Point;//Pointの使用に必要
class RideController extends Controller
{
public function indexRegNewRide(Request $request)
{
// インスタンス作成
$sample = new Sample();
// データベース全件取得
$data = $sample -> get();
// データを表示
dd($data);
}
}
まとめ
Laravel MySQL Spatial extensionを使用して、位置情報をデータベースに登録する方法を紹介しました。なんといっても、インストールするだけでOKという手軽さがいいですね。位置情報を活用したちょっとしたWebサービスを構築したいとき、大いに活躍してくれそうです。
コメント