ユーザーの現在地

Geolocation API では、ユーザーの同意を得たうえでユーザーの現在地を確認できます。

Geolocation API では、ユーザーの同意を得たうえでユーザーの現在地を確認できます。この機能は、ユーザーを目的地まで案内する、ユーザー作成コンテンツにジオタグを付ける(写真の撮影場所にマークを付けるなど)に使用できます。

Geolocation API では、ユーザーの同意を得ていれば(ページが開いている間のみ)ユーザーの位置を確認でき、移動中もどこにいるのかをトラックできます。これにより、さまざまな興味深いユースケースが実現できるようになります。たとえば、バックエンド システムと統合することで、ユーザーが近くにいる場合に、注文した品を受け取れるように準備することができます。

Geolocation API を使用する際は、さまざまな点に注意する必要があります。このガイドでは一般的なユースケースとソリューションについて順を追って説明します。

概要

  • 位置情報は、ユーザーにとって有益な場合に使用してください。
  • ユーザー操作に対する明確なレスポンスとしてパーミッションを要求します。
  • ユーザーのブラウザが位置情報をサポートしていない場合に備えて、機能検出を使用します。
  • 位置情報の実装方法だけでなく、位置情報の最適な使用方法を学びましょう。
  • サイトで位置情報をテストします。

位置情報を使用するタイミング

  • 特定の物理的な位置に最も近いユーザーの現在地を検索し、ユーザー エクスペリエンスを調整します。
  • ユーザーのいる場所に応じた情報(ニュースなど)を表示します。
  • ユーザーの位置を地図上に表示します。
  • ユーザーの位置情報を使用してアプリ内で作成されるタグデータ(写真にジオタグを付けるなど)。

責任を持って権限をリクエストする

最近のユーザー調査では、ユーザーは、ページ読み込み後に単純に位置情報を要求するサイトを信用しないという結果が示されています。では、ベスト プラクティスは何でしょうか?

ユーザーは自分の場所を知らせようとしない、ということを前提にします。

多くのユーザーは自分の位置情報を知りたがらないため、防御的な開発スタイルを採用する必要があります。

  1. Geolocation API からのすべてのエラーを処理して、この条件にサイトを適応できるようにします。
  2. 位置情報の必要性を明確かつ明示的にします。
  3. 必要に応じて代替ソリューションを使用します。

位置情報が必要な場合は、代替を使用します。

サイトやアプリケーションで、ユーザーの現在位置へのアクセスを要求しないようにすることをおすすめします。現在位置を取得する必要がある場合は、サードパーティのソリューションによってユーザーの現在位置を適切に推測することができます。

そういったソリューションの多くは、ユーザーの IP アドレスを取得して、それを RIPE データベースに登録された物理的な位置にマッピングすることによって機能します。多くの場合、これらの位置情報はあまり正確ではなく、通常、ユーザーに最も近い無線通信ハブや電波搭の位置が提供されます。多くのケースでは、特にユーザーが VPN または他のプロキシ サービスを使用していると、さらに精度が落ちる場合もあります。

ユーザーの操作時に限って位置情報へのアクセスをリクエストする

位置情報が必要な理由と位置情報を提供した場合の利点を、ユーザーが理解できるようにします。サイトが読み込まれた直後にホームページで位置情報を求めると、ユーザーにあまり良くない印象を与えてしまいます。

店舗検索ページで権限をリクエストしているサイト。
推奨: 常に、ユーザーの操作時に限って位置情報へのアクセスをリクエストします。
トップページで権限をリクエストしているサイト。
しないでください: サイトの読み込み時にホームページで位置情報を求めると、ユーザーにあまり良くない印象を与えてしまいます。

代わりに、ユーザーに明確な行動喚起を行うか、位置情報へのアクセスが必要になる旨を明記します。この対応により、ユーザーは、自分が今行ったアクションによって、アクセスを要求するシステム プロンプトが表示されていることを理解しやすくなります。

ユーザーのアクションに位置情報が必要であることを明確に示す

Google 広告チームの調査では、ユーザーに対して、特定のホテルの会場で開催されるコンファレンスのためにボストンのホテルを予約するように求めました。そこでユーザーがホームページの [検索と予約] というアクションを要請するボタンをタップすると、直後に GPS の位置情報を共有するよう求められます。

