JavaScriptで位置情報を取得する方法(Geolocation API)

JavaScriptで位置情報を取得する方法(Geolocation API)

スマホ全盛期の現在、位置情報を利用したwebサービスは珍しくなく、むしろ、どのwebサービスも位置情報を当たり前のように活用しています。webサービスを作成するにあたって、ユーザーの現在位置を取得する方法は必須の知識といってもいいんじゃないでしょうか。今回はJavaScriptを利用した取得方法を解説します。

サンプルデモ

ユーザーの現在位置を取得
ユーザーの現在位置を取得

現在位置を取得するサンプルデモを見るには、下記ページにアクセスして下さい。このブログがあなたの位置情報を取得してもいいか、という確認が表示されるので、許可すると、あなたの現在位置(緯度、経度の座標)の取得を開始、表示します。

サンプルデモを見る

端末が対応しているかを判定

現在位置を取得するには、ユーザーのブラウザが、Geolocation APIという機能に対応している必要があります。Geolocation APIとは、簡単に言うと、端末の位置情報をやり取りするシステムです。GPSに対応しているスマホだけでなく、現在位置を設定できるデスクトップPCでも利用可能です。

判別方法は簡単です。Geolocation APIに対応している端末の場合、navigator.geolocationというオブジェクトが最初から存在するので、これの有無で判別すればいいだけです。

JavaScript

// Geolocation APIに対応している
if( navigator.geolocation )
{
	// 現在位置を取得できる場合の処理
	alert( "あなたの端末では、現在位置を取得することができます。" ) ;
}

// Geolocation APIに対応していない
else
{
	// 現在位置を取得できない場合の処理
	alert( "あなたの端末では、現在位置を取得できません。" ) ;
}

現在位置の取得 [getCurrentPosition()]

位置情報を取得するメソッド

ブラウザがGeolocation APIに対応していることが分かったら、続いて、現在位置を取得してみましょう。navigator.geolocation.getCurrentPositionに対して、getCurrentPosition()というメソッドを利用します。

JavaScript

// 現在位置を取得する
navigator.geolocation.getCurrentPosition( successFunc , errorFunc , optionObj ) ;

メソッドの引数

このメソッドには、3つの引数を指定することができます。

引数説明
successFunc現在位置が取得できた時に実行する関数名、もしくは、関数の内容を指定します。必ず指定する必要があります。
errorFunc現在位置の取得に失敗した時に実行する関数名、もしくは、関数の内容を指定します。省略可能です。
optionObj現在位置の取得に関するオプションを、オブジェクト形式で指定します。省略可能です。

オプションの指定

第3引数のオプションを指定する場合、オブジェクトの内容に、下記のプロパティを指定することができます。

引数説明
enableHighAccuracyBoolean値を指定します。trueを指定すると、より精度の高い情報を取得するように試みます。
timeout秒数をミリ単位で指定します。現在位置の取得に、この秒数以上、かかった場合、タイムアウト・エラー扱いになります。
maximumAge秒数をミリ単位で指定します。次回、再び現在位置を取得する時に、ここで指定した秒数だけ、今回のデータをキャッシュしておきます。

取得できる値

現在位置の取得に成功すると、第1引数で指定した関数に、下記内容のオブジェクト・データが渡されます。ブラウザの機能で取得できなかった値はnullとなります。ここでは、speedなどイメージが掴めないデータが存在すると思いますが、次章で明快になります。

引数説明
coords.latitude現在位置の緯度。-180180で表す。
coords.longitude現在位置の経度。-9090で表す。
coords.altitude現在位置の高度。メートル単位で表す。
coords.accuracy取得した緯度、経度の精度。メートル単位で表す。
coords.altitudeAccuracy取得した高度の精度。メートル単位で表す。
coords.heading方角。0360の角度で表す。0が北、90が東、180が南、270が西。
coords.speed速度。メートル / 秒数で表す。

エラー番号

現在位置の取得に失敗すると、第2引数で指定した関数に、下記内容のエラー番号が渡されます。エラー番号はcodeプロパティの中にあります。

引数説明
0原因不明のエラーで、現在位置を取得できなかった。
1ユーザーが、ウェブサイトに対して、位置情報の使用を許可しなかった。
2電波状況が悪いなどの理由で、現在位置を取得できなかった。
3位置情報の取得に時間がかかりすぎ、タイムアウト・エラーになった。

[getCurrentPosition()]の使い方

仕様を一通り説明してきました。それでは、このメソッドの使い方を紹介します。まずは、成功した時の関数を作っておきましょう。関数名はsuccessFuncとします。関数には、位置情報を含んだオブジェクト・データが引数で渡されるので、それをpositionという変数で受け取るようにしましょう。

JavaScript

// 成功した時の関数
function successFunc( position )
{
	// 緯度をアラート表示
	alert( position.coords.latitude ) ;

	// 経度をアラート表示
	alert( position.coords.longitude ) ;
}

続いて、位置情報取得に失敗した場合の関数を用意します。関数名はerrorFuncとします。こちらにも、エラーコードを含んだデータが引数として渡されるので、errorという変数で受け取るようにしましょう。

