GTFS を Deck.gl のデータ形式に変換する
先日「Geospatial Hackers Program 沖縄」というハッカソンに出た際に GTFS という形式のデータを使った。
このデータ形式はバスなどの公共交通機関の時間表をオープンデータにする際の一般的なフォーマットらしい。
ハッカソンではこの形式のデータを Deck.gl の TripLayer に適応させ、地図上で移動を表現した作品を作りました。
ただその際に GTFS 形式のデータを Deck.gl 用に変換するのが面倒でした。
今回は GTFS についてまとめるのと同時に Deck.gl(TripLayer)用に変換するノウハウを紹介したいと思います。
ちなみにハッカソンは沖縄で開催されたこちらです。
リモート参加したのですが、楽しくできました。
ghp.connpass.com
作品(Github)はこちら
GTFS(General Transit Feed Specification)とは
GTFS とは公共交通機関の時刻表と地理的情報に関するオープンフォーマットのことを言います。
GTFS と調べるとよく Google の乗り換え案内などがヒットするが Google は GTFS 形式で公共交通機関の情報を配信しているらしい。
GTFS には動的なものと静的なものが存在します。
動的なものはリアルタイムでバスや船の位置を把握することができるものです。
静的なものは単に時刻表で 1 日の位置がわかります。
GTFS は Zip ファイルに格納されたテキストファイルで構成します。
ファイルには停車地点、ルート、時刻などそれぞれの情報を表すものが分割されています。
ファイル一覧は以下のページに記載されています。
これらのファイルを用意すると GTFS として配信することが出来ます。
Deck.gl
言わずとしれた Uber 社のデータビジュアライズツールです。
Deck.gl は WebGL を使用するため 3D のデータ表現に長けています。
例えば ArcLayer を使うと飛行機の移動や人流データを表現することができます。
今回は船の移動を表現したかったので TripLayer を使いました。
この https://deck.gl/#/examples/overview を見るといろんな活用法が見れて想像力が駆り立てられますね。
実装
それでは実装していきます。
まずデータ集めですが、日本の公共交通機関は以下のサイトに集まっています。
ここからハッカソンのテーマであった沖縄の交通機関に関するデータを落としてきました。
あるファイルを zip でダウンロードしたあとに解凍すると先程のリファレンスに合ったようなファイルがありました。
ただ空のファイルも中にはあり、今回必要となるのが時刻とその時の緯度経度だけなので最終的に使ったファイルは「#」のついたものだけです。
. ├── agency.txt ├── calendar.txt ├── calendar_dates.txt ├── fare_attributes.txt ├── fare_rules.txt # 旅程(始点と終点を結ぶために使用) ├── frequencies.txt ├── routes.txt ├── shapes.txt ├── stop_times.txt # 時間 ├── stops.txt # 停車位置 ├── transfers.txt └── trips.txt # 船便
これらの ER 図を書くと以下のようになります。
このように正規化されたテーブル構造になっているため SQL で join するのも一つの手だと思われますが、Python の DataFrame を使うと割と簡単に join できました。
ソースコード https://github.com/hiracky16/ghp-hackathon-team-conviction/blob/master/make_data/script.py
作るデータ形式は以下のようなものです。これが TripLayer で読むことのできる形式です。 https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/trips/trips-v7.json
データの作成が終わったらあとはデータを読み込むだけです。
まとめ
GTFS 形式のデータを扱ったのが初めてだったのでまとめてみました。
今回扱ったのは静的なデータだったためいつか動的なものも扱ってみたいと思いました。
今回データの変換には Python を使いましたが、GTFS → Deck.gl への適応はこれから多用すると外でも使えると思うので npm モジュールなどほしいなと思いました。
時間があれば自作してみようと思います。