ユーザーの現在地

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

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

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

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

概要

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

位置情報を使用する場合

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

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

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

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

多くのユーザーは自分の場所を知らせたくないと考えるため、受け身の開発スタイルを採用する必要があります。

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

Geolocation で必要な場合は、代替ソリューションを使用します。

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

そういったソリューションの多くは、ユーザーの 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() を呼び出すことで、ユーザーの位置を取得することができます(ユーザーの同意が必要)。

ユーザーの現在位置を継続的に監視する必要がある場合は、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 に設定して位置情報を無効にしたりできます。

フィードバック