Geolocation API を使用すると、ユーザーの同意を得たうえで、ユーザーの現在地を検出できます。
Geolocation API を使用すると、ユーザーの同意を得たうえで、ユーザーの現在地を検出できます。この機能は、ユーザーを目的地に案内したり、ユーザーが作成したコンテンツにジオタグを付けたり(写真を撮った場所にマークするなど)に使用できます。
Geolocation API では、常にユーザーの同意を得て(ページが開いている間のみ)ユーザーの現在地を確認し、移動中も監視することができます。これにより、バックエンド システムと統合し、ユーザーが近くにいる場合に注文の受け取りを準備するなど、興味深いユースケースが多数生まれます。
Geolocation API を使用する際は、多くの点に注意する必要があります。このガイドでは、一般的なユースケースとソリューションについて説明します。
まとめ
- ユーザーにとって有益な場合に位置情報を使用します。
- ユーザー操作に対する明確な応答として権限を要求します。
- ユーザーのブラウザが位置情報をサポートしていない場合は、機能検出を使用します。
- ここでは、位置情報を実装する方法だけでなく、位置情報の最適な使用方法を学びます。
- サイトの位置情報をテストします。
位置情報を使用する場面
- 特定の物理的な場所に最も近いユーザーの場所を見つけて、ユーザー エクスペリエンスを調整します。
- ユーザーの現在地に合わせて情報(ニュースなど)をカスタマイズする。
- 地図上にユーザーの位置を表示します。
- アプリケーション内で作成されたタグデータにユーザーの位置情報を含める(つまり、写真にジオタグを付ける)。
責任を持って許可を求める
最近のユーザー調査によると、ユーザーは、ページの読み込み時にユーザーに位置情報を放棄するよう求めるだけのサイトに対して不信感を抱くことが示されています。では、ベスト プラクティスとはどのようなものでしょうか。
ユーザーから位置情報が提供されないと仮定する
多くのユーザーは自分の居場所を提供したくないため、防御的な開発スタイルを採用する必要があります。
- Geolocation API からのすべてのエラーを処理して、サイトをこの条件に適応できるようにします。
- 位置情報が必要なことを明確かつ明示的に示します。
- 必要に応じて代替ソリューションを使用します。
位置情報が必要な場合はフォールバックを使用する
サイトやアプリケーションでユーザーの現在地へのアクセスを必要としないことをおすすめします。ただし、サイトまたはアプリケーションでユーザーの現在地が必要な場合は、ユーザーの現在地を最も正確に推測できるサードパーティのソリューションがあります。
多くの場合、これらのソリューションはユーザーの IP アドレスを確認し、RIPE データベースに登録された物理アドレスにマッピングすることで機能します。これらの位置情報はあまり正確でないことが多く、通常はユーザーに最も近い電気通信ハブや携帯電話の基地局の位置がわかります。多くの場合、特にユーザーが VPN やその他のプロキシ サービスを使用している場合は、それほど正確でないこともあります。
ユーザー操作で常に位置情報へのアクセスをリクエストする
位置情報を尋ねる理由と、位置情報をユーザーに提示するメリットをユーザーが理解できるようにします。サイトの読み込み直後にホームページでリクエストすると ユーザーエクスペリエンスが低下します
![サイトが店舗検索ページで権限をリクエストしている。](https://web.dev/static/articles/user-location/image/a-site-requesting-permiss-7da80ad474ecf.png?authuser=8&hl=ja)
![サイトがホームページへのアクセス許可を求めています。](https://web.dev/static/articles/user-location/image/a-site-requesting-permiss-de9fb69ac4117.png?authuser=8&hl=ja)
代わりに、ユーザーに明確な行動喚起や、位置情報へのアクセスが必要な操作を示します。これにより、ユーザーは、アクセスを求めるシステム プロンプトと、開始したアクションをより簡単に関連付けることができます。
アクションによって位置情報がリクエストされることを明確に示す
Google 広告チームの調査によると、ある特定のホテルのサイトで予定されている会議のためにボストンのホテルを予約するようユーザーに依頼されると、ホームページの「検索して予約」という行動を促すフレーズをタップした直後に、GPS 位置情報を共有するように求められました。
場合によっては、ボストンのホテルを予約しようとしたときに、サンフランシスコのホテルが表示される理由がわからず、ユーザーが不満を感じることがあります。
よりよい体験は、位置情報を尋ねる理由をユーザーが理解できるようにすることです。距離計など、複数のデバイスに共通するよく知られた記号や、「この近くで探す」などの明示的な行動を促すフレーズを追加します。
![距離計。](https://web.dev/static/articles/user-location/image/a-range-finder-318d55f8a5009.png?authuser=8&hl=ja)
![[近くの場所を探す] ボタンを含むフォーム。](https://web.dev/static/articles/user-location/image/a-form-a-find-near-butt-9d544025fb506.png?authuser=8&hl=ja)
位置情報の利用許可を付与するようユーザーに丁寧に案内する
ユーザーの操作にはアクセスできません。ユーザーが位置情報へのアクセスを許可しないタイミングは正確にはわかっても、いつアクセスを許可されたかはわからないため、結果が表示されてからアクセスを取得したということしかわかりません。
ユーザーにアクションを完了してもらう必要がある場合は、ユーザーにアクションを「誘導」することをおすすめします。
次のような方法をおすすめします。
- 短時間後にトリガーされるタイマーを設定します。5 秒は適切な値です。
- エラー メッセージが表示された場合は、ユーザーにメッセージを表示します。
- 肯定的な応答が返された場合は、タイマーを無効にして結果を処理します。
- タイムアウト後に肯定的な回答が得られない場合は、ユーザーに通知を表示します。
- 後で応答があっても通知が表示される場合は、画面から削除します。
button.onclick = function () {
var startPos;
var nudge = document.getElementById('nudge');
var showNudgeBanner = function () {
nudge.style.display = 'block';
};
var hideNudgeBanner = function () {
nudge.style.display = 'none';
};
var nudgeTimeoutId = setTimeout(showNudgeBanner, 5000);
var geoSuccess = function (position) {
hideNudgeBanner();
// We have the location, don't display banner
clearTimeout(nudgeTimeoutId);
// Do magic with location
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
};
var geoError = function (error) {
switch (error.code) {
case error.TIMEOUT:
// The user didn't accept the callout
showNudgeBanner();
break;
}
};
navigator.geolocation.getCurrentPosition(geoSuccess, geoError);
};
ブラウザ サポート
現在、ほとんどのブラウザで Geolocation API がサポートされていますが、何かを行う前に、サポート状況を常に確認することをおすすめします。
位置情報オブジェクトの存在をテストすることで、簡単に互換性を確認できます。
// check for Geolocation support
if (navigator.geolocation) {
console.log('Geolocation is supported!');
} else {
console.log('Geolocation is not supported for this Browser/OS.');
}
ユーザーの現在地を確認する
Geolocation API には、ユーザーの位置情報を取得するシンプルな「ワンショット」メソッド getCurrentPosition()
が用意されています。このメソッドを呼び出すと、非同期でユーザーの現在地が報告されます。
window.onload = function () {
var startPos;
var geoSuccess = function (position) {
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
};
navigator.geolocation.getCurrentPosition(geoSuccess);
};
このドメイン上のアプリケーションが初めて権限をリクエストする場合、ブラウザは通常、ユーザーの同意を確認します。ブラウザによっては、権限のルックアップを常に許可または禁止する設定があり、その場合、確認プロセスは省略されます。
ブラウザが使用している位置情報デバイスによっては、位置オブジェクトには、緯度と経度だけでなく、たとえば高度や方向など、多くの情報が含まれている場合があります。実際にデータが返されるまで、位置情報システムが使用する追加情報はわかりません。
ユーザーの現在地を監視する
Geolocation API を使用すると、getCurrentPosition()
を 1 回呼び出すだけで(ユーザーの同意を得て)ユーザーの位置情報を取得できます。
ユーザーの位置情報を継続的にモニタリングするには、Geolocation API メソッド watchPosition()
を使用します。動作は getCurrentPosition()
と同様ですが、位置測定ソフトウェアとして複数回起動します。
- ユーザーをより正確にロックします。
- ユーザーの位置が変化しているかどうかを判断します。
var watchId = navigator.geolocation.watchPosition(function (position) {
document.getElementById('currentLat').innerHTML = position.coords.latitude;
document.getElementById('currentLon').innerHTML = position.coords.longitude;
});
ユーザーの位置情報を確認するために位置情報を使用するタイミング
- ユーザーの位置情報をより正確にロックしたい場合。
- アプリは、新しい位置情報に基づいてユーザー インターフェースを更新する必要があります。
- ユーザーが特定の定義されたゾーンに入ったときに、アプリケーションでビジネス ロジックを更新する必要があります。
位置情報を使用する際のベスト プラクティス
常にクリーンアップしてバッテリーを節約する
位置情報の変更を監視することは、無料のオペレーションではありません。オペレーティング システムでは、アプリケーションが地理サブシステムに接続できるようにプラットフォーム機能を導入しているかもしれませんが、ウェブ デベロッパーは、ユーザーの位置情報をモニタリングするためにユーザーのデバイスがどのようなサポートをしているか把握していません。また、位置を監視している間は、多くの追加処理をデバイスで行うことになります。
ユーザーの位置を追跡する必要がなくなったら、clearWatch
を呼び出して位置情報システムをオフにします。
エラーを適切に処理する
残念ながら、すべての場所のルックアップが成功するわけではありません。GPS の位置を特定できなかったか、ユーザーが位置情報のルックアップを突然無効にしたことが考えられます。エラーが発生した場合は、getCurrentPosition()
に対する 2 番目のオプションの引数が呼び出され、コールバック内でユーザーに通知できます。
window.onload = function () {
var startPos;
var geoSuccess = function (position) {
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
};
var geoError = function (error) {
console.log('Error occurred. Error code: ' + error.code);
// error.code can be:
// 0: unknown error
// 1: permission denied
// 2: position unavailable (error response from location provider)
// 3: timed out
};
navigator.geolocation.getCurrentPosition(geoSuccess, geoError);
};
位置情報ハードウェアを起動する必要がない
多くのユースケースでは、ユーザーの最新の位置情報は必要なく、大まかな推定値が必要です。
maximumAge
オプション プロパティを使用すると、最近取得した位置情報の結果を使用するようにブラウザに指示します。これにより、ユーザーが以前にデータをリクエストした場合にすばやく返されるだけでなく、ブラウザが Wi-Fi 三角測量や GPS などの位置情報ハードウェア インターフェースを起動できなくなります。
window.onload = function () {
var startPos;
var geoOptions = {
maximumAge: 5 * 60 * 1000,
};
var geoSuccess = function (position) {
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
};
var geoError = function (error) {
console.log('Error occurred. Error code: ' + error.code);
// error.code can be:
// 0: unknown error
// 1: permission denied
// 2: position unavailable (error response from location provider)
// 3: timed out
};
navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
};
ユーザーを待たせないように、タイムアウトを設定する
タイムアウトを設定しないと、現在の位置のリクエストは返されない場合があります。
window.onload = function () {
var startPos;
var geoOptions = {
timeout: 10 * 1000,
};
var geoSuccess = function (position) {
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
};
var geoError = function (error) {
console.log('Error occurred. Error code: ' + error.code);
// error.code can be:
// 0: unknown error
// 1: permission denied
// 2: position unavailable (error response from location provider)
// 3: timed out
};
navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
};
精度の高い位置情報よりも低精度の位置情報を優先する
ユーザーに最も近い店舗を検索する場合、1 メートルの精度が必要になることはあまりありません。この API は、可能な限り早く結果を返すおおまかな位置情報を提供するように設計されています。
高レベルの精度が必要な場合は、enableHighAccuracy
オプションでデフォルト設定をオーバーライドできます。解決に時間がかかり、バッテリーの使用量が多いため、慎重に使用してください。
window.onload = function () {
var startPos;
var geoOptions = {
enableHighAccuracy: true,
};
var geoSuccess = function (position) {
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
};
var geoError = function (error) {
console.log('Error occurred. Error code: ' + error.code);
// error.code can be:
// 0: unknown error
// 1: permission denied
// 2: position unavailable (error response from location provider)
// 3: timed out
};
navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
};
Chrome DevTools を使用して位置情報をエミュレートする
![DevTools の [Sensor] タブ。](https://web.dev/static/articles/user-location/image/the-sensor-tab-devtools-99f58f9bf1aac.png?authuser=8&hl=ja)
位置情報を設定したら、以下を行います。
- さまざまな地域でアプリの動作をテストします。
- 位置情報が利用できない場合に、アプリのグレースフル デグラデーションが行われることを確認します。
どちらも Chrome DevTools で行うことができます。
- Chrome DevTools を開きます。
- Esc キーを押してコンソール ドロワーを開きます。
- コンソール ドロワー メニューを開く
- [センサー] オプションをクリックして、[センサー] タブを表示します。
ここから、ロケーションをプリセットの大都市にオーバーライドしたり、カスタムの場所を入力したり、オーバーライドを [Location unavailable] に設定して位置情報を無効にしたりできます。