geolocation API により、ユーザーは希望すれば自身の場所を web アプリケーションに通知することができるようになります。なお、プライバシー保護の観点から、ユーザーは位置情報が送信される際には確認を求められます。
geolocation オブジェクト
geolocation API は navigator.geolocation
オブジェクトを通じて提供されます。
このオブジェクトが存在していれば、geolocation サービスを使うことが可能です。以下のようなコードで geolocation の存在を確認することができます:
if ("geolocation" in navigator) { /* geolocation is available */ } else { /* geolocation IS NOT available */ }
注記: Firefox 24 およびそれ以前のバージョンでは API が無効化されている場合でも、"geolocation" in navigator
が常に true
を返します。これは Firefox 25 で、仕様書に適合するよう修正しました (バグ 884921)。
現在位置の取得
ユーザーの現在位置を取得するには、getCurrentPosition()
メソッドを呼び出します。このメソッドはユーザーの現在位置を特定するための非同期通信を開始するとともに、位置取得デバイスから最新の情報を取得します。現在位置が特定されるとコールバック関数が実行されます。また、オプションとして第二引数にコールバック関数を指定することで、エラー発生時に実行される関数を指定することができます。省略可能な第三引数は、最大試行回数、要求待ち時間、高精度の位置情報を求めるかを指定するオブジェクトです。
注記: 既定の getCurrentPosition()
は、低精度の結果により可能な限り高速な応答を試みます。これは、正確さに関わらず速い応答を必要とする場合に役立ちます。例えば GPS を備えるデバイスでは GPS による補正に時間をかけることができますので、getCurrentPosition()
で低精度のデータ (IP ロケーションや Wi-Fi) が返されてもかまいません。
navigator.geolocation.getCurrentPosition(function(position) { do_something(position.coords.latitude, position.coords.longitude); });
上記の例では、位置情報が取得でき次第 do_something() 関数が実行されます。
現在位置の監視
位置情報が変化した場合 (デバイスの移動やより正確な位置情報を得ることにより) は、位置情報の更新と同時に呼び出されるコールバック関数を規定することができます。これは getCurrentPosition()
メソッドと同じ引数を持つ watchPosition()
メソッドを使うことで実現できます。コールバック関数は繰り返し呼び出され、ブラウザは移動に応じて位置情報を更新したり、位置の特定に別の技術を使用することでより詳細な位置情報を提供したりすることが可能です。エラー発生時に呼び出されるコールバック関数は getCurrentPosition()
と同様に任意指定であり、繰り返し呼び出される場合があります。
注記: 初めに getCurrentPosition()
を呼び出すことなく、watchPosition()
を使用できます。
var watchID = navigator.geolocation.watchPosition(function(position) { do_something(position.coords.latitude, position.coords.longitude); });
watchPosition()
メソッドは、呼び出し元を特定するための一意な ID 番号を返します。この ID 番号を clearWatch()
メソッドに渡すことでユーザーの位置監視を終了することができます。
navigator.geolocation.clearWatch(watchID);
応答の微調整
getCurrentPosition()
および watchPosition()
は成功時のコールバック、省略可能なエラー時のコールバック、そして省略可能な PositionOptions
オブジェクトを受け取ります。
watchPosition
の呼び出しは以下のようになります:
function geo_success(position) { do_something(position.coords.latitude, position.coords.longitude); } function geo_error() { alert("Sorry, no position available."); } var geo_options = { enableHighAccuracy: true, maximumAge : 30000, timeout : 27000 }; var wpid = navigator.geolocation.watchPosition(geo_success, geo_error, geo_options);
watchPosition の使用デモはこちらです: https://www.thedotproduct.org/experiments/geo/
位置の記述
ユーザーの位置情報は、Coordinates
オブジェクトを参照する Position
オブジェクトを用いることで表記されます。
エラーのハンドリング
getCurrentPosition()
もしくは watchPosition()
を呼び出す際にエラーコールバック関数を指定する場合、その第一引数は PositionError
オブジェクトであるものとします。
function errorCallback(error) { alert('ERROR(' + error.code + '): ' + error.message); };
Geolocation のライブサンプル
body { padding: 20px; background-color:#ffffc9 } p { margin : 0; }
HTML コンテンツ
<p><button onclick="geoFindMe()">Show my location</button></p> <div id="out"></div>
JavaScript コンテンツ
function geoFindMe() { var output = document.getElementById("out"); if (!navigator.geolocation){ output.innerHTML = "<p>Geolocation is not supported by your browser</p>"; return; } function success(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; output.innerHTML = '<p>Latitude is ' + latitude + '° <br>Longitude is ' + longitude + '°</p>'; var img = new Image(); img.src = "https://maps.googleapis.com/maps/api/staticmap?center=" + latitude + "," + longitude + "&zoom=13&size=300x300&sensor=false"; output.appendChild(img); }; function error() { output.innerHTML = "Unable to retrieve your location"; }; output.innerHTML = "<p>Locating…</p>"; navigator.geolocation.getCurrentPosition(success, error); }
結果
許可の要求
addons.mozilla.org で提供している、geolocation データを使用するアドオンは、そのデータを使用する前に明示的に許可を求めなければなりません。以下の関数は、Web ページ向けに自動的に表示されるプロンプトと似た方式で許可を求めます。ユーザの応答は適切であれば、パラメータ pref
で指定した設定項目に保存します。パラメータ callback
で提供する関数は、ユーザの応答を示す真偽値とともに呼び出します。true
であれば、アドオンは geolocation データへのアクセスが許されます。
function prompt(window, pref, message, callback) { let branch = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefBranch); if (branch.getPrefType(pref) === branch.PREF_STRING) { switch (branch.getCharPref(pref)) { case "always": return callback(true); case "never": return callback(false); } } let done = false; function remember(value, result) { return function() { done = true; branch.setCharPref(pref, value); callback(result); } } let self = window.PopupNotifications.show( window.gBrowser.selectedBrowser, "geolocation", message, "geo-notification-icon", { label: "Share Location", accessKey: "S", callback: function(notification) { done = true; callback(true); } }, [ { label: "Always Share", accessKey: "A", callback: remember("always", true) }, { label: "Never Share", accessKey: "N", callback: remember("never", false) } ], { eventCallback: function(event) { if (event === "dismissed") { if (!done) callback(false); done = true; window.PopupNotifications.remove(self); } }, persistWhileVisible: true }); } prompt(window, "extensions.foo-addon.allowGeolocation", "Foo Add-on wants to know your location.", function callback(allowed) { alert(allowed); });
ブラウザ実装状況
機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
基本サポート | 5 | 3.5 (1.9.1)[1] | 9 | 10.60 未サポート 15.0 16.0 |
5 |
機能 | Android | Chrome for Android | Firefox Mobile (Gecko) | Firefox OS | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|---|
基本サポート | ? | ? | 4.0 (4) | 1.0.1 | ? | 10.60 未サポート 15.0 16.0 |
? |
[1] Firefox は、Google Location Services を使用した Wi-Fi 情報に基づく位置測定をサポートします。Firefox と Google との間の処理において、Wi-Fi アクセスポイントのデータ、アクセストークン (2 週間有効な cookie に似たもの)、ユーザーの IP アドレスを含むデータを交換します。詳しくは Mozilla のプライバシーポリシーおよびどのようにデータを使用するか似関する Google のプライバシーポリシーを確認してください。
Firefox 3.6 (Gecko 1.9.2) で、Linux での geolocation 向け GPSD (GPS デーモン) サービスをサポートしました。