スマホアプリ開発にも便利な位置情報API - Geolocation API -
HTML5は、Webページを作成するための基本的なマークアップ言語HTMLの最新版です。もっとも、HTML5では、単なるマークアップ言語としての機能だけではなく、JavaScriptで利用できるAPIが大幅に拡充され、アプリケーション開発がより簡単になっているのが特徴です(HTML5について、より詳しくは別連載「今さら聞けないHTML5総おさらい」も参照してください)。
本連載では、このHTML5の基本的なテクニックをTIPS形式でまとめていくものです。
まず、第1回となる今回は、HTML5の新機能の中でも人気の高いGeolocation APIについて紹介します。サンプル一式は、会員限定特典としてダウンロードできます。記事末尾をご確認ください。
- TIPS 001:現在の位置情報を取得する
- TIPS 002:位置取得に失敗した場合の処理を定義する
- TIPS 003:位置情報の動作パラメータを設定する
- TIPS 004:現在の位置情報を定期的に取得する
- TIPS 005:位置情報の定期取得を中止する
- TIPS 006:Googleマップ連携で現在位置を地図表示する
Geolocation APIの概要とブラウザの対応状況
Geolocation APIはユーザーの現在の位置情報を取得するための命令群です。従来は、デバイスや携帯電話キャリアごとに独自のしくみを提供しており、アプリ開発にもそれぞれの仕様に従ったコードを記述する必要がありました。しかし、Geolocation APIの登場によって、ブラウザの機能のみで、しかも統一した方法で位置情報の取得が可能となります。
Geolocation APIのブラウザごとの対応バージョンは、以下の通りです。
表1:Geolocation APIの対応状況
ブラウザ | 対応バージョン |
---|---|
Internet Explorer | 9以降 |
Firefox | 3.5以降 |
Google Chrome | 5以降 |
Safari | 5以降 |
Opera | 10以降 |
TIPS 001:現在の位置情報を取得する
現在の位置情報を取得するには、navigator.geolocationオブジェクトのgetCurrentPositionメソッドを利用します。以下は、Geolocation API経由でユーザーの現在位置を取得し、経度/緯度/方角を表示する例です。
[リスト]現在の位置情報を取得するコード(current.html)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>HTML5 TIPS</title> <script> window.addEventListener('DOMContentLoaded', function() { // 結果の表示先(<div>要素)を取得 var latitude = document.querySelector('#latitude'); var longitude = document.querySelector('#longitude'); var heading = document.querySelector('#heading'); // Geolocation APIが利用できるかを判定(1) if (navigator.geolocation) { // 現在の位置情報を取得(2) navigator.geolocation.getCurrentPosition( function(pos) { // 取得した位置情報をページに反映(3) latitude.innerHTML = pos.coords.latitude; longitude.innerHTML = pos.coords.longitude; heading.innerHTML = pos.coords.heading; }, ...中略... ); } else { window.alert('Geolocation API対応ブラウザでアクセスしてください。'); } }, false ); </script> </head> <body> <!--Geolocation APIで取得した位置情報を表示--> <ul> <li>経度:<span id="latitude"></span></li> <li>緯度:<span id="longitude"></span></li> <li>方角:<span id="heading"></span></li> </ul> </body> </html>
実行結果は、以下の通りです。[●○が物理的な現在地を追跡する許可を求めています]のようなメッセージが表示されたら、[許可]ボタンをクリックしてください。ユーザーが明示的に許可しないかぎり、Geolocation APIが勝手に位置情報を取得することはありません(ただし、一度許可したら、次回以降、許可は求められません)。
図1:現在の位置情報をブラウザに表示(クリックで拡大) |
Geolocation APIは新しい命令なので、利用する前にまず、ブラウザが対応しているかをチェックしなければなりません。これを行っているのが(1)です。
Geolocation APIには、navigator.geolocationプロパティでアクセスできます。(1)では、プロパティに実際にアクセスしてみて、アクセスできたらGeolocation APIに対応していると判断し、以降の処理を行っているわけです(「機能テスト」と言います)。
Geolocation APIが未サポートである場合、サンプルではエラーメッセージをダイアログ表示しています。
現在位置は、getCurrentPositionメソッドで取得できます(2)。引数には、位置取得に成功した場合に実行する「成功コールバック関数」(コールバック)を指定します。
コールバックの引数posには、取得した位置情報(Positionオブジェクト)が自動的にセットされます。コールバックの中では、一般的に、このPositionオブジェクトを利用して、以降の処理を行うことになるでしょう。サンプルでは、取得した位置情報を表示しています(3)。
Positionオブジェクトでアクセスできる情報には、以下のようなものがあります。環境によっては取得できない情報もありますが、その場合、プロパティはnull、NaN、undefinedのいずれかを返します(上の図でも、[方角]の欄が空になっていることが確認できるでしょう)。
表2:Positionオブジェクトの主なプロパティ
プロパティ | 概要 | |
---|---|---|
coords | 位置情報(Coordinatesオブジェクト)。主なプロパティは以下 | |
プロパティ | 概要 | |
latitude | 緯度 | |
longitude | 経度 | |
altitude | 高度 | |
accuracy | 緯度/経度の誤差(m) | |
altitudeAccuracy | 高度の誤差(m) | |
heading | 方角(度) | |
speed | 速度(m/秒) | |
timestamp | 取得日時(1970年からの経過ミリ秒) |
TIPS 002:位置取得に失敗した場合の処理を定義する
getCurrentPositionメソッドの第2引数に「失敗コールバック関数」を指定しておくことで、位置情報の取得に失敗した場合に、エラーメッセージの表示などのエラー処理を行えます。
失敗コールバック関数は省略可能ですが、位置取得はネットワーク接続の理由をはじめ、さまざまな原因で失敗することがあります。位置取得できなかった場合にそのままにするのではなく、ユーザーに通知できるようなしくみを設けておくのが望ましいでしょう。
[リスト]位置取得に失敗した場合にメッセージ表示するコード(current.html)
// 現在の位置情報を取得 navigator.geolocation.getCurrentPosition( // 位置情報の取得に成功した場合の処理 function(pos) { ...中略... }, // 位置情報の取得に失敗した場合の処理 function(err) { // エラーコードに対応するメッセージを準備(1) var msgs = [ err.message, '位置情報の取得を許可されていません。', '位置情報の取得に失敗しました。', '位置情報を取得中にタイムアウトしました。' ]; // エラーコードに応じてメッセージをダイアログ表示(2) window.alert(msgs[err.code]); }, ...中略... );
エラーメッセージを確認したい場合には(例えばGoogle Chromeであれば)、
[現在地の例外]ウィンドウが表示されますので、そこから現在サンプルを配置しているホストを削除します。
図2:[現在地の例外]ウィンドウ(クリックで拡大) |
サンプルにアクセスすると、[●○が物理的な現在地を追跡する許可を求めています]のようなメッセージが表示されますので、[拒否]ボタンをクリックすると、以下のようなエラーメッセージを確認できます。
図3:現在位置を取得できなかった時のエラーメッセージ(クリックで拡大) |
失敗コールバック関数(サンプルの網掛け部分)の引数errには、エラー情報(PositionErrorオブジェクト)が渡されます。PositionErrorオブジェクトでアクセスできる情報は、以下の通りです。
表3:PositionErrorオブジェクトの主なプロパティ
プロパティ | 概要 | |
---|---|---|
code | エラーコード(戻り値は以下の通り) | |
値 | 意味 | |
0 | 不明なエラー | |
1 | 位置情報の取得を拒否された | |
2 | 位置情報を取得できない | |
3 | 取得処理中にタイムアウトした | |
message | 詳細なエラーメッセージ |
サンプルでは、エラーコード0~3に対応するエラーメッセージを配列msgsにセットしておくことで(1)、codeプロパティの値に応じてメッセージを返しているわけです(2)。
TIPS 003:位置情報の動作パラメータを設定する
getCurrentPositionメソッドの第3引数では、位置取得の動作オプションをハッシュの形式で設定できます。
[リスト]位置取得の動作オプションを設定するコード(current.html)
// 現在の位置情報を取得 navigator.geolocation.getCurrentPosition( // 位置情報の取得に成功した場合の処理 function(pos) { ...中略... }, // 位置情報の取得に失敗した場合の処理 function(err) { ...中略... }, // 位置取得の動作オプションを設定 { timeout : 10000, maximumAge : 0, enableHighAccuracy: true } );
getCurrentPositionメソッドに設定できる動作オプションには、以下のようなものがあります。
表4:Geolocation APIの動作オプション
オプション名 | 概要 |
---|---|
timeout | 取得タイムアウトまでの時間(ミリ秒) |
maximumAge | 位置情報の有効期限(ミリ秒) |
enableHighAccuracy | より精度の高い位置情報を取得するか(true/false) |
例えば位置情報の取得でタイムアウトエラーが頻発する場合には、まずtimeoutオプションを長めに設定すると良いでしょう。
maximumAgeオプションは、取得済みの位置情報(Positionオブジェクト)を維持する期間を表します。この値を0にした場合、常に新しい情報に更新しようとします。
スマホ環境では、enableHighAccuracyプロパティをtrueにすることで、GPS機能を利用するようになります。これによって、より精度の高い位置情報を取得できますが、反面、取得時間が長くなる、バッテリーの消耗が激しくなるなどのデメリットもありますので、注意してください。
TIPS 004:現在の位置情報を定期的に取得する
getCurrentPositionメソッドがワンポイントで位置情報を取得するのに対し、位置情報の変化を監視し、変化を定期的に取得するのがwatchCurrentPositionメソッドです。主に、移動しながら利用するスマホアプリなどで利用します。
[リスト]位置情報を定期的に取得するコード(watch.html)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>HTML5 TIPS</title> <script> window.addEventListener('DOMContentLoaded', function() { // 結果の表示先(<div>要素)を取得 var latitude = document.querySelector('#latitude'); var longitude = document.querySelector('#longitude'); var heading = document.querySelector('#heading'); var stop = document.querySelector('#stop'); // Geolocation APIが利用できるかを判定 if (navigator.geolocation) { // 現在の位置情報を定期的に取得 var id = navigator.geolocation.watchPosition( // 位置情報の取得に成功した場合の処理 function(pos) { latitude.innerHTML = pos.coords.latitude; longitude.innerHTML = pos.coords.longitude; heading.innerHTML = pos.coords.heading; }, // 位置情報の取得に失敗した場合の処理 function(err) { var msgs = [ err.message, '位置情報の取得を許可されていません。', '位置情報の取得に失敗しました。', '位置情報を取得中にタイムアウトしました。' ]; window.alert(msgs[err.code]); }, // 位置取得の動作オプションを設定 { timeout : 10000, maximumAge : 0, enableHighAccuracy: true } ); ...中略... } else { window.alert('Geolocation API対応ブラウザでアクセスしてください。'); } }, false ); </script> </head> <body> <!--Geolocation APIで取得した位置情報を表示--> <ul> <li>経度:<span id="latitude"></span></li> <li>緯度:<span id="longitude"></span></li> <li>方角:<span id="heading"></span></li> </ul> ...中略... </body> </html>
watchPositionメソッドの動作は、スマホ環境などでアクセスして確認してみましょう。ページにアクセスした状態で移動してみると、以下のように、位置情報の変化を確認できるはずです。
図4(左)/図5(右):移動すると、合わせて位置情報も変化(クリックで拡大) |
watchPositionメソッドの構文は、ほぼgetCurrentPositionメソッドと同じです(watchPositionメソッドでは、位置の変化が検出されるたびに成功コールバック関数が呼び出されますので、一度呼び出した後は、とりたてて呼び出しを意識する必要はありません)。
ただ、getCurrentPositionメソッドが戻り値を返さないのに対して、watchPositionメソッドは監視IDを返す点だけが異なります。この情報は、後から位置情報の監視を中断する際に利用します。
TIPS 005:位置情報の定期取得を中止する
watchPositionメソッドで開始した位置情報の監視は、clearWatchメソッドで中止できます。clearWatchメソッドには、watchPositionメソッドの戻り値である監視IDを渡すだけです。
[リスト]位置情報の監視を中止するコード(watch.html)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>HTML5 TIPS</title> <script> window.addEventListener('DOMContentLoaded', function() { ...中略... // [位置情報の監視を中止]ボタンを取得 var stop = document.querySelector('#stop'); ...中略... // 位置情報の監視を開始 var id = navigator.geolocation.watchPosition( ...中略... ); // ボタンクリック時に位置情報の監視を中止 stop.addEventListener('click', function() { navigator.geolocation.clearWatch(id); } ); ...中略... }, false ); </script> </head> <body> <ul> <li>経度:<span id="latitude"></span></li> <li>緯度:<span id="longitude"></span></li> <li>方角:<span id="heading"></span></li> </ul> <!--ボタンクリックで位置情報の取得を中止--> <input id="stop" type="button" value="位置情報の監視を中止" /> </body> </html>
サンプルを実行し、移動に応じて位置情報が変化すること、[位置情報の監視を中止]ボタンをクリックすると、移動しても位置情報の表示が「変わらなくなる」ことを確認してみましょう。
TIPS 006:Googleマップ連携で現在位置を地図表示する
Geolocation API経由で取得した位置情報は、Google Maps APIを介してGoogleマップ(http://maps.google.co.jp/)に反映させることもできます。GoogleマップとGeolocation APIとは直接の関係があるわけではありませんが、その性質上、セットで利用される機会も多いので、まずは基本だけでもおさえておくと便利です。
以下は、Geolocation APIで取得した現在位置を中心に、Googleマップを表示する例です。
[リスト]現在位置を中心とした地図を表示するコード(gmap.html)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>HTML5 TIPS</title> <!--Google Maps APIを有効化(1)--> <script src="http://maps.google.com/maps/api/js?sensor=true"></script> <script> window.addEventListener('DOMContentLoaded', function() { // Geolocation APIが利用できるかを判定 if (navigator.geolocation) { // 現在の位置情報を取得 navigator.geolocation.getCurrentPosition( // 位置情報の取得に成功した場合の処理 function(pos) { // 取得した位置情報をGoogleマップに反映(3) var gmap = new google.maps.Map( document.querySelector('#result'), { zoom: 15, center: new google.maps.LatLng( pos.coords.latitude, pos.coords.longitude ), mapTypeId: google.maps.MapTypeId.ROADMAP } ); }, // 位置情報の取得に失敗した場合の処理 function(err) { var msgs = [ err.message, '位置情報の取得を許可されていません。', '位置情報の取得に失敗しました。', '位置情報を取得中にタイムアウトしました。' ]; window.alert(msgs[err.code]); }, // 位置取得の動作オプションを設定 { timeout : 10000, maximumAge : 0, enableHighAccuracy: true } ); } else { window.alert('Geolocation API対応ブラウザでアクセスしてください。'); } }, false ); </script> </head> <body> <!--Googleマップを表示させる領域(2)--> <div id="result" style="width:500px; height:350px;"></div> </body> </html>
サンプルを実行すると、以下のように現在地を中心に、地図が表示されることが確認できます。ただし、Geolocation APIは、環境に応じてGPS(全地球測位システム)、Wi-Fi、IPアドレス、携帯電話の基地局などから位置情報を割り出します。ネットワーク環境によっては、位置情報の精度も変化しますので注意してください。
図6:現在地を中心とした地図を表示(クリックで拡大) |
Google Maps APIを有効にするには、
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- JavaScriptでローカルファイルを自在に操る- File API
- プラグインは要らない!音声/動画対応したHTML5- / 要素
- HTML+JavaScriptだけでブラウザに図形描画(3)- Canvas API-
- サンプルのプログラムコード解説
- デスクトップアプリライクな操作性を実現するドラッグ&ドロップAPI
- HTML+JavaScriptだけでブラウザに図形描画- Canvas API-
- クッキーより便利になったブラウザ標準ストレージ- Web Storage
- HTML+JavaScriptだけでブラウザに図形描画(2)- Canvas API-
- ブラウザの機能拡張「Gears」とは
- 近くにある病院の場所をキャラクターが音声で教えてくれるアプリを作る