CANデータを見るプログラムを動画にしてみた

先般のエントリにてRX-8のCANデータをグラフにしてみましたが、リアルタイム情報を車載動画にピクチャインピクチャとして重ね合わせた動画をつくり、ニコニコ動画にアップロードしました。

今までは見る専門だったので、どの程度の方に見て頂けるかはまったく未知数でしたが、一日経たない間に300人以上の方に見て頂けたようで。 人気動画とは比べものになりませんが、場末のブログにひっそり置いておくよりはよっぽど見て頂けるので嬉しいです。

次はもう少し派手目に作ります。

iPhoneのSafariを使って走行中の道路名をtweetしてみた

というわけで、サーバに展開した国交省のデータを使って、実際にTwitterでつぶやくようなアプリを作ってみました。

といっても、専用アプリを書くのは面倒なので、ひとまずはiPhoneのSafariからGPS情報をサーバに送りつぶやくようにしてみました。

仕組み

iPhoneのSafariは、JavaScriptを利用して現在位置を取得するGeolocation APIに準拠しています。そこで、定期的にiPhoneから現在位置をサーバに投げてやり、サーバ側で道路名を解析してTwitterにツイートさせてやるような仕組みを作りました。 iPhoneのSafariでGPS情報を扱う方法は、Ascii.jpのiPhoneのGPSをJavaScriptで操ろうという記事が参考になります。

…というか、今回やったことはこの6ページ目にあるサンプル03をちょいといじっただけです。

ここのソースコードにupdate関数があり、位置情報が更新された際に呼び出されます。結構これは頻繁に呼び出されるので、たとえば10分おきにサーバに情報を伝えたい、なんてときには、update関数の最後あたりに

var now = new Date();
if ((now.getTime() - before.getTime() ) > (1000 * 60 * 10)){
    before = new Date();
    updateStatus();
}

こんなのを埋め込んで、10分おきにupdateStatus関数が呼ばれるようにすれば良いです。

そして、updateStatus関数内では、lat変数とlng変数を利用してサーバ側にデータを渡してやります。ここではXMLHttpRequestを使います。たとえばこんな感じに。

var url = "http://your_site.com/rest.jsp?lat=" + lat + "&lng=" + lng;
var myRequest = new XMLHttpRequest();
myRequest.open("GET", url);
myRequest.onreadystatechange = function(){ 
    //readyState値は4で受信完了
    if (httpoj.readyState==4){ 
        getServerResponse(httpoj)
    }
}
myRequest.send(null);

そしてまぁ、urlからの返答如何によっては再送したりなんなりをgetServerResponse内で実装してやれば良いです。

サーバ側では、前回までに作ったDBでHibernateを利用しつつ道路名を割り出し、Twitter4Jを使ってツイートをしています。

できばえ

まず大学まで、いつもとは全然違う道をとおって走ってみましたが、うまくいきませんでした。これは単純に道路名割り出しルーチン内で、しきい値がやたらシビアだったためでした。

そのため大学でちょっとプログラムを書き直し、またいつもとは全然違う道を走って動作確認をしたところ、そこそこうまくいっているようです(それが上の図)。 ただまぁ、例によって15年前のデータなので「浦和東村山線」なんて道路名が出てきたりしてますが、現在は「さいたま東村山線」だったりするようです。

最新のデータについては、先日国交省にもらえないのかメールしてみました。担当者に確認の後返事を頂けるようですが、どうも「公開していない理由」を担当者に確認するみたいな雰囲気なので、あまり期待せずに待っています^^;

まとめ

常にツイートし続けるのはどうかと思いますが、どっか遠出するときとかはおもしろいかもしれません。そこそこうまくツイートできてるっぽいですし。 今は一定間隔でツイートしてますが、道路が変わったらツイートする、なんてのも面白いかもしれませんね。

せっかくなので道路をGoogleMaps上にプロットする

前回のエントリで記したとおり、自分が道路上にいるかどうかを調べるためには、そもそも道路のデータを保持していなければなりません。

このデータを使って地図上に高速道路や国道のラインをプロットすることが出来ます。

最初、前回のエントリで作ったデモに組み込もうと思って試しにやってみたんですが、位置データが多すぎるため、blazedsを使って単純にサーバからクライアントにプッシュするとTomcatが落ちてしまいました…(たぶんシリアル化する時に落ちてる)。

GoogleMaps APIを調べてみると位置データをエンコード化して読み込ませるというオプションがあったので、サーバ側でデータをエンコードした上でクライアントにプッシュすることで、そちらを実装してみたらうまくいったので公開します。

