GoogleMapsAPIなどを利用する場合、経度や緯度といった座標情報を取得する必要があります。これはジオコーディング(Geocoding)と呼ばれ、GoogleMapsAPIにもそのための仕組みが用意されていました。
それに対し、GPSや地図をドラッグさせるなどして取得した座標から地名などを取得する方法は逆ジオコーディング(Reverse Geocoding)と呼ばれていますが、以前はこちらの方法はAPIが提供されていませんでした。
しかし、いつの間にか(V3になってから?)GoogleMapsAPIでも逆ジオコーディングが出来るようになっていたので、今回はそれをつかって、スマホから現在地を取得し、住所を表示させてみようと思います。
GPSから座標を取得する方法
今回はHTML5のGeolocationAPIという仕組みを使います。
理由としては、
- 実装が簡単であること
- GPSを使ったウェブアプリとなるとターゲットはほぼスマホになること
- スマホブラウザをメインとするならデスクトップ向けよりもHTML5をごりごり使えること(古いIEとかを考慮しないでいいため)
などです。
GeolocationAPIはGPS以外にも、無線LAN・WiFi・携帯電話基地局・IPアドレスなどから現在地を割り出すことが出来るため、PC環境でもある程度の位置までは取得できるようです。 ((ただし、接続環境によってはかなり大雑把なところまでしか取れなかったり、そもそも取得ができない場合もあります。))
では早速現在地を取得してみましょう。
1 2 3 4 5 6 7 8 9 |
<script> navigator.geolocation.getCurrentPosition(is_success,is_error); is_success(position) { // 取得成功時に何かする } is_error(error) { // 取得失敗時に何かする } </script> |
これだけでOKです。
実行結果に応じて、成功したら第一引数の関数が、失敗すると第二引数の関数が呼ばれます。
今回は、成功時は is_success()、失敗時は is_error() という関数名に、更にそれぞれ、position、errorに結果を格納するようにしました。名前を変更する場合はうまいこと読み替えて下さい(←
と、いうことで成功時は position に座標情報が格納されますので、それを取り出していけばOKです。
経度 | position.coords.latitude |
---|---|
緯度 | position.coords.longitude |
高度 | position.coords.attitude |
経度・緯度の誤差 | position.coords.accuracy |
高度の誤差 | position.coords.altitudeAccuracy |
方角 | position.coords.heading |
速度 | position.coords.speed |
例えば、経度をコンソールに出したいなら、
1 |
console.log('position.coords.latitude'); |
って具合です。
続いてエラーの時の内容ですが、こちらはエラーの内容に応じて error.code にエラーコードが返ってきます。また、エラーの詳細が error.message に入ります
1 | PERMISSION_DENIED 位置情報の取得が許可されていない |
---|---|
2 | POSITION_UNAVAILABLE デバイスの位置情報の取得に失敗 |
3 | TIMEOUT 処理がタイムアウトした (タイムアウト時間を指定してる場合) |
ただし、エラーが起きた時に、ユーザーに提示するエラーメッセージとして error.message をそのまま使用すべきではないとのことなので、このコードで判定して独自にメッセージを作成したほうがいいみたいです。 ((error.messageはデバッグ用らしいです))
ということで、ここまでをまとめるとこんなかんじになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!DOCTYPE html> <html> <head> <title>GeolocationAPI Test</title> <meta charset=utf8> <script> navigator.geolocation.getCurrentPosition(is_success,is_error); function is_success(position) { var result = '結果'; result += '経度:' + position.coords.latitude + '<br>'; result += '緯度:' + position.coords.longitude + '<br>'; result += '高度:' + position.coords.attitude + '<br>'; result += '経度・緯度の誤差:' + position.coords.accuracy + '<br>'; result += '高度の誤差:' + position.coords.altitudeAccuracy + '<br>'; result += '方角:' + position.coords.heading + '<br>'; result += '速度:' + position.coords.speed + '<br>'; document.getElementById('result').innerHTML = result; } function is_error(error) { var result = ""; switch(error.code) { case 1: result = '位置情報の取得が許可されていません'; break; case 2: result = '位置情報の取得に失敗しました'; break; case 3: result = 'タイムアウトしました'; break; } document.getElementById('result').innerHTML = result; } </script> </head> <body> <div id="result"></div> </body> </html> |
これを適当に名前をつけて、ブラウザで開くと、「現在地の利用を許可するか」を聞いてきますので許可します。拒否すると、エラーコード2になります。
取得出来れば現在地の座標が表示されるはずです。
これで座標の取得はできるようになりました。
続いて座標から地名を取得(逆ジオコーディング)します。
逆ジオコーディングの方法
ジオコーディング サービス – Google Maps JavaScript API v3 — Google Developers
こちらのページを見ると、逆ジオコーディング(住所の逆検索)という章があり、そこにそのまんまサンプル付きで載っていますので、それをそのまま利用すればよさそうですね。
サンプルではフォームに入力された座標から地名を取得し、地図をそこに移動してバルーンに地名を出していますが、今回は地図は出さないしフォームも使わずGPSからとった位置で判定するのでその辺をごりごり消していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
<!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0,user-scalable=no"> <meta charset="utf-8"> <title>Reverse Geocoding Test</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script> var geocoder; // 現在地の取得 navigator.geolocation.getCurrentPosition(is_success,is_error); function is_success(position) { var gpsLat = position.coords.latitude; var gpsLng = position.coords.longitude; gmap_init(gpsLat,gpsLng); } function is_error(error) { var result = ""; switch(error.code) { case 1: result = '位置情報の取得が許可されていません'; break; case 2: result = '位置情報の取得に失敗'; break; case 3: result = 'タイムアウト'; break; } document.getElementById('message').innerHTML = result; } // googlemap init function gmap_init(gpsLat,gpsLng) { geocoder = new google.maps.Geocoder(); var latlng = new google.maps.LatLng(gpsLat,gpsLng); geocoder.geocode({'latLng':latlng},function(results,status){ if (status == google.maps.GeocoderStatus.OK) { console.log(results[1].formatted_address); result = '現在地の取得に成功<br>'; result += '経度:' + gpsLat + '<br>'; result += '緯度:' + gpsLng + '<br>'; result += '住所:' + results[2].formatted_address + '<br>'; document.getElementById('message').innerHTML = result; } else { console.log(status); } }); } </script> </head> <body> <div id="message"></div> </body> </html> |
これを保存して開くと、
現在地の経度・緯度・住所が表示されるはずです。
因みに地名の精度(?)は
results[0].formatted_address
の[0]って部分で変更できます。
0〜7まであって、それぞれ取得できる範囲が異なります。
– | 皇居の例 | スカイツリーの例 |
0 | 日本, 〒102-0072 東京都千代田区千代田1−1 | 日本, 東京都墨田区押上1丁目1−2 |
1 | 〒100-8111, 日本 | 日本, 東京スカイツリータウン(バス)(東京) |
2 | 〒100-0001, 日本 | 日本, 東京都墨田区押上1丁目1 |
3 | 〒100-0001, 日本 | 日本, 東京都墨田区押上1丁目 |
4 | 〒102-0072, 日本 | 日本, 東京都墨田区押上 |
5 | 日本, 東京都千代田区千代田 | 〒131-0045, 日本 |
6 | 日本, 東京都千代田区千代田1 | 日本, 押上駅(東京) |
7 | 〒101-0021, 日本 | 日本, 東京都墨田区 |
こんなかんじで、実はいろんな返り方をします。0番以外は結構ブレますね。
一致率が最も高い住所から最も低い住所の順で表示されます。通常、より正確な住所が最も重要な結果であり、この場合もそうなっています。最も詳細な番地まで含む住所から、周辺地域、都市、郡、州などのより範囲の広い行政区画まで、さまざまなタイプの住所が返されていることに注意してください。より一般的な住所との一致を検索する場合は、results[].types
フィールドを調べます。
注: 逆ジオコーディングは科学的に正確というわけではありません。ジオコーダは、一定の許容範囲内で最も近い、住所の特定が可能な場所を探そうとします。
とのことです。
逆ジオコーディングを使って住所を入力する場合でも、あくまでGPSによる取得は補助的なものとして使い、取得結果をフォームに出力させておいて、手動で修正できるようにするのがよさそうですね。
おまけ
ところで、GPSのテストとかをする場合、実際にあちこち移動してチェックするのは大変ですよね。
そんなときは開発ツールにあるGPSの上書き機能を使うと便利です。
Chromeでの例になりますが、Cmd+Opt+I(またはF12)でデベロッパーツールを開き、右下の歯車アイコンをクリックすると出てくる、Settings の Overrides にある、「Override Geolocation」を有効化して、座標を入力すると、GPSなどの機能を使うときにその座標を返すようになるそうです。
これを使えばいろんな座標でテストを行うことができますね。
しかし、これがうまく動かないことがあったり、そもそも座標を調べるのが面倒だったりってこともありますよね。
そんなときは、 Manual Geolocation という Chrome エクステンションが便利です。
インストールして、Manual Geolocation のアイコンをクリックすると、GoogleMapっぽいものが表示されます。初期状態では無効「disable」になってますので、「enable」をクリックします。
すると、地図上にマーカーが出て、そのマーカーの座標で現在地が上書きされます。
「場所を入力」に地名を入力して「search」をクリックするとマーカーが移動して、現在地の情報もそこに変わります。
また、手動で地図をダブルクリックしてもそのマーカーがその位置に移動します。
更に、マーカーの下の「○」をドラッグすると、このように輪を広げることができます。
これを調整することで、GPSの取得誤差をかえることができます。
デベロッパーツールについている機能を使うよりもこちらのほうが地図や地名から簡単に設定できるため、GPSを利用したなにかを作るときのテストにはおすすめです。
テストが終わったら「disable」をクリックして機能をオフにすることを忘れずに…。
ダウンロードはウェブストアからどうぞ。
Chrome ウェブストア – Manual Geolocation
参考
Geolocation API-HTML5のAPI、および、関連仕様
ジオコーディング サービス – Google Maps JavaScript API v3 — Google Developers
コメントする