オープンソースの経路探索「OpenTripPlanner」をUbuntuで動かして岡山県で経路探索をする

ヴァル研究所アドベントカレンダー2018の1日目です。

弊社は30年目を迎える経路探索サービス「駅すぱあと」を開発しています。
そんな会社のアドベントカレンダーの１日でご紹介するのは、オープンソースの「OpenTripPlanner(以下OTP)」という経路探索ソフトウェアです。

岡山県の道路および一部のバス事業者のデータを使って経路探索ができるところまで動かします。「とりあえず面白そうなら触ってみよう」の精神でやってみました。

(2018/12/04追記)
*@niyalistさんのコメントの情報を元にmacOSでも同様にOTPを動かす記事を書きました。こちらもご参照ください→[オープンソースの経路探索「OpenTripPlanner」をmacOSで動かして岡山県で経路探索をする](https://qiita.com/kumatira/items/5235554b12f5f2725301)。情報ありがとうございました。*

<img width="1440" alt="スクリーンショット 2018-11-29 3.36.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/159912/efaac2a4-ae81-57c2-413b-b0a711e46f97.png">


# 何を説明するか
* OTPとはなんぞや(軽く)
* OTPの起動手順
* 経路探索してみる
* 情報まとめ

# 何を説明しないか
* OTPの機能に関する深い説明。起動→経路探索に必要な情報のみ言及します。
* 本記事に出てこない元データの入手方法。岡山県での経路探索に必要な情報のみ言及します。

# OTPとはなんぞや(軽く)
「OpenTripPlanner(以下OTP)」の公式サイトは[こちら](http://www.opentripplanner.org/)です。

トップページに
>OpenTripPlanner (OTP) is a family of open source software projects that provide passenger information and transportation network analysis services. 

とあるように、交通に関する情報やその分析を行うことができるOSSです。
OpenStreetMapや交通事業者から提供されるGTFSデータを元に徒歩、自動車、自転車、鉄道等の交通機関を複合的に扱うことができます。
今回はこれらの機能の中から、経路探索を行なっていきます。

インターフェースはHTTPであり、中身はJavaでできています。有志が作った、OTPとのやりとりをラップするいくつかの言語のライブラリもあるようです。

# OTPの起動手順
## 動作させる環境
### OS
あとで使うツールが`apt install`でのインストールが一番楽であるため、`Ubuntu` を使います。ここでは`Ubuntu 16.04.4 LTS`を使いました。

### マシン
マシンは個人的な趣味で[alibabacloud](https://jp.alibabacloud.com/)のECSインスタンスを借りました。この時注意すべき点は、メモリが4GB以上あるものを選ぶことです。(実際は、多めに8GBのインスタンスを借りました。)これはOSMの巨大なデータをメモリ上に展開するためです。

[公式チュートリアル](http://docs.opentripplanner.org/en/latest/Basic-Tutorial/)では、オレゴン州ポートランドを例としていますが、ここでは
>GTFS and OSM data sets are often very large, and OTP is relatively memory-hungry. You will need at least 1GB of memory when working with the Portland TriMet data set, and several gigabytes for larger inputs. 

と述べられています。今回例とする岡山県はポートランドの市域より広大なので、多めに8GBのメモリーをもつインスタンスを借りています。(経路探索はマシンパワーを食うため、CPUは2コアとしました。正確にどのくらいのリソースを必要とするのかはわかりません。)

また後ほど手元から叩けるようにグローバルIPをもらっておくことをお勧めします。

### JDK
OTPを動かすには1.8以上のJDKが必要です。入っていない場合は入れてください。

```
# sudo apt-get update //↓のインストールが失敗したらaptをアップデートしてからもう一度試す。
# sudo apt-get install openjdk-8-jre

# java -version //環境の確認
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-1ubuntu0.16.04.1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
```

## 準備
では必要なものをバンバン落としてきましょう。
主に[公式チュートリアル](http://docs.opentripplanner.org/en/latest/Basic-Tutorial/)を参考にしています。

### 作業ディレクトリを作り移動
名前はわかりやすければなんでもいいです。

```
# mkdir otp
# cd otp
```

### OTP本体を取得
[こちら](https://repo1.maven.org/maven2/org/opentripplanner/otp/)よりOTPの本体を落としてきます。最新バージョンのディレクトリからファイル名が`.shaded.jar`で終わるファイルを使います。

```
# wget https://repo1.maven.org/maven2/org/opentripplanner/otp/1.3.0/otp-1.3.0-shaded.jar
```

### 交通事業者の提供するGTFSデータを取得
経路探索の公共交通機関の部分のデータに使うGTFSデータを取得します。
今回は**公共交通オープンデータ先進都市**こと岡山市に乗り入れる、[宇野バス](http://www.unobus.co.jp/)、[下電バス](http://www.shimoden.net/rosen/)、[両備バス](https://www.ryobi-holdings.jp/bus/rosen/index/)、[岡電バス](http://www.okayama-kido.co.jp/bus/jikoku.html)、[中鉄バス](http://www.chutetsu-bus.co.jp/)の各社が提供するデータを使います。このように地域でまとまってオープンデータ化してもらえると使う側としても使いがいがありますね!!

以下のサンプルコマンドで呼んでいるアドレスは2018/11/27時点での最新のものです。
新しいデータがあるか確認したい場合はこちらから各社のデータ置き場へ辿ることが出来ます。

~~2018/12/04 10:00現在、中鉄バスのGTFSデータ(β版)が正常に取得できません。この後、OTPの起動でデータについてエラーが起きた場合は一度該当データを抜いて起動することをお勧めします~~
→2018/12/04 20:00現在 復旧していました。

(2019年1月15日追記)
宇野バス、下電バスのオープンデータのファイル名が変更されました。

[GTFS・「標準的なバス情報フォーマット」オープンデータ一覧](http://tshimada291.sakura.ne.jp/transport/gtfs-list.html)

```
# wget "http://www3.unobus.co.jp/opendata/GTFS-JP.zip" -O unobus.gtfs.zip
# wget "http://www.shimoden.net/busmada/opendata/GTFS-JP.zip" -O shimodenbus.gtfs.zip
# wget "http://loc.bus-vision.jp/gtfs/ryobi/gtfsFeed" -O ryobibus.gtfs.zip
# wget "http://loc.bus-vision.jp/gtfs/okaden/gtfsFeed" -O okadenbus.gtfs.zip
# wget "http://loc.bus-vision.jp/gtfs/chutetsu/gtfsFeed" -O chutetsubus.gtfs.zip
```

### 作業ディレクトリから出る
一旦出ます
この後落とす中国地方全体のpbfファイルを作業用ディレクトリに落としたくないためです。
作業用ディレクトリと異なる場所ならどこでもいいです

```
# cd ../
```

### 中国地方のOSMのデータを取得
続いて道路の部分の情報を提供するOSMのデータを落としてきます。
まずはOSMデータを提供している[geofabrik.de](https://download.geofabrik.de)から[中国地方のデータ](https://download.geofabrik.de/asia/japan/chugoku.html)を取得してきます。
これは後ほどインストールするツールで岡山県周辺にトリムします。

```
# wget http://download.geofabrik.de/asia/japan/chugoku-latest.osm.pbf
```

### osmctoolsをインストール
osmctoolsは前の手順でダウンロードしたOSMのデータ(pbfファイル)をトリムするためのツールです。
(他にも色々出来そうですが、OSM素人な筆者には難しかったです・・・)

```
# sudo apt-get update //↓のインストールが失敗したらaptをアップデートしてからもう一度試す。
# sudo apt install osmctools
```

### 岡山県周辺のみに切り取る
では先ほど落とした中国地方のOSMのデータを岡山県周辺にトリムしましょう。
`-b`パラメータにはトリムする緯度経度、`-o`パラメータには出力ファイル名を指定しています。またトリム範囲の隅っこで切り落とされる道路情報も含めたいため、`--complete-ways`オプションを付与します。
ファイルが出力されたらこれを作業用ディレクトリに入れます。

ここで注意!!
`-b`に指定する4つの値はその順番に気をつけてください。
南西の角、北東の角の座標を`lng,lat(経度,緯度)`の順番で指定します。トリム範囲の`左辺(西端),下辺(南端),右辺(東端),上辺(北端)`と言い換えることもできます。
筆者はここで2時間詰まりましたorz

```
# osmconvert chugoku-latest.osm.pbf -b=133.455201,34.274923,134.298740,35.284564 --complete-ways -o=okayama.pbf

# mv okayama.pbf otp/
```

### 作業ディレクトリに戻る

```
# cd ./otp
```

## 起動
では早速実行してみましょう。
結構時間がかかりますが気長に待ちましょう

```
# java -Xmx5G -jar otp-1.3.0-shaded.jar --build ./ --inMemory
```

起動中にWARNINGが ~~結構~~ いくつか出てくると思います。「バス停とどのstreetsとも紐づかないから使用されないよ」とか「系統名がユニークじゃないよ」などですが一旦無視します。原因と対策はまた調べたら追記します。もしご存知ならコメントで教えてください。

`Grizzly server running`と出たら起動完了です!!:point_up:

# 使ってみよう
では起動したOTPに早速リクエストを投げてみましょう。
リクエスト例中の`IPaddress`は適時読み替えてください。

## まずは正常に生きてるか
まずはちゃんと起動しているか確認しましょう。
ブラウザから下記のリクエストを投げると、利用できる交通手段が返ってきます。
今回はバスのデータしか入れていないため、`BUS`はあっても`TRAIN`はありません。

```
http://IPaddress:8080/otp/routers/default/
```
[ドキュメント](http://dev.opentripplanner.org/apidoc/1.0.0/resource_Routers.html)

## GTFSデータが入っているか確認
では次にGTFSデータがきちんと取れるかみてみましょう。
まずこのリクエストでOTPに入っているGTFSデータの`Feedid`を得ることが出来ます。今回は5つのデータを入れたので、1~5が返るはずです。

```
http://IPaddress:8080/otp/routers/default/index/feeds
```

続いて上のリクエストで得た`Feedid`を使い、データのうち１つをみてみましょう。

```
http://IPaddress:8080/otp/routers/default/index/agencies/3
```

例えば上のリクエストで宇野バスの情報が取れたとします。この時レスポンスの`id `パラメータには`1260001000674 `が入っています。これを使って次は宇野バスの全系統を取得してみます。

```
http://IPaddress:8080/otp/routers/default/index/agencies/3/1260001000674/routes
```

それぞれのリクエストについてのドキュメントは[こちら](http://dev.opentripplanner.org/apidoc/1.0.0/resource_IndexAPI.html)
系統名の一覧が取得できればOKです!!

## 経路探索
ではいよいよ経路探索をしてみましょう。
データは岡山県内のものしか入れていませんので、もちろん県内の経路探索しかできないことは留意してください。
以下がリクエスト例です。それぞれのパラメータが何を表しているのかは[こちら](http://dev.opentripplanner.org/apidoc/1.0.0/resource_PlannerResource.html)などを参照してください。

```
http://IPaddress:8080/otp/routers/default/plan?fromPlace=34.656513,133.975075&toPlace=34.665495,133.918570&time=1:02pm&date=11-14-2018&mode=TRANSIT,WALK&maxWalkDistance=500&arriveBy=false&numItineraries=5
```

```
http://IPaddress:8080/otp/routers/default/plan?fromPlace=34.779151,134.038106&toPlace=34.665495,133.918570&time=1:02pm&date=11-14-2018&mode=TRANSIT,WALK&maxWalkDistance=500&arriveBy=false&numItineraries=5
```

`itineraries`要素に入っているのが具体的な経路です!!きちんと取れているでしょうか?

# まとめ
本記事ではとりあえずOpenTripPlannerを動かしてみるところまで書きました。
ドキュメントをみるにもっと色々できる(分析方面とか)アプリケーションのようです。
探索結果に`points `要素として経路のポリラインが返ってきているのも何かに使えそうですね。

ちなみに弊社ではデータのメンテフリーで経路探索を含む便利な機能が多数揃った[駅すぱあとWebサービス](https://ekiworld.net/service/lp/webservice/)を提供しています。フリープランもあるよ!!(ダイレクトマーケティング)

ところで、OTP周りでは日本語情報を全然見つけることができませんでした:frowning2:こんな使い方したよとかあればぜひ記事化してください!!

最後にドキュメント等の情報をまとめて終わります。
明日はaosho235さんのPDFに関するお話です!!

* [公式ドキュメントページ](http://dev.opentripplanner.org/apidoc/1.0.0/index.html)
* [本体のリポジトリ(関連ライブラリも載っています)](https://github.com/opentripplanner)
* [openstreetmapWikiの該当ページ](https://wiki.openstreetmap.org/wiki/OpenTripPlanner)
* [レスポンスの形式(XMLorJSON)を指定する方法](https://github.com/opentripplanner)