あ、そうそう、前回のデモでは関東圏だけしか動きませんでしたが、DBをアップデートしたので、今は日本全国調べられます。

説明

前回のデモに追加で実装したので、前回のサイト(停止しました)を訪れて同じように動かすだけです。

前回は、地図中心点に道路があるかどうかを調べ、道路に名前がついていればその旨表示するだけでしたが、今回はそのあとに表示されている地図の範囲の道路位置データをダウンロードしてGoogleMaps上にプロットします。 ダウンロードするのに最大で10秒くらいかかるかもしれないので、気長にお待ちください。

また、ある程度地図の拡大率が低い場合には、中心付近を一部だけロードするようにしています。DBのロード、データエンコード、クライアントへのプッシュ、クライアント側での描画、ととんでもなく時間がかかるためです。

また、手抜きプログラミングのため、同じ場所を拡大したとしても再度全てのデータを読み込み直します。ほんとはバッファとか用意した方が良いんでしょうが、重複判定するのも面倒だったりします。クライアント側にDB持ってるとそのあたりも柔軟にできるかもですが。

なんでこんなの作ったか

前回の道路名を調べるデモですが、結構条件がシビアで、きちんと場所を合わせているつもりでも道路名が出てこないことがあり、(作った本人が)いらいらしておりました。

まぁ、どこまで判定をシビアにするかというのはパラメータをいじれば済むのですが、あると思っていた道路が95年現在はなかったため道路名が表示されない、とか、そもそも道路名が登録されていないために表示されない、といった場合には、その場では原因がよく分からず「おかしい…」と悩んでしまったのでした。

であれば、DBに登録してある道路を周辺地区だけでもプロットし、そもそもDBに登録されているのか否かを調べられるとよろしい、ということで作ったのでした。

その他

現在は高速から一般道まで全て同じ色で表示していますが、色を変えたり、チェックボックスで表示する道路を選択できたりすると面白いかもしれません。

位置データのエンコードは、エンコード化ポリライン アルゴリズム方式というGoogleのページで説明されているのですが、いまいち日本語がよくわからず…。 検索したら、こちらのサイトにて、まさに合点のいかないところがシンプルに説明されており助かりました。

緯度経度から、その場所を走っている道路名を調べる

