Geolocation API

現在位置を取得する

 現在位置を取得する方法として「 クイック・スタート 」で、getCurrentPosition()メソッドを紹介しましたが、このメソッドについてもう少し詳細を解説します。

getCurrentPosition() メソッド


navigator.geolocation.getCurrentPosition(
	successCallback,
	errorCallback,
	options
);

 このメソッドは最大で 3つの引数を取ります。

第一引数 successCallback
これは、位置情報取得に成功した時に実行される関数のオブジェクトを指定します。第一引数は必須です。
第二引数 errorCallback
これは、位置情報取得に失敗した時に実行される関数オブジェクトを指定します。
第三引数 options
これは、位置情報取得に関する各種パラメータを格納した JavaScript オブジェクトを指定します。

 第一引数は必須となっていますが、第二、第三引数は省略が可能です。「 クイック・スタート 」では、第二、第三引数を省略して作っています。

 上記の例では、後述のスクリプトを書きやすくするために改行して引数を縦に並べていますが、もちろん横に並べて記述することもできます。用途に応じて使い分けてください。

getCurrentPosition() メソッド


navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);

 横に長くなりますし、階層構造が見づらくなったりもしますが、「 クイック・スタート 」では第一引数のみしか使わなかったので、(実質1つですが)横に並べる記述方法を使っています。

位置情報の取得に成功した時の処理

 位置情報の取得に成功できたら、getCurrentPosition()メソッドの第一引数に指定した関数が実行されます。

位置情報取得に成功した時の処理


// 現在位置情報を取得
navigator.geolocation.getCurrentPosition(successCallback);

// 位置情報取得完了時の処理
function successCallback(position) {
	// ここに処理を記述
	:
	:
}

 ここの例では、第二、第三引数を省略して書いています。

 位置情報の取得に成功すると、コールバック関数に Positionというオブジェクトが渡されます。 位置情報の取得に成功した場合のコールバック関数内では、Positionオブジェクトの coords属性から緯度・経度・高度などの様々な値を取得します

position.coords.latitude
緯度を10進の数値(-180〜180)で返します。単位は「度」です。
position.coords.longitude
経度を10進の数値(-90〜90)で返します。単位は「度」です。
position.coords.accuracy
緯度と経度の精度のレベル(誤差)を数値で返します。単位はメートル(m)です。もしこの値が取得できなかった場合は null を返します。
position.coords.altitude
GPS高度を数値で返します。単位は、WGS84楕円体上のメートル(m)です。もしこの値が取得できなかった場合は null を返します。
position.coords.altitudeAccuracy
GPS高度の精度のレベル(誤差)を数値で返します。単位はメートル(m)です。もしこの値が取得できなかった場合は null を返します。
position.coords.heading
進行方向を 0 以上 360 未満の数値で返します。この値は角度を表し、単位は度(°)です。真北を 0° として、時計回り(右回り)に数えます。従って東は 90°、南は 180°、西は 270° になります。ただし、この値が取得できるのは移動中のみです。移動せずに静止しているとき、つまり、position.coords.speed が 0 のときは、NaN を返します。また、この値が取得できなかった場合は null を返します。
position.coords.speed
移動速度を数値で返します。単位はメートル/秒です。この値が取得できなかった場合は null を返します。
position.timestamp
位置情報が取得できたときのタイムスタンプを表す Date オブジェクトを返します。

 位置情報を取得できた場合、つまり、コールバック関数が呼び出された場合は、緯度を表す latitudeプロパティ、経度を表すlongitude プロパティ、そして、その精度を表す accuracyプロパティが必ずセットされています。

 「 クイック・スタート 」のサンプルに手を加えて、この各種プロパティの値を表示するサンプルを作ってみました。

>> サンプルページを表示する

HTML source


