Google Map APIを使ってみる(その2)
せっかくAPIキーを取得したので、Google Map APIを使ってみる(Google Map APIのトップページへのリンク)。
Google Map APIを使ったページを書くには、「Google Map APIを使ってみる(その1)」で紹介した、※2の画面のサンプルをコピペして、改造するのがよい。
サンプルをみると、
<script src="http://maps.google.com/maps? file=api&v=2&key=ABQIAAAAkb*******************- *************************hWCSshiltKG5Yg" type="text/javascript"> </script> (注)keyパラメータはマスクしてある。本当は一行。
となっている。3年くらい前にはV1だったはず(V2への移行とかいう話があったような気がする)なので、正式にv2が「最新リリース」となったのだな、と思う。
RESTfullなwebサービスでは、こんな感じで「呼び出すAPIのバージョンをリクエストパラメータで指定」して、後方互換性(backward compatibility、下位互換ということが多い)の代わりにすることが多い。
ちょっと凝って、携帯(au)で場所を測位して、Google Map上にマップしてみる。
ググってみたが、引っかかるのは旧い情報ばかり。
Google Map APIが出たとき、良く見かけたサンプルの一つだが、今時は、試す人がいないのかなぁ(助手席ナビとかあるし)。
携帯電話(au)で位置情報を取得する(測位する)。
まず、KDDIのHPにいって、携帯端末(携帯電話)のAPIを確認する。
KDDIの技術情報(リンクはこちら)にある、「簡易位置情報」がそれだ。
「簡易位置情報」とは、基地局情報を元に「だいたいこの辺り」と測位測位することをいう。
この「簡易位置情報」のページには、
自分のHP上に
device:location?url=http://server/location.cgi
というURLを(aタグで)置いて、そこにau端末からアクセスすれば、位置が取得できると書いてある。
aタグでリンクした場合、location.cgi(サーバーPGMの総称)で、GETメソッドで送られてきたパラメータを取得する。このリクエスト・パラメータに緯度・経度が含まれる。
device:locationは、そのためのプロトコルの一つで、このスキームに反応して、携帯が位置情報を送出するというやり方になる。
ここまで読んで、「あれ?GPSもあったよなぁ」と思い、昔の本を開いて見ると、スキームが
device:gpsone
と書かれている。
「でばいす:GPSわん」と読むとおり、gpsOneは、GPS(と基地局からの情報)を使う測位のためのスキームである(gpsOneを解説しているページへのリンク)。OneはCDMA Oneののワンである。
ググってみると、こっちのスキームは「精度はよいが、正式には非公開」と書いてあることが多い。
この場合、具体的には
device:gpsone?url=http://server/sokui.php&ver=1&datum=0&unit=0 (注) serverは、ドメイン名と考えればよい
のように、パラメータを指定する。(パラメータに詳しいページへのリンク。device:locationでもパラメータ指定をするのが普通)。
サンプルでは、このスキームを使うことにした。
まず、自分のレンタル・サーバーに、sokui.htmlとして以下のhtmlを置いた。
<HTML> <HEAD> </HEAD> <BODY> <a href="device:gpsone?url=http://server/sokui.php&ver=1&datum=0&unit=0"> get GPS Info </a> </BODY> </HTML>
このhtmlに書かれているsokutei.phpは以下の通り。
測位点の情報を(全てのGETメソッドのパラメタを)抽出して、PEAR::LogでLogとして書き出す仕様となっている。
<?php require_once("PEAR/Log.php"); $p_log=Log::factory("file","logs/log.log",WEBAPP); $p_log->setMask(Log::UPTO(PEAR_LOG_DEBUG)); $p_log->debug("sokutei: start"); foreach ($_GET as $key => $value) { $p_log->debug("key: ".$key." value: ".$value); } $p_log->debug("sokutei: start"); ?>
携帯電話(au)で位置情報を取得してみる。
関越道でドライブした際に、練馬ICの入り口付近(比丘尼交差点付近)から、川越ICまで上のプログラムで測位をしてみた(注;上のプログラムはレスポンスの処理がないので、送信後にエラーとなるが、測位する分には問題ない;パケット代節約??)。
sokui.htmlにアクセスすると、au端末(携帯電話)が送出確認するので、それに「いいよ」と答えればよい。
上のパラメータだと、unit=0としているので、度分秒での測位結果が返ってくる。
国土地理院のHPにいけば、「度分秒での測位結果から地図上の位置がわかる」ので(リンクはこちら。東経139度35分56秒、北緯35度44分47秒を1/10000で表示。)、これで結果のトレースができる。
だが、上のHPだと一点しか確認できないので、Google Map APIを使って表示することにした。
まずは、度分秒系から、百分率系へ変換をする。
これは以下の式で計算すればよい。
百分率=(度*3600000+分*60000+秒*1000)/3600000
実験では、以下のデータが取得できた。
緯度 | 経度 |
35.7564 | 139.6000 |
35.7625 | 139.5917 |
35.7625 | 139.5917 |
35.7645 | 139.5792 |
35.7741 | 139.5678 |
35.7814 | 139.5614 |
35.7867 | 139.5531 |
35.7956 | 139.5431 |
35.8061 | 139.5320 |
35.8061 | 139.5320 |
35.8347 | 139.5056 |
35.8467 | 139.5022 |
35.8595 | 139.4928 |
35.8711 | 139.4819 |
35.8834 | 139.4725 |
35.8925 | 139.4592 |
35.9006 | 139.4664 |
これをつかって、以下のコードを書いて、APIキーを取得したサーバーに配置。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>Google Maps JavaScript API Example</title> <script src="http://maps.google.com/maps?file=api&v=2& key=ABQIAAAAkb**************-******************shiltKG5Yg" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ function createMarker(point,index){ var msg = "測位("+index+ ");<br/>" +"北緯;"+point[0]+"、東経;"+point[1]; var pos = new GLatLng(point[0],point[1]); var mark = new GMarker(pos); GEvent.addListener(mark,"click",function(){ mark.openInfoWindowHtml(msg); } ); return mark; }; function load() { if (GBrowserIsCompatible()) { var map = new GMap2(document.getElementById("map")); var posArray = [ [35.7564,139.6000], [35.7625,139.5917], [35.7625,139.5917], [35.7645,139.5792], [35.7741,139.5678], [35.7814,139.5614], [35.7867,139.5531], [35.7956,139.5431], [35.8061,139.5320], [35.8061,139.5320], [35.8347,139.5056], [35.8467,139.5022], [35.8595,139.4928], [35.8711,139.4819], [35.8834,139.4725], [35.8925,139.4592], [35.9006,139.4664]]; var posCtr = new GLatLng(35.8061,139.5320); map.setCenter(posCtr, 11); map.addControl(new GLargeMapControl()); map.addControl(new GMapTypeControl()); for(var i=0; i<posArray.length; i++){ var mark =createMarker(posArray[i],i); map.addOverlay(mark); } } } //]]> </script> </head> <body onload="load()" onunload="GUnload()"> <div id="map" style="width:500px;height:300px"></div> </body> </html>
これを表示したのが、下の画面である。
この画面では、Google Map APIの「デフォルトのMarker」をつかって、測位結果を表示している。
各Markerには、クリックイベントのハンドラとして、測位点の「index」、「経度」、「緯度」を吹き出し表示するようにした。
携帯電話(au)の位置情報(測位結果)を評価する。
自分のau端末(携帯電話)はTOSHIBA製のW41T。もう2年以上使っている代物。
送出される情報は以下の通り。
GET METHODのparameter key | parameter value | 意味 |
lat | +35.53.33.46 | 緯度(度分秒+2桁) |
lon | +139.27.33.82 | 経度(度分秒+2桁) |
alt | 81 | 高度(m) |
time | 20081224075140 | 取得時間(2008/12/24,07:51:40) |
smaj | 16 | 長軸半径誤差(m) |
smin | 7 | 短軸半径誤差(m) |
vert | 17 | 高度誤差(m) |
majaa | 175 | 誤差楕円長軸角度 |
fm | 0 | 精度(測位方法らしい。小さいほどよい??) |
誤差については、こちらのページ(ezplusことはじめさん)が詳しい。
簡単にいうと、長軸誤差が「可能性として一番大きい誤差」ということ。
測定結果をみると、7m〜223mの範囲で分布(サンプルサイズ20)している。
以下は、Mapを拡大したときに、あきらかに見た目のおかしいもの。
上は、高架下辺りでの測位、下は、マンションと高速道路高架付近での測位となっている。
これを見る限り、このレベルの拡大となると、誤差が相当に目だってしまうのが分かる。
ルートのトレースレベルで見ると、見た目の粗は目に付かない。
先にも述べたように、私のau端末は旧式のもの。
機種変更をしたら、また、測位してみようと思う。アンテナが進化していると思うので。