🌏️

GTFS-RTを触ってみよう

2024/12/14に公開

この記事は Social Databank Advent Calendar 2024 の 14 日目の記事です。

はじめに

皆さんは GTFS と GTFS-RT というものをご存知でしょうか?

GTFS

GTFS は General Transit Feed Specification の略で公共交通機関の時刻表と地理的情報に関するオープンフォーマットです。

公共交通機関のルートや停車時刻等の情報をそれぞれ CSV ファイルに記述し、CSV ファイルを 1 つの ZIP ファイルにまとめたものになります。

GTFS は GTFS-static と呼ばれることもあります。

GTFS-RT

GTFS-RT(GTFS-realtime) は公共交通機関のリアルタイムな運航状況に関するフォーマットです。

ルートの最新情報や運航状況、車両位置情報を Protocol Buffers 形式の API によって提供しています。

Protocol Buffers の説明に関してはこの記事ではしないので、気になる方は調べてみて下さい。

GTFS を静的なものとした場合 GTFS-RT は動的なものになります。そのため GTFS-RT は GTFS を補完し提供する情報に付加価値を与えるものになります。

活用例

GTFS は公共交通機関のオープンデータに関してデファクトスタンダードになっています。

Google や Apple の地図アプリの乗り換え検索で電車やバスの遅延情報が表示されたりするのは、この GTFS と GTFS-RT を活用したものになります。

GTFS-JP について

GTFS-JP は GTFS を元に日本で使うにあたって拡張されたフォーマットになります。

国土交通省のサイトでは GTFS-JP の仕様書 が公開されていて、仕様書内で「標準的なバス情報フォーマット」として GTFS-JP を定めています。

この記事ではこれ以降 GTFS といえば GTFS-JP のことを指すことにします。

国土交通省のサイトや GTFS(-JP)について解説しているサイトでは、GTFS を「静的バス情報フォーマット」、GTFS-RT を「動的バス情報フォーマット」と呼んでいる場合もあります。

電車等でも使われているのに「バス情報フォーマットなのかよ」という声が聞こえてきそうですが、気にしないことにします。

実際に GTFS-RT を触ってみよう

GTFS は CSV ファイルがまとめられた ZIP ファイルのため各プログラミング言語のライブラリを使うと割と簡単に扱うことが可能だと思います。そのためこの記事では GTFS-RT を触ってみることにします。

今回は 公共交通オープンデータセンター が公共交通オープンデータチャレンジ 2024 の一環として限定公開している JR 東日本の関東エリアの一部路線の運行情報のデータ を使用して JR の運行情報を表示してみようと思います。

今回使用する運行情報のデータは公共交通オープンデータセンター開発者サイトにユーザー登録し、チャレンジ専用の API キーを発行する必要があります。

ユーザー登録の際に公共交通オープンデータセンターの方で確認作業があるようなので、ユーザー登録の際は登録情報に不備が無いかきちんと確認しましょう。(申請から開発者サイトにアクセスできるようになるまで時間がかかります)

自分はユーザー登録の際に部屋番号を入れ忘れる不備があったため、1 度ユーザー登録ができませんでした。

今回は TypeScript を使用して GTFS-RT を扱うコードを作成しました。作成したコードは以下のようになります。このコードをトランスパイルして実行すると JR にて遅延等が発生している際に運行情報を取得できます。

import axios from "axios";
import { transit_realtime } from "gtfs-realtime-bindings";

const API_KEY = process.env.API_KEY;

const main = async () => {
  try {
    const { data } = await axios.get<ArrayBuffer>(
      "https://api-challenge2024.odpt.org/api/v4/gtfs/realtime/jreis_odpt_train_alert",
      {
        params: {
          "acl:consumerKey": API_KEY,
        },
        responseType: "arraybuffer",
      }
    );
    const feed = transit_realtime.FeedMessage.decode(new Uint8Array(data));

    console.log(JSON.stringify(feed.entity));
  } catch (error) {
    console.error("Error fetching data:", error);
  }
};

(async () => {
  await main();
})();

コードの簡単な解説をしていきます。

1〜2 行目では必要なライブラリを読み込んでいます。今回使用するライブラリは HTTP クライアントの axios と GTFS-RT 用の Protocol Buffers の binding である gtfs-realtime-bindings です。

8〜16 行目で API を叩いて、データを取得しています。公共交通オープンデータセンターが提供しているデータで API キーが必要なものものに関してはクエリパラメータにacl:consumerKeyというキーで API キー を渡してあげる必要があります。

Protocol Buffers のデータはバイナリデータなので、axios に受信するファイルはバイナリデータだよと教えるために axios のオプションにresponseType: "arraybuffer"を追加します。

17 行目で axios で取得した Protocol Buffers のデータをデコードして TypeScript のオブジェクトにします。

ここまで実行すると、オブジェクトになっているので取得したデータを自由自在に扱うできます。

データの構造がどのような形式になっているかは Google のドキュメント が詳しいため、気になる人はぜひ確認してみて下さい。

最後に

GTFS で提供される停車時刻等の情報と GTFS-RT で提供される運行情報等を組み合わせると 少し前に Twitter[1]で話題になっていた 大学の最寄り駅の電子時刻表 のようなものを自作できると思います。

現在 GTFS と GTFS-RT、Lambda を組み合わせて Slack に通勤時に使うルートの遅延情報を投稿してくれる Bot を作成しています。遅延等が発生しないとデバックできないので、なかなか完成しません...

脚注
  1. Twitter と西武ドームに関しては絶対に今の名前で呼ばないと決めています。 ↩︎

ソーシャルデータバンク テックブログ

Discussion