<dl>
	<dt>緯度</dt>
	<dd id="resultLatitude">-</dd>

	<dt>経度</dt>
	<dd id="resultLongitude">-</dd>

	<dt>緯度・経度の精度</dt>
	<dd id="resultAccuracy">-</dd>

	<dt>GPS 高度</dt>
	<dd id="resultAltitude">-</dd>

	<dt>GPS 高度の精度</dt>
	<dd id="resultAltitudeAccuracy">-</dd>

	<dt>移動方向</dt>
	<dd id="resultHeading">-</dd>

	<dt>移動速度</dt>
	<dd id="resultSpeed">-</dd>

	<dt>タイムスタンプ</dt>
	<dd id="resultTimestamp">-</dd>
</dl>

>> サンプルページを表示する

JavaScript source


// 現在位置情報を取得
navigator.geolocation.getCurrentPosition(successCallback);

// 位置情報取得完了時の処理
function successCallback(position) {
	// 緯度
	const gllatitude = position.coords.latitude;
	document.getElementById("resultLatitude").innerHTML = gllatitude;
	// 経度
	const gllongitude = position.coords.longitude;
	document.getElementById("resultLongitude").innerHTML = gllongitude;
	// 緯度・経度の精度
	const glaccuracy = position.coords.accuracy;
	document.getElementById("resultAccuracy").innerHTML = glaccuracy;
	// GPS 高度
	const glaltitude = position.coords.altitude;
	document.getElementById("resultAltitude").innerHTML = glaltitude;
	// GPS 高度の精度
	const glaltitudeAccuracy = position.coords.altitudeAccuracy;
	document.getElementById("resultAltitudeAccuracy").innerHTML = glaltitudeAccuracy;
	// 移動方向
	const glheading = position.coords.heading;
	document.getElementById("resultHeading").innerHTML = glheading;
	// 移動速度
	const glspeed = position.coords.speed;
	document.getElementById("resultSpeed").innerHTML = glspeed;
	// タイムスタンプ
	const gltimestamp =  position.timestamp;
	if( typeof(gltimestamp) == "number" ) {
		gltimestamp = new Date(gltimestamp);
	}
	document.getElementById("resultTimestamp").innerHTML = gltimestamp;
}

>> サンプルページを表示する

>> サンプルページを表示する

 このスクリプトでは、タイムスタンプの扱いに注意してください。Geolocation API仕様では、position.timestampプロパティは JavaScriptの Dateオブジェクトを返すことになっています。ところが、ブラウザによっては Dateオブジェクトから getTime()メソッドを呼び出したときに得られる数値(1970年1月1日午前0時GMTから経過ミリ秒)を返します。そのため、ここでは、その値が数値であれば、Dateオブジェクトに変換しています。もし、position.timestampプロパティからタイムスタンプを得たい場合は、注意が必要なようです。

 なお、先ほどのサンプルの結果では、移動方向、移動速度を計測することはできませんでした。これらの計測値は、1回だけ位置情報を取得する getCurrentPosition()メソッドでは取得することができません。watchPosition()メソッドを使って移動しながらリアルタイムに位置情報を監視すれば、これらの値を取得することができます。

位置情報取得に失敗した時の処理

 位置情報は、必ずしも取得できるとは限りません。もし位置情報が取得できなかった場合は、getCurrentPosition() メソッドに第二引数に指定した関数を実行することができます。

 「 クイック・スタート 」で使った「 位置情報を取り出すサンプル 」を改良して、位置情報取得のエラー・ハンドリングを加えてみます。

サンプルの表示

JavaScript source


document.addEventListener("DOMContentLoaded", function() {
	// 現在位置情報を取得
	window.navigator.geolocation.getCurrentPosition(
		show_location,  // 位置情報取得完了時に実行されるコールバック
		show_error      // 位置情報取得失敗時に実行されるコールバック
	);
}, false);

// 位置情報取得完了時の処理
function show_location(event) { ... }

// 位置情報取得失敗時の処理
function show_error(event) {
	alert(event.message + "(" + event.code + ")");
}

