GTFSを触ってみた

GTFSとは何ぞや

GTFSはGeneral Transit Feed Specificationの略で、「公共交通機関の時刻表と地理的情報に関するオープンフォーマット」(Wiki情報)のこと。直訳すると、”一般的な乗換案内の仕様”となります。公共交通データのデファクトスタンダードになっています。
GTFSは、オレゴン州のポートランドでバスや鉄道を運営するTriMetがGoogleと協力し、乗換案内データのフォーマットを策定したものが始まりです。

GTFSには静的データと動的データの2種類があります。静的データは単にGTFS、もしくは静的GTFSと呼ばれ、動的データはGTFSリアルタイムと呼ばれます。GTFSリアルタイムはGTFSの拡張です。

GTFS-JPとは、GTFSを日本向けに拡張したものです。標準的なバス情報フォーマットとは、このGTFS-JPとGTFSリアルタイムの2つのフォーマットを含有するフォーマットのことです。2017年に国土交通省が策定しました。

GTFS(GTFS-JP)のデータ

GTFS(GTFS-JP)のデータ形式はzip形式です。zipファイル内にコンマ区切り形式のファイルを複数作成します。このコンマ区切り形式のファイルの拡張子は.txtとします。改行文字はCRLFまたはLF、文字コードはUTF-8とします。

これについてはGoogleのリファレンスや国土交通省の『静的バス情報フォーマット(GTFS-JP)仕様書』が詳しいです。既存のもので十分なのでここでは説明を省きます。
一度どこかの会社のデータを見てみると何となく雰囲気が掴めるでしょう。txtファイル自体を開いてもいいですし、GTFS Viewer(http://app.linkdata.org/run/app1s1493i)を使うと視覚的に理解できます。

ファイル一覧を眺めると、末尾に”_jp”とあるものとないものがあるかと思います。”_jp”とあるものはGTFS-JPで拡張されたもの、”_jp”とないものはGTFS元来のものになります。また、フィールド名の先頭に”jp_”とあるものはGTFS-JPで拡張されたもの、”jp_”とないものはGTFS元来のものです。

GTFSリアルタイムのデータ

GTFSリアルタイムのデータ形式は、プロトコルバッファです。プロトコルバッファとは、Googleが開発したバイナリ形式のシリアライズフォーマットです。拡張子はbinだったりpbだったりします。

データを見る

プロトコルバッファファイルは、バイナリ形式なのでそのままでは読むことができません。これをパースする必要があります。
パースする方法についてはある程度Googleにサンプルが載っています(https://developers.google.com/transit/gtfs-realtime/examples/code-samples)。

今回はPHPを例にデータを見ていこうと思います。
まず、Composerにgoogle/gtfs-realtime-bindingsパッケージを追加します。

データを用意します。今回は宇野バスのオープンデータをお借りしました。
GTFS_RT.bin・GTFS_RT-VP.bin・GTFS_RT-Alert.binの三種類のファイルがあります。
それぞれ順に遅延情報・車両情報・アラートを表します。
実験用に各ファイルを保存しておきましょう。

例えば、GTFS_RT.binでgetfs_realtime_versionフィールドを取得するには、以下のようにします。

<?php
require_once 'vendor/autoload.php';
use transit_realtime\FeedMessage;

$data = file_get_contents("GTFS_RT.bin");

$feed = new FeedMessage();
$feed->parse($data);

echo "getfs_realtime_version:\t";
var_dump($feed->getHeader()->getGtfsRealtimeVersion());

実行すると以下のようになります。

getfs_realtime_version: string(3) "1.0"

次に、message Position内のlatitudeフィールドを取得するには、以下のようにします。

<?php
require_once '../vendor/autoload.php';
use transit_realtime\FeedMessage;

$data = file_get_contents("GTFS_RT-VP.bin");

$feed = new FeedMessage();
$feed->parse($data);

foreach($feed->getEntityList() as $entity){
	if($entity->hasVehicle()){
		if($entity->getVehicle()->hasPosition()){
			$position = $entity->getVehicle()->getPosition();
			echo "latitude:\t";
			var_dump($position->getLatitude());
		}
	}
}

これを実行すると以下のようになります。

latitude:	float(34.665458679199)
latitude:	float(34.791370391846)
latitude:	float(34.661628723145)
latitude:	float(34.665554046631)
latitude:	float(34.671039581299)
latitude:	float(34.673313140869)
latitude:	float(34.736721038818)
latitude:	float(34.691162109375)

GTFS リアルタイム リファレンス(https://developers.google.com/transit/gtfs-realtime/reference/)と見比べてみてください。各フィールドの説明はリファレンスに全部載ってるのでそちらを参照してください。

上を見てもらえればフィールド名とタイプとメソッドの関係が分かってもらえるのではないかと思います。

基数が複数の場合、そのフィールドには複数の要素が入る可能性があるのでget****List()を用いてforeachするのが良いかと思います。ex. foreach($feed->getEntityList() as $entity){}

データの使いどころ

例えばGoogleMap。

こんな感じで時刻・系統名・行先・乗り場等々のデータが出せます。関東自動車はGoogleにGTFS-JPとGTFS-RTを提供しているようで、マップ上にバスの位置が表示されます(モバイル版のみ)。バスマークの白い円形のアイコンがマップ上を動きます。

こんな感じのことができるっぽいので、何か面白いものが出来ないか思案中。。。

 

参考ページ

技術資料(仕様書、ガイドライン)(2019年3月)(国土交通省) http://www.mlit.go.jp/sogoseisaku/transport/sosei_transport_tk_000112.html
標準的なバス情報フォーマット https://www.gtfs.jp/
GTFS https://gtfs.org/
静的な GTFS の概要 https://developers.google.com/transit/gtfs/
GTFS リアルタイムとは https://developers.google.com/transit/gtfs-realtime/

コメント

タイトルとURLをコピーしました