JavaScript

// 失敗した時の関数
function errorFunc( error )
{
	// エラーコードのメッセージを定義
	var errorMessage = {
		0: "原因不明のエラーが発生しました…。" ,
		1: "位置情報の取得が許可されませんでした…。" ,
		2: "電波状況などで位置情報が取得できませんでした…。" ,
		3: "位置情報の取得に時間がかかり過ぎてタイムアウトしました…。" ,
	} ;

	// エラーコードに合わせたエラー内容をアラート表示
	alert( errorMessage[error.code] ) ;
}

最後に第3引数のオプション・オブジェクトも作っておきましょう。optionObjという変数に代入しておきます。

JavaScript

// オプション・オブジェクト
var optionObj = {
	"enableHighAccuracy": false ,
	"timeout": 8000 ,
	"maximumAge": 5000 ,
} ;

引数が一通り用意できたら、最後に、メソッドを実行しましょう。これを実行すると、まずブラウザがユーザーに、「位置情報を送信してもいいか?」という確認をして、ユーザーが許可すると、位置情報の取得が開始されます。

JavaScript

// 現在位置を取得する
navigator.geolocation.getCurrentPosition( successFunc , errorFunc , optionObj ) ;

サンプルプログラム

この章を踏まえて作成したサンプルプログラムを紹介します。実行結果を見たい人は、デモページにアクセスして下さい。

JavaScript

// ユーザーの端末がGeoLocation APIに対応しているかの判定

// 対応している場合
if( navigator.geolocation )
{
	// 現在地を取得
	navigator.geolocation.getCurrentPosition(

		// [第1引数] 取得に成功した場合の関数
		function( position )
		{
			// 取得したデータの整理
			var data = position.coords ;

			// データの整理
			var lat = data.latitude ;
			var lng = data.longitude ;
			var alt = data.altitude ;
			var accLatlng = data.accuracy ;
			var accAlt = data.altitudeAccuracy ;
			var heading = data.heading ;			//0=北,90=東,180=南,270=西
			var speed = data.speed ;

			// アラート表示
//			alert( "あなたの現在位置は、\n[" + lat + "," + lng + "]\nです。" ) ;

			// HTMLへの書き出し
			document.getElementById( 'result' ).innerHTML = '<dl><dt>緯度</dt><dd>' + lat + '</dd><dt>経度</dt><dd>' + lng + '</dd><dt>高度</dt><dd>' + alt + '</dd><dt>緯度、経度の精度</dt><dd>' + accLatlng + '</dd><dt>高度の精度</dt><dd>' + accAlt + '</dd><dt>方角</dt><dd>' + heading + '</dd><dt>速度</dt><dd>' + speed + '</dd></dl>' ;

			// 位置情報
			var latlng = new google.maps.LatLng( lat , lng ) ;

			// Google Mapsに書き出し
			var map = new google.maps.Map( document.getElementById( 'map-canvas' ) , {
				zoom: 15 ,				// ズーム値
				center: latlng ,		// 中心座標 [latlng]
			} ) ;

			// マーカーの新規出力
			new google.maps.Marker( {
				map: map ,
				position: latlng ,
			} ) ;
		},

		// [第2引数] 取得に失敗した場合の関数
		function( error )
		{
			// エラーコード(error.code)の番号
			// 0:UNKNOWN_ERROR				原因不明のエラー
			// 1:PERMISSION_DENIED			利用者が位置情報の取得を許可しなかった
			// 2:POSITION_UNAVAILABLE		電波状況などで位置情報が取得できなかった
			// 3:TIMEOUT					位置情報の取得に時間がかかり過ぎた…

			// エラー番号に対応したメッセージ
			var errorInfo = [
				"原因不明のエラーが発生しました…。" ,
				"位置情報の取得が許可されませんでした…。" ,
				"電波状況などで位置情報が取得できませんでした…。" ,
				"位置情報の取得に時間がかかり過ぎてタイムアウトしました…。"
			] ;

			// エラー番号
			var errorNo = error.code ;

			// エラーメッセージ
			var errorMessage = "[エラー番号: " + errorNo + "]\n" + errorInfo[ errorNo ] ;

			// アラート表示
			alert( errorMessage ) ;

			// HTMLに書き出し
			document.getElementById("result").innerHTML = errorMessage;
		} ,

		// [第3引数] オプション
		{
			"enableHighAccuracy": false,
			"timeout": 8000,
			"maximumAge": 2000,
		}

	) ;
}

// 対応していない場合
else
{
	// エラーメッセージ
	var errorMessage = "お使いの端末は、GeoLacation APIに対応していません。" ;

	// アラート表示
	alert( errorMessage ) ;

	// HTMLに書き出し
	document.getElementById( 'result' ).innerHTML = errorMessage ;
}

このコードの動作を確認する

現在位置の追跡 [watchPosition()]

位置情報の追跡とは?