サンプルの表示

 このスクリプトでは、getCurrentPosition() メソッドの第二引数に、エラー時に実行させる show_error() 関数のオブジェクトを指定しています。show_error() メソッドでは、エラーの内容をアラート表示します。

エラー表示の例

Firefox でのエラー表示例
Firefoxのエラー表示
Google Chrome でのエラー表示例
Google Chromeのエラー表示

 エラーの内容は、イベント・オブジェクトから取得することができます。

エラーの内容を取得するためのプロパティ

event.code
現在のエラー状況を表すコード番号を返します。番号の意味は下記の通りです。
1 : 位置情報取得の許可が得られなかった。(PERMISSION_DENIED)
2 : 位置情報の取得に失敗した。(POSITION_UNAVAILABLE)
3 : タイムアウトが発生した。(TIMEOUT)
event.message
エラーを表すメッセージをテキストで返します。
event.PERMISSION_DENIED
常に 1 を返す定数です。
event.POSITION_UNAVAILABLE
常に 2 を返す定数です。
event.TIMEOUT
常に 3 を返す定数です。

 もしエラーが発生していれば、イベント・オブジェクトの code プロパティから、エラーの種類を表す 1~3 の数値を得ることができます。

 それぞれのエラーには数値だけではなく PERMISSION_DENIEDPOSITION_UNAVAILABLE といった名前が規定されています。そして、その名前と同じプロパティが規定されており、そのプロパティは常にエラーを表す数値を返します。

数値を使った場合の code プロパティの利用例


function show_error(event) {
	if( event.code == 2 ) { ... }
	...
}

名前を使った場合の code プロパティの利用例


function show_error(event) {
	if( event.code == POSITION_UNAVAILABLE ) { ... }
	...
}

 いずれの表記も結果は同じです。後者の方がコードが理解しやすいといえるでしょう。これについてはお好みに合わせて使い分けてください。

オプション・パラメータ

 getCurrentPosition() メソッドの第三引数を使うと、位置情報取得に関するパラメータを事前に定義することができます。

位置情報取得に関するパラメータを事前に定義するためのプロパティ

PositionOptions.enableHighAccuracy
true をセットすると、ブラウザに対して高精度な位置情報を要求します。このパラメータの指定がなければ false が適用されます。
PositionOptions.timeout
位置情報を取得するまでに許す時間をミリ秒で指定します。もし負の数値が指定された場合は、0 が指定されたと見なされます。
PositionOptions.maximumAge
キャッシュされた位置情報の有効時間をミリ秒で指定します。指定がなければ 0 がセットされたと見なされます。

 このオプション・パラメータを表すオブジェクトは、通常の JavaScript オブジェクトとして、自分で用意します。

オプション・パラメータを表すオブジェクトを用意する


document.addEventListener("DOMContentLoaded", function() {
	// オプション・パラメータをセット
	var position_options = {
		enableHighAccuracy: true,  // 高精度を要求する
		timeout: 60000,            // 最大待ち時間(ミリ秒)
		maximumAge: 0              // キャッシュ有効期間(ミリ秒)
	};
	// 現在位置情報を取得
	window.navigator.geolocation.getCurrentPosition(
		show_location,    // 位置情報取得完了時に実行されるコールバック
		show_error,       // 位置情報取得失敗時に実行されるコールバック
		position_options  // オプション・パラメータ
	);
}, false);

 では、個々のパラメータを見ていきましょう。

位置情報の精度を上げる

 enableHighAccuracy プロパティに true がセットされると、ブラウザは、出来る限り詳細な位置情報を得ようと、あらゆる手段を尽くします。そして、待つことで詳細な位置情報が得られるなら、出来る限り待ちます。そのため、true をセットした場合は、位置情報の取得に時間がかかる場合があります。特に、GPS を搭載したデバイスでは、この違いが顕著に表れます。また、得られる位置情報も、精度が増します。

enableHighAccuracy プロパティに true をセットし、位置情報の精度を上げた場合→サンプルの表示

