Laravel上で地理情報を扱う
Laravel Magellanというパッケージを使うと、Laravel上で地理情報データを扱うのが楽になるため、簡単に紹介します。
必須条件
- Laravel 11.x / 12.x
- PHP 8.2+
- PostGISをインストール済みのPostgreSQL DB
インストール
composer でパッケージをインストールします:
composer require clickbar/laravel-magellan
マイグレーションを行います:
php artisan vendor:publish --tag="magellan-migrations"
php artisan migrate
固有なconfigを持つので、追加します:
php artisan vendor:publish --tag="magellan-config"
PostGISカラムをテーブルに作る
magellanで始まるメソッドが追加されているので、これらを駆使してPostGISカラムを追加できます:
// Deprecated, use the new Laravel methods instead ->geometry('location', 'POINT', 4326)
$table->magellanPoint('location', 4326);
// Special column types (not deprecated)
$table->magellanBox2D('bounds2d');
$table->magellanBox3D('bounds3d');
$table->magellanGeometryCollection('collection');
$table->magellanGeometryCollectionM('collection_m');
$table->magellanGeometryCollectionZ('collection_z');
$table->magellanGeometryCollectionZM('collection_zm');
但し、Laravel 11.x以降は本家もgeometry/geographyサポートがあるため、基本的な型はそっちを使うようです。
Modelの準備
$castsに定義を加えることで、扱いやすくなります:
protected $casts = [
/** ... */
'location' => Point::class,
'bounds' => Box2D::class,
];
ジオメトリーデータクラス
これらのクラスが使えます:
- Point
- LineString
- Polygon
- MultiPoint
- MultiLineString
- MultiPolygon
- GeometryCollection
例えばPOINT型のオブジェクトを生成するには:
$point = Point::make(51.087, 8.76);
他、突っ込んだ話は、参考記事をどうぞ。
ジェネレーター&パーサー
下記の表現を解釈できます:
- EWKB
- EWKT
- GeoJson
例えばGeoJSON文字列を得るには:
$point = Point::makeGeodetic(51.087, 8.76);
json_encode($point); // returns GeoJson
// "{"type":"Point","coordinates":[8.76,51.087]}"
他、突っ込んだ話は、参考記事までどうぞ。
フォームリクエストの検証と変換
GeoJSON文字列で渡されるなら、GeometryGeojsonRuleが使えます。
また、トレイトTransformsGeojsonGeometryを使うことで、GeoJSON文字列からジオメトリーデータオブジェクトへの変換を支援します。
例えばこんな風に:
class StorePortRequest extends FormRequest
{
use TransformsGeojsonGeometry;
public function rules(): array
{
return [
'name' => ['required', 'string'],
'country' => ['required', 'string'],
'location' => ['required', new GeometryGeojsonRule([Point::class])],
];
}
public function geometries(): array
{
return ['location'];
}
}
詳しくは、参考記事まで。
(あまりいないかもしれないけれど)v1.xからv2.xへのアップグレードについて
参考記事によると、割と破壊的な変更が加わっていて、v2.xですっきり整理されたし覚えやすくなった気がします。
新規プロジェクトで、以前書いたコードを動かそうとしたら難儀したので、「全然変わってるじゃないか!」とつい叫んでしまいました。
v1.x普及期に書かれたweb記事を真似してコードを書くときには、結構な変更があるので、十分注意してください。
(わたしも直し中です、、)