うわー、これまたタイトルからしてニッチ(笑

最近、「流行っている」と形容するのも恥ずかしいtwitterですが、「○○なう」などとつぶやいている人が結構見受けられます。「○○」にはその時訪れた場所だったり、その際やっている行動だったりが入るわけなんですが。

これ、車の運転中にはできないですよね、危なくて。なので、つぶやきをそれっぽく自動化できないか考えてみた訳なんですが…。

前回のエントリでは車の中を流れる各種データを取り出すことが出来たので、たとえば、エンジンを切らずに速度0が一定時間続いた回数をして「(ほぼ)信号待ちの回数」としてカウントし、「信号待ち100回目なう」などとつぶやくことは出来そうです。あるいは、制限速度を超えたら「現在XXkm/hで巡航中。○○県警かかってこいや」とつぶやくことも可能でしょう(よい子はまねしちゃいけません)。

…ただまぁ、大がかりなわりにはあまり面白そうなつぶやきのネタにはならなそうですし、第一この設備が一般的ではないので、他の人にとっては「ふーん」程度であまり参考にならないです(自分で運転を解析するにはとても面白い情報なんですけどね)。

そんなわけで、もう少し一般的なGPSから得られる位置情報を利用してなんかできないか考えてみました。それが、このタイトルにあるような技術を利用して「国道○○号線なう」みたいなことをつぶやくというものです。

ひとまずお披露目

とりあえず関東地区だけなのですが、緯度経度から道路名を調べるプログラムを組んでみました。こちらのページ (停止しました)でそれを体験することが出来ますので、ぜひ一度お試しください(適当に立てたTomcatサーバなので、落ちてたらごめんなさい)。ではいってらっしゃいませ。

…あ、おかえりなさい。使い方は分かったでしょうか? 地図の中心部に調べたい道路を合わせると、その地点の道路名を吹き出しに表示するものです。デフォルトの倍率だとうまく道路上に中心があわないので、少し拡大すると良いです。地図上だとあまりずれてないと思っても、拡大率によっては数ピクセルで10m以上ずれていることもあります。それでも現れない場合には別の原因が考えられます(後述します)。

さてさて、今は手動で位置を合わせているわけですが、当然ながら携帯やPCのGPS位置情報を利用して、自動的にその位置の道路名を割り出すこともできます。 なんとなく、定期的に携帯から位置情報を送信し、その都度道路名を調べて「国道○○号から首都高へ」とかつぶやけそう、じゃないですか?

どうやって道路名を調べるか

ちょろっと調べた限りでは、位置情報から道路名に変換する既存のサービスはなさそうでした。

位置情報から住所を割り出すサービスはあります。「逆ジオコーディング」と呼ばれますが、Finds.jpが無料でサービスを公開していますし、最近ではGoogleもGoogleMaps APIにてサービスを提供し始めました。ただ、住所じゃないんですよね、必要なのは…。あくまで道路。

Googleの逆ジオコーディングは、道路上の緯度経度を入力してやると、有名な道路の場合にはそのむね返答をしてくれることがあるようです。ただまぁ、どの程度入っているかわかりませんし、建物名や地名など混ざった状態で返答されてもちょっと…という気がします。

仕方ないので今回は、国土交通省が公開している国土数値情報を使って自分で調べるプログラムを組むことにしました。

国土交通省は、以前から無料で国土数値情報をデータで公開しています。数年前に気づいてブログのエントリにもしているのですが、エントリ先くらいのクオリティのデータはすぐに手に入るわけです。ただ、道路情報に限っては1995年版が最新で、そこは非常に残念なのですが…。 国交省内部では必ずデータはあるはずで、他のデータは新しいモノもあるので、しばらく待てば/担当者にかけあえば新しいデータを閲覧できるかも知れませんが、まぁひとまずはいいでしょう。誰がどのくらい使いたいかも分からないですし^^;

この道路情報には、道路の線分データと、その線分に対応する道路名と種別(高速・国道・県道・…)などが含まれています。 なので、与えられた緯度経度に対して、近い道路の線分データがあればその道路名を返答する、というプログラムを書いてやれば良いということになります(久しぶりに点と直線の距離を求める公式とか思い出した^^;)。

応用

今はGoogleMapsアプリという形になっていますが、WebサービスやiPhoneアプリ化することで実際に自動でつぶやけるようになります。…自分以外にこんなものを使う人がいれば、ですが^^; ひとまず今は乗りかかった船なので、関東以外のデータをDBに突っ込んでいる最中です。

また、いわゆる一般的な逆ジオコーディングを使って、「埼玉県に突入なう」などとつぶやくことも出来るので、組み合わせると面白いかも知れません。

問題点

問題点、あります。

まずは上の方に書きましたが、データが1995年のものということです。首都高は一部開通してませんし、アクアラインもありません。千葉の館山道もないっぽいです。上で紹介したGoogleMapsアプリを使ってどうしても道路名が出なかった方は、もしかしたらその時代にはまだ道路がなかった(あるいは名前が付いてなかった)のかもしれません。 これはまぁ、国交省が新しいものをリリースしてくれるのを待ったり、あるいは自力で最新データに書き換えるしかありませんね。

あとは、道路名が法定名なので、微妙に違和感があります。たとえば池袋や渋谷を走っている通称「明治通り」は、「芝新宿王子線」と出てきます。 国道は全て「国道○○号線」となっているのでまぁ問題ないですが、それより細かい範囲の道路に関しては「??」となる可能性があります。環七は「環状七号線」なんだけどなー。 これも、必要ならば頑張ってデータを加えていく必要があります。

副産物

95年産ではありますが、高速・国道等の線分データが得られます。 下の写真は、首都高のデータを抜き出してプロットしたものです。

GoogleMapsやGoogleEarthにプロットしたり出来るので、もしかしたらそういったものが必要な人には役に立つかも知れません。これらのデータは再配布可能らしいので、自由に使えるようです。

まとめ

国交省が配布しているデータを使って、緯度経度からその地点の道路名を割り出すプログラムを作りました。今のところ関東のみ・GoogleMapsでの動作確認デモプログラムしかありませんが、他の地域も現在DBに突っ込んでいます。また今度遠出したときにでも、PCあるいはiPhoneを利用して実際につぶやいてみようと思います。

データが古く道路の名称もなじみのないもの、と問題点がないわけではないですが、もし使ってみたい・興味があるという方はご連絡ください。このウィンドウの右側に常に出ているtwitterリンクから僕のアカウントに飛べます。

あと、なにかこのデータを使って面白いことができるといったアイディアがあったら教えてください^^;