OpenTripPlannerとGTFSを利用して独自の乗り換え案内を作ってみたの関連記事です。
OTPをJavaライブラリとして使用して乗り換え案内サイト欧亜大陸鉄道を作った時のTips。
はじめに
OSSの経路探索アプリケーションOpenTripPlanner(OTP)には、複数のGTFSファイルをフィードとして登録することができる。
このとき複数のフィードの中に同一駅を示すStopが個別に含まれていたらどうしたらいいのかという話。
前提条件
通常OTPは、GTFSデータだけでなく地図データを登録するので、この場合駅間は徒歩移動として経路探索されるので問題ない。
また、複数のGTFSを一つに統合できるのであれば、それを読み込ませればいいので解決。
しかしながら、やんごとなき事情で複数のGTFSファイルが必要で、なおかつ地図データを登録しない場合にどうしたらいいのかというのがこの記事の内容。
要するに、かなりニッチな話ということ。
結論
org.opentripplanner.routing.edgetype.FreeEdgeオブジェクトを使う。
OTPでは地図やGTFSの経路情報をEdgeオブジェクトの結びつきで保持しているが、この一種であるFreeEdgeは移動コストが0のエッジとみなされる。
よってこのFreeEdgeオブジェクトで2つのStopを結び付ければ、実質的に同一駅であるとみなされることになる。
ソース
// GraphオブジェクトからGraphIndexオブジェクトを取得
GraphIndex index = graph.index;
// 同一地点とみなす二つのstop情報を取得
Stop stop1 = index.stopForId.get(new FeedScopedId("nmbs", "aachen-hauptbahnhof"));
Stop stop2 = index.stopForId.get(new FeedScopedId("dr", "aachen-hauptbahnhof"));
// StopオブジェクトからVertexオブジェクトを取得
TransitStop ts1 = index.stopVertexForStop.get(stop1);
TransitStop ts2 = index.stopVertexForStop.get(stop2);
// FreeEdgeオブジェクトをインスタンス化するだけで結び付けられる
new FreeEdge(ts1, ts2);
// 反対方向も結び付けておく
new FreeEdge(ts2, ts1);
解説
StopオブジェクトはGraphオブジェクトから取得されるGraphIndexから取得できる。(詳しくはこちらを参照)
EdgeオブジェクトはVertexオブジェクトを結び付けて経路を表しているのだが、StopオブジェクトはGTFSのメタデータを表すオブジェクトであり、Vertexではない。
そこで、GraphIndexのstopVertexForStopStopからStopをキーに対応するVertexオブジェクトを取得する。
これをFreeEdgeで結び付ければ完成。通常は、2つの駅間双方向で乗り換え可能となるので、逆方向もEdgeも作成しておく。
なお、FreeEdgeは、newするだけで経路として登録されるので、その後特に何もしなくてよい。