Gears Geolocation API

測位APIはちょっと好きなので、早速チェック。

http://code.google.com/apis/gears/api_geolocation.html

Gears(a.k.a Google Gears)の一部なので、既にGearsを導入していれば自動的に更新されて利用可能になっていると思われます。
で、サンプルを動かしてみよう……動くサンプルが提供されとらんがな。サンプルコードをもとにしてノートPCで適当に動かしてみると、荒い精度の緯度経度が取得できました。江東区で測位したんですが、新宿付近の座標が出ちゃったよ。無線LAN無しのマシンでも同じ位置が出たので、IPアドレスのみを使って測位してるのかな?
ドキュメントには「いくつかの測位方法を使うよ」とだけ書かれているので、測位方法を調べてみるためにソースコードを見てみます。このあたり↓
http://code.google.com/p/gears/source/browse/trunk/gears/geolocation/?r=2531

測位能力を持つクラスのベースクラスがLocationProviderBase(location_provider.h)。このサブクラスに、NetworkLocationProvider、WinceGpsLocationProviderが存在する、と。前者が電測情報をサーバに送信し位置情報を返してもらうもので、後者はオンボードGPSを使って単体で測位するもの(今のところWinCEにしか対応してない)。GearsGeolocation::GetPositionFix()によると(geolocation.cc)、GeolocationAPIを呼ぶときのオプションでenableHighAccuracyオプションを有効にするとWinCEのときにはGPSが有効になるみたい(WinceGpsLocationProviderが使われる)。GPS付きWinCE端末を持っていないので、GPSについてはこれ以上追いかけません。
enableHighAccuracyオプションの有無にかかわらず、NetworkLocationProviderは有効になります。デフォルトでは、http://www.google.com/loc/jsonに対し問い合わせに行くインスタンスだけが生成されますが、ここのNetwork Location Provider Protocolに掲載されているようなプロトコルを備えてさえいれば他のサーバを追加指定することも可能みたい。

NetworkLocationProviderのコードを追いかけてみます(network_location_provider.cc)。コンストラクタにて、携帯電話の基地局無線LAN基地局からの電測結果を取得するよう書かれています。携帯電話に関してはまだWinCEのコードしか無いみたいで、PCは無線LANからの情報のみをもとに測位するみたい。
無線LANの電測はXxxxxWifiDataProviderクラスによって行われます(XxxxxはOSによって違う)。Win32の場合はWin32WifiDataProvider。wlanapi.dllを使い、無ければwzcsapi.dll。定期的に電測し、変化があればリスナ(NetworkLocationProvider)に通知するみたい。
電測情報が得られたら、サーバに対しJSONで電測情報を送り、位置情報が帰ってくる……という仕組みのようです。

うーん、無線LANでの測位ができそうなのに、ノートPCでの測位精度が悪いのはなんでだろう?
サーバとの通信をパケットキャプチャしてみると、サーバに対する電測情報が{"radio_type" : "unknown"}になっているので、妥当な電測情報が送信できていないみたい(電測情報が取得できなくてもIPアドレス等からある程度の位置情報が取得できている、ということでもある)。なんでだろう? wzcsapi.dllにはパスが通っているので、DLLのハンドルは取得できているはずだし。もしかして、無線LANの電測そのものが現バージョンでは行われていないとか。
そんじゃデバッグビルドして追いかけてみるか……と思ったのですが、どうやらVisualStudioのExpressEditionではビルドできない(ATLが必要)ようなので、断念。そろそろ眠いので、今度時間ができたらLinuxでビルドして追いかけてみよう。


ところで、Googleストリートビューカーって、写真を撮るだけじゃなくて無線LANアクセスポイントの電測情報を蓄積してるに違いないよね。