GTFSリアルタイム v2.0 どこが新しくなったか？

この記事は、GTFSリアルタイム v2.0策定における主要な変更点を、規格策定者の一人であるSean Barbeau氏が ["What’s new in GTFS-realtime v2.0"](https://medium.com/@sjbarbeau/whats-new-in-gtfs-realtime-v2-0-cd45e6a861e9) というタイトルで記事にしたものです。現在、日本においても、「標準的なバス情報フォーマット」の一環としてGTFSリアルタイムをベースにしたデータ形式が標準化されようとしています。それに合わせて、技術をより深く知るためにこの記事を翻訳し、著者の許可を得て公開するものです。

- [元記事 "What’s new in GTFS-realtime v2.0"](https://medium.com/@sjbarbeau/whats-new-in-gtfs-realtime-v2-0-cd45e6a861e9)
- [GTFS リアルタイム v2.0 リファレンス](https://developers.google.com/transit/gtfs-realtime/reference/?hl=ja)
- [GTFS リアルタイム v1.0 リファレンス](https://developers.google.com/transit/gtfs-realtime/reference?hl=ja)

著者: Sean Barbeau
2017年9月25日
翻訳：孕石直子

----



映画『2001年宇宙の旅』の原作者の一人でイギリスの作家アーサー・C・クラークは、次のように言っている: 

> 十分に発達した科学は魔法と区別がつかない

100年前、世界初の路面電車がサンフランシスコで運行を開始した。もし当時の利用客にiPhoneを渡し、今地図上のどこを路面電車が走っているのかリアルタイムで示したり、到着時刻の予測までしたりしたら、大そう驚かれるだろう。


<div align="center">
<img src="https://qiita-image-store.s3.amazonaws.com/0/53416/2f4a2ebf-bf38-317d-7d3a-ae9055f4e950.png" "画像タイトル">
</div>

	100年前の開業当時のサンフランシスコの路面電車 (写真出典: SFMTA Photography Department and Archive,  https://tinyurl.com/ycq5asge )


今日ではそうしたスマートフォンの機能はもはや魔法ではなくなったが、それでも人々はやはりリアルタイム運行情報の恩恵を享受している。例えば:

- 感覚的待ち時間の短縮 [^1] [^2]
- 実際の待ち時間の短縮 [^1]
- 初めて乗る人にとっての学習しやすさ [^3]
- 利用者数の増加 [^4] [^7]
- 安心・安全な感覚（夜間など）[^5] [^6]

リアルタイム運行情報は質もまた重要である。ある研究では [^8]、9%の乗客が「リアルタイム運行情報の出す誤情報のせいで以前よりバスを利用しなくなった」と言った、とある。


長文になるので先に結論: GTFSリアルタイムv2.0は交通事業者にとって自社のリアルタイム運行情報の質を向上させるのに役立つ。—その詳細を語る前にまず、リアルタイム運行情報がどのようにバスから利用者の手の中に届くのか、基本を大まかに説明しよう。


## リアルタイムデータはどこから来る？

![スライド1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/53416/57593970-dd16-3c93-b7c1-f268a11839d4.jpeg)
 

	リアルタイム情報の交通事業者からスマートフォンアプリまでのフローの典型例

スマートフォンの交通アプリはリアルタイム運行情報を直接交通事業者から得る。リアルタイム運行情報は、大抵車両ロケーションシステムによって生成されたものである。初期の車両ロケーションシステムではリアルタイム運行情報の交換フォーマットは様々だった。それぞれの車両ロケーションシステムのメーカーがそれぞれのAPI仕様を持っていたからだ。しかしこの数年で交通事業者は[GTFSリアルタイム](https://github.com/google/transit/tree/master/gtfs-realtime)を標準フォーマットとし始めている。広く使われている[GTFSフォーマット](https://github.com/google/transit/tree/master/gtfs)と組になるものである。現在[TransitFeeds.com](http://transitfeeds.com/search?q=gtfsrt)では50以上の交通事業者がGTFSリアルタイムフィードを公開している。

GTFSリアルタイムは、[Trip Updates](https://github.com/google/transit/blob/master/gtfs-realtime/spec/en/trip-updates.md)（到着と出発の予想時刻）、 [Vehicle Positions](https://github.com/google/transit/blob/master/gtfs-realtime/spec/en/vehicle-positions.md) (その名の通り車両の位置)、[Service Alerts](https://github.com/google/transit/blob/master/gtfs-realtime/spec/en/service-alerts.md) (運休や遅延などについての可読形式での表現) についての情報をどのように交換するかを表現している。


## GTFSリアルタイムv1.0の何がいけなかったのか？
リアルタイム運行情報にデ・ファクト・スタンダードができるのはいいことだ。アプリ開発者はデータについて議論する必要がなくなり、新しい機能を生み出すことに専念できるようになる。

ところが、GTFSリアルタイムを使ううちに交通事業者やアプリ開発者はあることに気が付いた。それは、ほとんどのGTFSリアルタイムのフィールドが「省略可能」だということだ。正確には、63個あるGTFSリアルタイムのデータフィールドのうち必須なのはわずか7つ、全体の約11%だった。

「省略可能」のフィールドが大量にあるおかげで、車両ロケーションシステム開発者にとってGTFSリアルタイムv1.0に公式に準拠したGTFSリアルタイムフィードを公開することはとても簡単である。ほとんどの値を空白のままにすれば良いのだ。しかしそれでは重要な情報が欠けてしまうかもしれず、情報を使う側は大変困る。公共交通利用者はアプリが使えない情報を出すと不満を感じ、するとアプリ開発者と交通事業者は評判を落とし、すると車両ロケーションシステムメーカーは製品が品質基準を満たさないとのことで問題になる。

例を見てみよう。以下は車両位置についてGTFSリアルタイムv1.0に完全に準拠したフィードだ:

```json:
header {
  gtfs_realtime_version: "1.0"
}
entity {
  id: "d131dd02"
  vehicle {
    position {
      latitude: 28.04265
      longitude: -82.45945
    }
  }
}
```

重大な情報が欠けている:

- **この位置情報はいつ算出されたのか？** 1分前？1日前？
- **この車両は現在どの路線や便を運行中なのか？** 路線の形状と比較してどの路線を運行中か予想することもできるが、いいやり方ではない。
- **利用者に特定の車両をどのように伝えるのか？** まさかd131dd02がバスの便名ではあるまい…？

2つ目の例。GTFSリアルタイムv1.0において到着予測時刻を提供する時、`stop_sequence`のフィールドは省略可能である:

```json:
trip {
 trip_id: "277725"
}
stop_time_update {
 arrival {
   delay: 900 // 15 minutes
 }
 stop_id: “A”
}
```

このことについて、`stop_id`だけでもほとんどの路線で問題ない。しかしながら、停留所に2回以上立ち寄る循環のある路線では`stop_sequence`の値がないと問題になる。


 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/53416/05f9382c-5241-18b5-af04-ddcb98d62b55.png)

	停留所Aに2回停車する循環のある路線


バスが15分遅れたのは停留所Aに1回目に停車した時か、それとも2回目に停車した時か？これは大きな違いである。1回目と2回目の間にたくさんの停留所がある大きな循環線ではさらに違いが大きくなる。もし（15分の遅れが循環の前半で起こっていると思い）B停留所でバスを待つ利用者にコーヒーを1杯飲む時間があると伝え、（実際には遅れは循環の後半で起こっていたために）利用者が定刻通りに到着したバスを逃してしまったら、大変な迷惑をかけることになる。こうした場合にも正しい予想時刻を出すために`stop_sequence`のフィールドは必要なのだ。


## なぜこんなに多くの省略可能なフィールドがあるのか？ 

では、GTFSリアルタイムv1.0にはなぜこんなに多くの「省略可能」のフィールドがあり必須のフィールドが少ないのか？

これはGTFSリアルタイムデータを交換するために使われているフォーマット、プロトコルバッファに関係がある。[プロトコルバッファ](https://developers.google.com/transit/gtfs-realtime/#data-format)はバイナリ形式で情報を表す大変コンパクトな方法である。（これまで例示したGTFSリアルタイムデータのように）フィードデータがUnicodeの文字で書かれていれば、1文字あたり最低1バイト（8ビット）必要になるが、プロトコルバッファでは0と1の表現でより小さいサイズに収まる。

プロトコルバッファによるスペースの節約は、この情報が秒単位で更新されることを考えれば、すぐに大きな違いを生むことが分かる。以下の図はマサチューセッツ湾交通局（MBTA）の[GTFSリアルタイムのTrip Updates](http://developer.mbta.com/lib/GTRTFS/Alerts/TripUpdates.pb)フィードからの一回分のレスポンスである。バイナリ版のプロトコルバッファが1MB以下であるのに対し、テキスト版では5.5MBと、6倍以上の大きさだ。


 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/53416/d1cd23e9-8a54-2b88-4a89-d18d0559a8e7.png)

	MBTAのGTFSリアルタイムフィードのプロトコルバッファ版はプレーンテキスト版よりも6倍も小さい


バイナリのフォーマットは大変省スペースである一方、それを処理するコードを書くのはかなりの苦痛になり得るが、プロトコルバッファはコードを自動生成することでこの問題を解決している。まず、交換したいデータ構造を記述する[`.proto`ファイル](https://developers.google.com/protocol-buffers/docs/proto)を作る（今回の場合は公式の [`gtfs-realtime.proto`](https://github.com/google/transit/blob/master/gtfs-realtime/proto/gtfs-realtime.proto)）。そしてこの`.proto`ファイルをオープンソースの[プロトコルバッファツール](https://github.com/google/protobuf)で処理すると、情報をバイナリフォーマットに圧縮するコード（交通事業者の車両ロケーションサーバで使う）とバイナリフォーマットから情報を展開するコード（アプリ開発者のサーバで使う）が自動生成される。

![スライド2-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/53416/ab9e3ae2-9aa8-8fdb-8f2d-be28c225451f.jpeg)


	プロトコルバッファコンパイラがバイナリ形式でGTFSリアルタイムメッセージを交換するコードを自動生成する


しかもより便利なことに、Googleがこの手順を更に簡略化する[gtfs-realtime-bindingsライブラリ](https://github.com/google/gtfs-realtime-bindings)を開発した。このライブラリは、GTFSリアルタイムメッセージをJava、.NET、JavaScript / Node.js、PHP、Python、Ruby、Golangといったプログラミング言語で容易に交換することを可能にする。

こうしたことが一体GTFSリアルタイムのフィールドが「省略可能」か「必須」かに何の関係があるのか？

オリジナルのGTFSリアルタイムv1.0のドキュメンテーションを見てみると「指定回数（Cardinality）」のフィールドがあり、値は「必須」、「省略可能」それから…「繰り返し」？「繰り返し」って何？？？

実は「指定回数（Cardinality）」の項目は`gtfs-realtime.proto`ファイルからコピーしたもので、公共交通とは全く関係ないのだ。プロトコルバッファの「基数（Cardinality）」は単にバイナリメッセージを解析するソフトウェアがフィールドの存在を前提としているかどうか定義しているだけである—GTFS や交通特有の考え方とは直接結びついていない（ちなみに「繰り返し（repeated）」はプロトコルバッファ用語で省略可能な要素のリストのこと）。これがGTFSリアルタイムの問題となる。なぜなら多くのソフトウェアエンジニアが、プロトコルバッファの実装に将来的にも互換性を維持するため、プロトコルバッファのフィールドを「必須」以外にするからだ（詳しくはプロトコルバッファのドキュメンテーションの[“Required is Forever”](https://developers.google.com/protocol-buffers/docs/proto#specifying-field-rules)と[”GoogleグループでのこのGTFSリアルタイムについての議論”](https://groups.google.com/forum/#!msg/gtfs-realtime/wm3W7QIEZ9Y/DLyWKkknJyoJ)を参照）。結果、GTFSリアルタイムv1.0ではほとんどのフィールドが—たとえ交通アプリがリアルタイムの情報を正しく利用者に示すのに必要なフィールドであっても—「省略可能」になってしまう。


## GTFSリアルタイムv2.0で解決

この問題を解決するため、GTFSリアルタイムコミュニティはリアルタイム運行情報の「意味的な」必須項目と基数（cardinality）を定義する新しいバージョンのフォーマットを作った。言い換えれば、[GTFSリアルタイムv2.0](https://github.com/google/transit/blob/master/gtfs-realtime/spec/en/reference.md)はどのフィールドが必須とされるべきか、ドメイン特有の（交通の）ロジックに基づいて定義するのだ（詳細な提案は[こちら](https://github.com/google/transit/pull/64)）。これらの定義はプロトコルバッファのフォーマットから完全に独立したもので、GTFSリアルタイムのデータに他のフォーマットが使用された場合でも適用される。

GTFSリアルタイムv2.0は各フィールドに[「必須（Required）」欄](https://github.com/google/transit/blob/master/gtfs-realtime/spec/en/reference.md#required)があり、下記の値が入れられる:

- 「必須（Required）」: このフィールドはGTFSリアルタイムフィードの提供者によって提供されなければならない。
- 「条件付きで必須（Conditionally required）」: このフィールドは特定の条件下において必須。その条件は仕様書の「説明（Description）」欄に説明されている。その条件に当てはまらない場合フィールドは省略可能。
- 「省略可能（Optional）」: このフィールドは省略可能で、提供者はこのフィールドを含めなくても良いが、もし基盤として利用している車両ロケーションシステムにおいてデータがあれば（例: VehiclePositionにおける `timestamp`） 提供した方が良い。

[「基数（Cardinality）」欄](https://github.com/google/transit/blob/master/gtfs-realtime/spec/en/reference.md#required)はそのフィールドに設定される要素の数—つまり「1」か「複数」（例: 1つの便における複数の停留所での予想時刻のリスト）—を表す。

以下はGTFSリアルタイムの`FeedHeader`のスクリーンショット。上がGTFSリアルタイムv1.0で下がv2.0である：



 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/53416/451a875f-f84b-7716-6042-2188d57d23d3.png)
 
	GTFSリアルタイムv2.0では新たにできた「必須（Required）」欄と「基数（Cardinality）」欄で意味的な必須項目を定義する


v2.0では新たに「必須（Required）」欄があるのが分かる。これでヘッダーのタイムスタンプなど重要なフィールドが必須になり、先述の「いつの車両位置なのか」という問題も解決される（横だが各車両にそれぞれの`timestamps`も含めること！[重要！](https://github.com/CUTR-at-USF/gtfs-realtime-validator/blob/master/RULES.md#w001---timestamp-not-populated)）。

到着予想時刻と出発予想時刻それぞれの情報を含められる`StopTimeUpdate`メッセージは、新しい「条件付きで必須」の良い例だ: 

![about_stop_sequence.png](https://qiita-image-store.s3.amazonaws.com/0/53416/4653f4b5-9508-fd6c-957c-bfb1a7677474.png "循環線を考え、stop_sequenceは「条件付き必須（Conditionally required）」となる")
 
	循環線を考え、stop_sequenceは「条件付き必須（Conditionally required）」となる

循環線において到着予想時刻が曖昧になってしまう問題については先に書いたとおりだが、GTFSリアルタイムv2.0では`stop_sequence`は「条件付きで必須（Conditionally required）」とされ、「説明（Description）」欄に循環線が必須となるケースである旨書かれている。


## この次は？

[GTFSリアルタイムv2.0](https://github.com/google/transit/blob/master/gtfs-realtime/spec/en/reference.md)は、様々な条件においてどのフィールドが必要になるかどうか、待望の指針を提供者（交通事業者や車両ロケーションシステムメーカー）や利用者（アプリ開発者や公共交通利用者）に提供する。これでバリデーションツールは新たな利用事例に基づいてGTFSリアルタイムv2.0のデータのエラーを警告できる（我々は、オープンソースの[GTFSリアルタイムバリデータ](https://github.com/CUTR-at-USF/gtfs-realtime-validator)ツールをv2.0のエラーを検知出来るように[数週間前に更新](https://github.com/CUTR-at-USF/gtfs-realtime-validator/pull/274)した）。そうすればGTFSリアルタイム提供者のためのソフトウェア開発や品質保証のサイクルが短縮されるし、デプロイのコストも低下するし、そして最も重要な、公共交通利用者への情報の品質も上がる。

じゃあこれで終わり！問題は全部解決！……なんて物事はそう簡単にはいかないよな。トラブルシューティングについてまだ触れていなかった。予測時刻の純粋なエラー—例えばあと5分でバスが到着すると言って実際は15分前に出てしまっていた—とか。先に述べたように、予測時刻の精度は利用者にとってとても重要だ。でも現時点では精度や予測時刻の測定方法に共通の定義すら存在しない。次の課題だ。

そうだ、自身のGTFSデータについても忘れるなよ！リアルタイム情報は、GTFSデータあってこそだからな。下記の記事[GTFS Best Practices](http://gtfs.org/best-practices/)は取組みが5分で読めるからぜひ読んでみてくれ:


[https://medium.com/@sjbarbeau/gtfs-best-practices-now-available-88ac67194233](https://medium.com/@sjbarbeau/gtfs-best-practices-now-available-88ac67194233)


## 謝辞
サウスフロリダ大学（University of South Florida）都市交通センター（CUTR）におけるGTFSリアルタイムv2.0 についての意味的な必須項目と基数（cardinality）を定義するプロポーザル作成およびオープンソースGTFSリアルタイムバリデータ開発はNational Institute for Transportation and Communities (NITC)の助成によって行われている。この記事の内容は筆者の考えに基づくものであり、ここで示された事実や図や情報についての正確性は筆者一人に責がある。


## 著者について:
https://www.cutr.usf.edu/2012/02/sean-barbeau-tdm-research-associate-6/

**シーン・バーボー (Sean Barbeau)**, 博士

南フロリダ大学 都市交通研究センター モバイルソフトウェア研究開発主席設計者

南フロリダ大学都市交通研究センターで交通デマンドマネジメントグループに所属。ロケーションアウェアインフォメーションシステムズ研究室でソフトウェアエンジニアを率い、政府や企業の助成を受けてプロトタイプロケーションベースドサービスやインテリジェントモバイルアプリを開発。

専門分野: 携帯電話向けインテリジェントロケーションベースドサービス、モバイルデバイス向けライトウェイトデータコミュニケーションフレームワーク、バッテリー寿命保護のためのモバイルアプリ最適化

### 引用文献
[^1]: Kari Edison Watkins, Brian Ferris, Alan Borning, G. Scott Rutherford, and David Layton (2011), “Where Is My Bus? Impact of mobile real-time information on the perceived and actual wait time of transit riders,” Transportation Research Part A: Policy and Practice, Vol. 45 pp. 839–848.

[^2]: Candace Brakewood, Sean Barbeau, Kari Watkins (2014). “An experiment evaluating the impacts of real-time transit information on bus riders in Tampa, Florida”, Transportation Research Part A: Policy and Practice, Volume 69, November 2014, Pages 409–422, ISSN 0965–8564, http://dx.doi.org/10.1016/j.tra.2014.09.003.


[^3]: C. Cluett, S. Bregman, and J. Richman (2003). “Customer Preferences for Transit ATIS,” Federal Transit Administration. Available at http://ntl.bts.gov/lib/jpodocs/repts_te/13935/13935.pdf#sthash.jwn5Oltr.dpuf

[^4]: Lei Tang and Piyushimita Thakuriah (2012), “Ridership effects of real-time bus information system: A case study in the City of Chicago,” Transportation Research Part C: Emerging Technologies, Vol. 22 pp. 146–161.


[^5]: Brian Ferris, Kari Watkins, and Alan Borning (2010), “OneBusAway: results from providing real-time arrival information for public transit,” in Proceedings of the 28th International CHI Conference on Human Factors in Computing Systems, Atlanta, Georgia, USA, pp. 1807–1816.

[^6]: A. Gooze, K. Watkins, and A. Borning (2013), “Benefits of Real-Time Information and the Impacts of Data Accuracy on the Rider Experience,” in Transportation Research Board 92nd Annual Meeting, Washington, D.C., January 13, 2013.


[^7]: Brakewood, Macfarlane and Watkins (2015). The Impact of Real-Time Information on Bus Ridership in New York City. Transportation Research Part C: Emerging Technologies, Volume 53, pp. 59–7

[^8]: A. Gooze, K. Watkins, and A. Borning (2013), “Benefits of Real-Time Information and the Impacts of Data Accuracy on the Rider Experience,” in Transportation Research Board 92nd Annual Meeting, Washington, D.C., January 13, 2013.