読者です 読者をやめる 読者になる 読者になる

S.F. Page

Programming,Music,etc...

東京メトロオープンデータ (10) 応募完了

q.js JavaScript node.js bootstrap HTML5 Boost

何とか形にはなったが...

APIを使い続けるためにはコンテスト応募が必須なため、私にしてはかなり急ぎでアプリを作った。まだ直したいところはあるがもう期限ぎりぎりなのでこれであきらめることにした。

https://bxkvxg.dm2301.livefilestore.com/y2pTQYL-xQWK3dSPyon4SrKxOebHjvRIS94_prwzR7zLqVRRERGQ2JCx-j0oSApKoDPo_wQ-zProoAhPku0XvBi491RvCzC9Uz6oleKRWrFWbI/2014111501.png?psid=1

ソースコード


sfpgmr/metrop · GitHub

アプリサイト


Metro Info.

このアプリについて

このアプリケーションはサーバー上でクライアントコンテンツ生成とjsonデータのプロキシを行っている。生成はnode.jsで、コンテンツのデリバリーはnginxを使って行っている。クライアントは情報をサーバーから取得し、東京メトロAPIのサーバーには直接アクセスはしていない。

https://bxkvxg.dm2301.livefilestore.com/y2ptTTkkZnWYsw8p_BWfSsgzv7c0fQh4nGH5OdES9f3nRYojeLRmazwl0bT6aLAA7uCh3HUJoMk2OxqE79hQJStdFYIzdCbpFvOVTGhHRAFFZU/2014111506.PNG?psid=1

コンテンツの生成

node.jsではHTTPリクエストを直接受けずバッチ処理エンジンとして使用している。node.jsでは以下のことを行っている。

定期的に列車ロケーション情報・運行情報を東京メトロオープンデータAPIを定期的にコールして取得する。

取得したデータはファイル保存・zip圧縮して配布フォルダに保存する。メモリ管理を意識しないで作ったモジュールを常駐させるとガベコレがうまく働かずメモリを食いまくるということをここで学んだ。ガベコレが働くからといってリソース管理を怠ってはいけないのだった。

index.htmlを生成する。

  • 国土情報地理院の駅データおよび路線データをQGISで加工したあとgeojsonデータ化したものを読み込み、東京メトロオープンデータAPIで得られる路線情報と駅情報と組み合わせ、路線図データ(svg形式)をd3.jsを使用して生成する。
  • svgデータをectを使用しHTMLテンプレートへ埋め込み、index.htmlファイルを生成する。index.htmlは配布フォルダにzip圧縮して保存する。ectはなかなか高機能なテンプレートエンジンである。

駅情報・列車時刻表・駅時刻表を東京メトロオープンデータAPIをコールして取得し、配布フォルダにzip圧縮して保存する。

非同期処理はq.jsを使用してPromise/Futureでさばいている。q.jsを使用すれば非常に簡潔に非同期処理を書くことができるし、Promiseを返さないAPI(ほとんどがそうだけど)をラップするのに便利なヘルパーがたくさん用意されているのでラッパーも非常に簡単に書くことができる。

残念ながらJSON-LDというデータ形式を生かしたコンテンツ作りは行っていない。うまくするとそのままJSON-LDで配布コンテンツに埋め込んだり、RDFa Liteのデータとして埋め込んだりできそうだけれども、うまい使い方を思いつけなかった。これは今後の課題としておこう。

コンテンツの配布

コンテンツの配布はnginxを使用して行っている。nginxはリバースプロキシー的な利用は一切おこなっていない。zip処理自体は事前にnode.js側で行っているので対応しているUAに対しては静的zipファイルを配り、通信トラフィック削減を図っている。

UAでの処理

UA側ではrequire.js/d3.js/q.js/bootstrap/jqueryを使用して実装した。knockoutも使いたかったが、使いどころがなく断念した。ここでもq.jsが大活躍している。このライブラリのおかげに私にしてはかなり効率よく非同期処理が書けたと思う。プロから見たら糞コードだと思うが。UI全般は全面的にbootstrapを使用した。jqueryはbootstrapのためだけに使用しており、DOM操作はおおむねd3.jsで行っている。こういうデータをさばいてDOMに反映する処理はd3.jsの方が機能的に優れていると思う。非常に簡潔に書ける。

列車ロケーション情報をアニメーション表示する

サーバから全線の列車ロケーション情報を取得してマップ上に表示する。およそ90秒ごとにデータ更新が行われその際の位置移動はアニメーションする。

アニメーションはd3.jsのtransition()を使っている。データは90秒間隔で提供されるのであまり動きのある画面ではない。列車ごとの運行時刻表も取得できるから実時間でマップ上の動きをシミュレーションするようなことも可能だと思う。列車遅延時の補正とかが必要だからちょっと面倒かとは思うが。 列車の位置を示すマーカーのアニメーションは路線図上をトレースして動く。この部分の実装がちょっと難しかった。この部分の動きを実装するためには下記情報を参考にした。


【D3.js】 地図上のルートに沿ってアニメーション | GUNMA GIS GEEK

上記を参考に路線データをトレースすればよいのだが、路線データは必ずしも方向に沿って(順番に)データ化されているわけではない。そのため東京メトロオープンデータAPIで取得できる路線データは使用せず、国土数値情報 鉄道データを使用してQGISで路線データを加工し、駅順にうまくアニメーションするようにした。これが非常に面倒臭かった。

駅時刻表表示

マップ上の駅をクリックすると駅時刻表が表示される。下図はiPhon5で表示してみたものである。Bootstrapのモーダル丸出しですな。。

https://bxkvxg.dm2301.livefilestore.com/y2pOL1GHmFpVRZKzsZ7Q98JB63-jSVv2rYQvce1EtXUuC39u3Qldj69lUJT57pnu4NaLRZWOkz4SbBSyuZktbZtbJBmjdDcWl9GXSIHW5IWPTQ/2014111507.PNG?psid=1

時刻は現在「時」が一番上に表示され、次に発車する列車の分がブリンクする。このブリンク表示はCSSアニメーションを使用して実現している。この表示は実時間に合わせ1分おきに更新する。ここでの更新もd3.jsを使用して簡潔に書けたように思う。

運行情報表示

運行情報は画面下中ほどに常時表示され、およそ5分ごとに更新される。クリックすると各線の運行状況がモーダルで表示される。

https://bxkvxg.dm2301.livefilestore.com/y2pUnNGtNDRHwx2Eiyf8Kk8O3MBvKe6hJfTfbhMhjrXBK65XzNwYczG10TsVi9ZdOTvmQu9tMNqidoE2_090G9myrhRsqDMLbuN6nxaMwqw7eI/2014111508.PNG?psid=1

遅延が発生した場合は運行情報にその旨が表示され、マップ上の路線がブリンクする。

今後

締切は2014/11/17なのでそれまでは見つかったBugをつぶすことを行う。11/17は仕事があるのでいじることはできないので実質11/16が私の締め切りである。2014/11/18以降審査終了までは致命的なBug以外はアプリをいじることがルール上できなくなる。

このアプリはあくまでベースで、追加機能を実装したいけども、このAPIがいつまで運用されるのかがよくわからない。2014年内とかいう話もあるし、それだとやる気が萎えるので、今後どうなるのかをウォッチしていきたい。

やっぱり他の鉄道路線のデータもないとやっぱり実用的にはきついかなぁと思った。ただそうするとデータ量が多すぎてWebアプリでは処理的にきついかなあと思っている。