Geolocation API を使用したシンプルなトリップ メーター

Michael Mahemoff
Michael Mahemoff

はじめに

Geolocation API を使用すると、ユーザーの同意を得たうえで、ユーザーの現在地を特定し、ユーザーの現在地を監視できます。この機能は、たとえば目的地まで案内するなど、ユーザーのクエリの一部として使用できます。また、ユーザーが作成した一部のコンテンツに「ジオタグ」を付けるため(写真を撮った場所に印を付けるなど)にも使用できます。この API はデバイスに依存しません。クライアントが標準的な方法で位置情報をリクエストして受信できるのであれば、ブラウザが位置情報をどのように特定するかは関係ありません。基本的なメカニズムとしては、GPS、Wi-Fi 経由、またはユーザーに手動で位置情報を入力するよう求める場合があります。検索には時間がかかるため、この API は非同期です。位置情報をリクエストするたびにコールバック メソッドを渡します。

この例では、トリップ メーターで最初の位置を表示し、ページの読み込み後の移動距離を表示しています。

ステップ 1: 互換性を確認する

対応ブラウザ

  • 5
  • 12
  • 3.5
  • 5

ソース

位置情報オブジェクトの存在をテストすることで、簡単に互換性を確認できます。

// check for Geolocation support
if (navigator.geolocation) {
  console.log('Geolocation is supported!');
}
else {
  console.log('Geolocation is not supported for this Browser/OS version yet.');
}

手順 2. トリップ メーターの HTML を宣言する

この例ではトリップ メーターを作成するので、次の HTML を宣言します。

<div id="tripmeter">
<p>
Starting Location (lat, lon):<br/>
<span id="startLat">???</span>°, <span id="startLon">???</span>°
</p>
<p>
Current Location (lat, lon):<br/>
<span id="currentLat">???</span>°, <span id="currentLon">???</span>°
</p>
<p>
Distance from starting location:<br/>
<span id="distance">0</span> km
</p>
</div>

次の数ステップでは、Geolocation API を使用して、これらの空のスパンすべてにデータを入力します。

ステップ 3: ユーザーの現在地を特定する

getCurrentPosition() は、非同期にユーザーの現在地を報告します。ページが読み込まれたらすぐに呼び出して、開始位置が正しく入力されるようにし、後で使用するために保存します。

window.onload = function() {
var startPos;
navigator.geolocation.getCurrentPosition(function(position) {
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
});
};

このドメイン上のアプリケーションが初めて権限をリクエストする場合、ブラウザは通常、ユーザーの同意を確認します。ブラウザによっては、権限のルックアップを常に許可または禁止する設定があり、その場合、確認プロセスは省略されます。

このコードを実行すると、開始位置が表示されるはずです。ブラウザが使用している位置情報デバイスによっては、位置オブジェクトには、実際には緯度と経度だけにとどまらない多くの情報(高度や方向など)が含まれている場合があります。位置変数をコンソールにロギングすることで、さらに調査できます。

ステップ 4: エラーの処理

残念ながら、すべての場所のルックアップが成功するわけではありません。たとえば、GPS の位置を特定できなかったか、ユーザーが位置情報のルックアップを突然無効にしたことが考えられます。エラーが発生すると、getCurrentPosition() の 2 つ目のオプションの引数が呼び出されます。これにより、コールバック内でユーザーに通知できます。

window.onload = function() {
var startPos;
navigator.geolocation.getCurrentPosition(function(position) {
// same as above
}, function(error) {
alert('Error occurred. Error code: ' + error.code);
// error.code can be:
//   0: unknown error
//   1: permission denied
//   2: position unavailable (error response from locaton provider)
//   3: timed out
});
};

ステップ 5. ユーザーの現在地を監視する

前回の getCurrentPosition() の呼び出しは、ページの読み込み時に 1 回だけ実行されていました。変更を追跡するには、watchPosition() を使用します。ユーザーが動くたびに、自動的にコールバック関数に通知します。

navigator.geolocation.watchPosition(function(position) {
document.getElementById('currentLat').innerHTML = position.coords.latitude;
document.getElementById('currentLon').innerHTML = position.coords.longitude;
});

ステップ 6. 移動距離を表示

このステップは Geolocation API と直接関係ありませんが、デモを締めくくり、位置情報の使用例を示します。watchPosition() ハンドラに行を追加して、移動距離を入力します。

navigator.geolocation.watchPosition(function(position) {
// same as above
document.getElementById('distance').innerHTML =
    calculateDistance(startPos.coords.latitude, startPos.coords.longitude,
                    position.coords.latitude, position.coords.longitude);
});

calculateDistance() 関数は、幾何学的アルゴリズムを実行して 2 座標間の距離を決定します。JavaScript の実装は、クリエイティブ・コモンズ ライセンスの下で、Moveable Type が提供しているスクリプトに基づいています。

function calculateDistance(lat1, lon1, lat2, lon2) {
var R = 6371; // km
var dLat = (lat2 - lat1).toRad();
var dLon = (lon2 - lon1).toRad();
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
        Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
        Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
}
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}