enableHighAccuracy プロパティに false をセットし、位置情報の精度を上げないようにした場合→サンプルの表示

 この図は、iPhone を使って、enableHighAccuracy プロパティに true をセットした場合と、false をセットした場合を比較したものです。ご覧の通り、緯度・経度の精度が大幅に違うのがわかります。

 true をセットした時は、緯度・経度の精度は 10メートル程度の誤差の可能性を示唆しています。ところが、false をセットした時は、1.4キロ以上の誤差の可能性を示唆しています。

 ただし、enableHighAccuracy プロパティに true をセットすると、GPS を搭載したスマート・フォンでは、それだけ電力も消費することになります。詳細な位置情報を必要としないにもかかわらず、意味もなく enableHighAccuracy プロパティに true をセットすることは避けた方が良いでしょう。

タイムアウトをセットする

 timeout プロパティにミリ秒をセットすると、位置情報取得に費やす時間を制限することができます。もし指定時間内に位置情報が取得できなければ、getCurrentPosition() メソッドの第二引数に指定した関数に引き渡されるイベント・オブジェクトの code プロパティに 3(TIMEOUT) がセットされることになります。

 timeout プロパティに 0 をセットすると、必ずエラーになります。

タイムアウト時のエラー表示例
Google Chromeのエラー表示

サンプルの表示

Script


document.addEventListener("DOMContentLoaded", function() {
	// オプション・パラメータをセット
	var position_options = {
		enableHighAccuracy: false,   // 高精度を要求しない
		timeout: 0                   // 最大待ち時間(ミリ秒)
	};
	// 現在位置情報を取得
	window.navigator.geolocation.getCurrentPosition(
		show_location,    // 位置情報取得完了時に実行されるコールバック
		show_error,       // 位置情報取得失敗時に実行されるコールバック
		position_options  // オプション・パラメータ
	);
}, false);

// 位置情報取得完了時の処理
function show_location(event) { ... }

// 位置情報取得失敗時の処理
function show_error(event) {
	alert( event.message + "(" + event.code + ")" );
}

サンプルの表示

 この位置情報を取得するまでに許す時間とは、実際に位置情報の取得に費やす時間を表します。ユーザーに対して Geolocation API 利用許可を求めるダイアログを表示して待機している間は対象外となりますので注意してください。

キャッシュ有効期間をセットする

 maximumAge プロパティにミリ秒をセットすると、キャッシュ有効期間を指定することができます。通常、Geolocation API で取得した位置情報は、すぐには破棄されず、キャッシュとして保存されます。もし maximumAge プロパティにミリ秒がセットされていれば、指定した期間内に保存されたキャッシュを使い、位置情報を返します。

 場合によっては、何度も繰り返し位置情報を取得することが考えられますが、Geolocation API の用途によっては、必ずしも最新である必要はないこともあります。そういったシーンでは、レスポンスを早めるために、キャッシュを有効にしておきます。

 maximumAge プロパティをセットしたとしても、指定時間内に保存された位置情報キャッシュが存在していなければ、新たに位置情報を調べることになります。

 もしキャッシュを一切使わず、常に最新の位置情報が必要な場合は、このプロパティを指定しないか、または、このプロパティに 0 を指定してください。


document.addEventListener("DOMContentLoaded", function() {
	// オプション・パラメータをセット
	var position_options = {
		enableHighAccuracy: true,  // 高精度を要求する
		timeout: 60000,            // 最大待ち時間(ミリ秒)
		maximumAge: 0              // キャッシュ有効期間(ミリ秒)
	};
	// 現在位置情報を取得
	window.navigator.geolocation.getCurrentPosition(
		show_location,    // 位置情報取得完了時に実行されるコールバック
		show_error,       // 位置情報取得失敗時に実行されるコールバック
		position_options  // オプション・パラメータ
	);
}, false);

【Next】位置情報を連続して取得する