前章で紹介したgetCurrentPosition()は、1度だけ、位置情報を取得するメソッドです。この章で紹介するwatchPosition()は、それに対して、ユーザーの位置情報を常に追跡するメソッドです。どういうことか説明していきます。

watchPosition()は、指定する引数、取得できる値など、getCurrentPosition()と使い方、仕様がほぼ一緒です。一点だけ違うのは、watchPosition()が、繰り返し、処理を実行することです。現在位置を繰り返し取得し、その度に、第1引数に指定した「位置情報の取得に成功した場合の関数」を実行します。それにより、前回の値と比較して、coords.speedの値が求められます。

[watchPosition()]の使い方

watchPosition()getCurrentPosition()の使い方はほぼ一緒なので、仕様は前章をご参考下さい。このメソッドの特徴は、メソッドの実行時に、IDを作成しておくことです。具体的には、下記の通りです。

JavaScript

// 位置情報の追跡を開始する
// watchIdというIDを付けておく
var watchId = navigator.geolocation.watchPosition( successFunc , errorFunc , optionObj ) ;

何故、IDを付けておくかというと、追跡を止める処理に必要だからです。このwatchPosition()は、繰り返し、処理を実行するメソッドです。ブラウザに負担をかけないためにも、必要な分の処理が済んだら、追跡を中止させるのが望ましいですね。中止させる方法は簡単で、追跡を開始する時に付けたIDを引数にして、clearWatch()というメソッドを実行して下さい。

JavaScript

// 位置情報の追跡を中止する
navigator.geolocation.clearWatch( watchId ) ;

サンプルプログラム

位置情報を追跡するサンプルプログラムは下記の通りです。どのように動作するか確認したい人は、デモページをご覧下さい。

JavaScript

// グローバル変数
var syncerWatchPosition = {
	count: 0 ,
	lastTime: 0 ,
	map: null ,
	marker: null ,
} ;

// 成功した時の関数
function successFunc( position )
{
	// データの更新
	++syncerWatchPosition.count ;					// 処理回数
	var nowTime = ~~( new Date() / 1000 ) ;	// UNIX Timestamp

	// 前回の書き出しから3秒以上経過していたら描写
	// 毎回HTMLに書き出していると、ブラウザがフリーズするため
	if( (syncerWatchPosition.lastTime + 3) > nowTime )
	{
		return false ;
	}

	// 前回の時間を更新
	syncerWatchPosition.lastTime = nowTime ;

	// HTMLに書き出し
	document.getElementById( 'result' ).innerHTML = '<dt>緯度</dt><dd>' + position.coords.latitude + '</dd><dt>経度</dt><dd>' + position.coords.longitude + '</dd><dt>高度</dt><dd>' + position.coords.altitude + '</dd><dt>速度</dt><dd>' + position.coords.speed + '</dd><dt>実行回数</dt><dd>' + syncerWatchPosition.count + '回</dd>' ;

	// 位置情報
	var latlng = new google.maps.LatLng( position.coords.latitude , position.coords.longitude ) ;

	// Google Mapsに書き出し
	if( syncerWatchPosition.map == null )
	{
		// 地図の新規出力
		syncerWatchPosition.map = new google.maps.Map( document.getElementById( 'map-canvas' ) , {
			zoom: 15 ,				// ズーム値
			center: latlng ,		// 中心座標 [latlng]
		} ) ;

		// マーカーの新規出力
		syncerWatchPosition.marker = new google.maps.Marker( {
			map: syncerWatchPosition.map ,
			position: latlng ,
		} ) ;
	}
	else
	{
		// 地図の中心を変更
		syncerWatchPosition.map.setCenter( latlng ) ;

		// マーカーの場所を変更
		syncerWatchPosition.marker.setPosition( latlng ) ;
	}
}

// 失敗した時の関数
function errorFunc( error )
{
	// エラーコードのメッセージを定義
	var errorMessage = {
		0: "原因不明のエラーが発生しました…。" ,
		1: "位置情報の取得が許可されませんでした…。" ,
		2: "電波状況などで位置情報が取得できませんでした…。" ,
		3: "位置情報の取得に時間がかかり過ぎてタイムアウトしました…。" ,
	} ;

	// エラーコードに合わせたエラー内容を表示
	alert( errorMessage[error.code] ) ;
}

// オプション・オブジェクト
var optionObj = {
	"enableHighAccuracy": false ,
	"timeout": 1000000 ,
	"maximumAge": 0 ,
} ;

// 現在位置を取得する
navigator.geolocation.watchPosition( successFunc , errorFunc , optionObj ) ;

このコードの動作を確認する

ダウンロード

この記事で紹介したgetCurrentPosition()watchPosition()のサンプルデモ・ファイルを配布します。よろしければ、位置情報取得の動作確認用にご利用下さい。

ファイル一覧

SYNCER00074
get-current-position.html Download
get-current-position.js Download
watch-position.html Download
watch-position.js Download
geolocation-api.css Download

ファイル名をクリックすると内容を確認できます。「Download Zip」をクリックするとファイル一式をダウンロードできます。

Download Zip