ボストンのホテルの部屋を予約したいときに、サンフランシスコのホテルが表示される理由が分からず、ストレスを感じたユーザーもいました。

より良いエクスペリエンスを実現するには、位置情報を要求している理由をユーザーが理解できるようにする必要があります。レンジ ファインダーのようなデバイスによらない共通のマークを追加するか、[この近くを検索] などの明示的な行動喚起を行うことを検討します。

レンジ ファインダー。
レンジファインダーを使用する
[近くを検索] ボタンがあるフォーム。
「近くを検索」するための行動を促すフレーズ

位置情報へのアクセス許可が得られるようにユーザーを丁寧に誘導する

ユーザーの操作にアクセスできるわけではありません。ユーザーが位置情報へのアクセスを拒否するシーンは自明でも、アクセスを許可するシーンは特定できないため、結果が表示されるまではアクセスが許可されたことを知ることができません。

ユーザーにアクションを完了してほしい場合は、アクションを行うようにユーザーを「誘導する」ことが重要です。

次のように設定することをおすすめします。

  1. 短い時間でトリガーされるタイマーを設定します(5 秒が適切な値です)。
  2. エラー メッセージが出る場合は、そのメッセージをユーザーにも表示します。
  3. 肯定的なレスポンスが得られたら、タイマーを無効にして、結果を処理してください。
  4. タイマーがタイムアウトしても望む応答が得られない場合は、ユーザーに通知を表示します。
  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 は現在、大部分のブラウザでサポートされていますが、処理を実行する前には必ずサポート状況を確認することをお勧めします。

Geolocation オブジェクトの有無を調べることで、簡単に互換性を確認することができます。

// 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() と同様ですが、こちらは以下のような場合に、位置情報を得るために繰り返し処理を実行します。

  1. より正確にユーザーをロックします。
  2. ユーザーの位置が変化していることを判別します。
var watchId = navigator.geolocation.watchPosition(function (position) {
  document.getElementById('currentLat').innerHTML = position.coords.latitude;
  document.getElementById('currentLon').innerHTML = position.coords.longitude;
});

ユーザーの位置を確認するために位置情報を使用する場合

  • ユーザーの位置情報をより正確にロックする必要があります。
  • 新しい位置情報に基づいて、アプリケーションでユーザー インターフェースをアップデートする必要がある。
  • ユーザーが特定の定義されたゾーンに入ったときに、アプリケーションでビジネス ロジックをアップデートする必要がある。

位置情報を使用する際のベスト プラクティス

不要な追跡は必ず停止してバッテリーを節約する

GeoLocation で位置情報の変化を監視するには、リソースが必要になります。オペレーティング システムでは、アプリケーションが位置情報サブシステムに接続できるようにするプラットフォーム機能が導入されている場合がありますが、ウェブ デベロッパーは、ユーザーのデバイスがユーザーの位置情報をモニタリングするためにどのようなサポートを提供しているかを把握できません。また、位置情報を監視している間、デバイスで多くの余分な処理が行われます。

ユーザーの位置を追跡する必要がなくなったら、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 オプション プロパティを使用して、最近得られた位置情報の結果を使用するようにブラウザに指示します。これにより、ユーザーが以前にデータをリクエストしていた場合に、より迅速にデータが返されるようになるだけでなく、ブラウザによって WiFi の三角測量や 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 の [センサー] タブ。

位置情報を設定したら、次のことを行います。

  • さまざまな位置情報に対してアプリがどのように機能するかをテストする。
  • 位置情報が利用できないときに、アプリの機能が適切に制限されることを確認する。

どちらも Chrome DevTools から行うことができます。

  1. Chrome DevTools を開きます
  2. Esc キーを押して、コンソール ドロワーを開きます
  3. コンソール ドロワー メニューを開く
  4. [センサー] オプションをクリックして [センサー] タブを表示します。

ここで、事前に設定された主要都市で位置情報をオーバーライドしたり、カスタムの位置情報を入力したり、オーバーライドを [Location unavailable] に設定して位置情報を無効にしたりできます。

フィードバック