Javascriptで位置情報を取得する方法(Geo Location API)
スマホ全盛期の現在、位置情報を利用したwebサービスは珍しくなく、むしろ、どのwebサービスも位置情報を当たり前のように活用しています。webサービスを作成するにあたって、ユーザーの現在位置を取得する方法は必須の知識といってもいいんじゃないでしょうか。今回はJavascriptを利用した取得方法を解説します。
サンプルデモ
現在位置を取得するサンプルデモを見るには、下記ページにアクセスして下さい。このブログがあなたの位置情報を取得してもいいか、という確認が表示されるので、許可すると、あなたの現在位置(緯度、経度の座標)の取得を開始、表示します。
端末が対応しているかを判定
現在位置を取得するには、ユーザーのブラウザが、GeoLocation APIという機能に対応している必要があります。GeoLocation APIとは、簡単に言うと、端末の位置情報をやり取りするシステムです。GPSに対応しているスマホだけでなく、現在位置を設定できるデスクトップPCでも利用可能です。
判別方法は簡単です。GeoLocation APIに対応している端末の場合、navigator.geolocationというオブジェクトが最初から存在するので、これの有無で判別すればいいだけです。
GeoLocation APIに対応しているかを判別する
//GeoLocation APIに対応している
if(navigator.geolocation){
//現在位置を取得できる場合の処理
alert("あなたの端末では、現在位置を取得することができます。");
//GeoLocation APIに対応していない
}else{
//現在位置を取得できない場合の処理
alert("あなたの端末では、現在位置を取得できません。");
}現在位置の取得 [getCurrentPosition()]
位置情報を取得するメソッド
ブラウザがGeoLocation APIに対応していることが分かったら、続いて、現在位置を取得してみましょう。navigator.geolocation.getCurrentPositionに対して、getCurrentPosition()というメソッドを利用します。
GeoLocation APIに対応しているかを判別する
//現在位置を取得する
navigator.geolocation.getCurrentPosition(successFunc,errorFunc,optionObj);メソッドの引数
このメソッドには、3つの引数を指定することができます。
getCurrentPosition()の引数
- successFunc
- 現在位置が取得できた時に実行する関数名、もしくは、関数の内容を指定します。必ず指定する必要があります。
- errorFunc
- 現在位置の取得に失敗した時に実行する関数名、もしくは、関数の内容を指定します。省略可能です。
- optionObj
- 現在位置の取得に関するオプションを、オブジェクト形式で指定します。省略可能です。
オプションの指定
第3引数のオプションを指定する場合、オブジェクトの内容に、下記のプロパティを指定することができます。
オプションのプロパティ
- enableHighAccuracy
- Boolean値を指定します。
trueを指定すると、より精度の高い情報を取得するように試みます。 - timeout
- 秒数をミリ単位で指定します。現在位置の取得に、この秒数以上、かかった場合、タイムアウト・エラー扱いになります。
- maximumAge
- 秒数をミリ単位で指定します。次回、再び現在位置を取得する時に、ここで指定した秒数だけ、今回のデータをキャッシュしておきます。
取得できる値
現在位置の取得に成功すると、第1引数で指定した関数に、下記内容のオブジェクト・データが渡されます。ブラウザの機能で取得できなかった値はnullとなります。ここでは、speedなどイメージが掴めないデータが存在すると思いますが、次章で明快になります。
オプションのプロパティ
- coords.latitude
- 現在位置の緯度。
-180〜180で表す。 - coords.longitude
- 現在位置の経度。
-90〜90で表す。 - coords.altitude
- 現在位置の高度。メートル単位で表す。
- coords.accuracy
- 取得した緯度、経度の精度。メートル単位で表す。
- coords.altitudeAccuracy
- 取得した高度の精度。メートル単位で表す。
- coords.heading
- 方角。
0〜360の角度で表す。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);サンプルデモ
この章で紹介したサンプルの実行結果を見たい人は、下記ページにアクセスして下さい。
現在位置の追跡 [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);サンプルデモ
watchPosition()メソッドを利用して、現在位置情報を追跡するサンプルデモです。スマホ端末で、軽く移動しながら、実行タイミングなどを確認してみて下さい。デスクトップPCだと実感できないかもしれません。
ダウンロード
この記事で紹介したgetCurrentPosition()、watchPosition()のサンプルデモ・ファイルに加えて、一通りの処理方法を記述したindex.htmlとgeo.location.api.sample.jsを配布します。よろしければ、位置情報取得の確認用にご利用下さい。
ファイル構成
ファイルの内容
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<meta name="robots" content="noindex,nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>GeoLocation APIを利用して現在位置を取得するデモ</title>
<!-- プログラムの実行 -->
<script src="./geo.location.api.sample.js"></script>
</head>
<body>
<h1>GeoLocation APIを利用して現在位置を取得するデモ</h1>
<p>お使いの端末の、位置情報を取得してアラート表示、HTML表示します。</p>
<p>(解説:<a href="http://syncer.jp/how-to-use-geolocation-api" target="_blank" rel="nofollow">Syncer</a>)</p>
<h2>実行結果</h2>
<p id="result">結果が出るまで、少々お待ち下さい…。</p>
</body>
</html>geo.location.api.sample.js
window.onload = function(){
//ユーザーの端末が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>";
},
//[第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;
}
}getcurrentposition.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<meta name="robots" content="noindex,nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>getCurrentPosition()のサンプルデモ</title>
<!-- プログラムの実行 -->
<script>
//成功した時の関数
function successFunc(position){
//緯度をアラート表示
alert(position.coords.latitude);
//経度をアラート表示
alert(position.coords.longitude);
}
//失敗した時の関数
function errorFunc(error){
//エラーコードのメッセージを定義
var errorMessage = {
0: "原因不明のエラーが発生しました…。",
1: "位置情報の取得が許可されませんでした…。",
2: "電波状況などで位置情報が取得できませんでした…。",
3: "位置情報の取得に時間がかかり過ぎてタイムアウトしました…。",
};
//エラーコードに合わせたエラー内容を表示
alert(errorMessage[error.code]);
}
//オプション・オブジェクト
var optionObj = {
"enableHighAccuracy": false,
"timeout": 8000,
"maximumAge": 5000,
};
//現在位置を取得する
navigator.geolocation.getCurrentPosition(successFunc,errorFunc,optionObj);
</script>
</head>
<body>
<h1>getCurrentPosition()のサンプルデモ</h1>
<p>お使いの端末の、位置情報を取得して、緯度と経度をアラート表示します。初回のアクセスの場合、位置情報の取得を許可して下さい。</p>
<p>(解説:<a href="http://syncer.jp/how-to-use-geolocation-api" target="_blank" rel="nofollow">Syncer</a>)</p>
</body>
</html>watchposition.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<meta name="robots" content="noindex,nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>watchPosition()のサンプルデモ</title>
<!-- プログラムの実行 -->
<script>
//グローバル変数
var i = 0;
//成功した時の関数
function successFunc(position){
//緯度をHTMLに書き出し
document.getElementById("lat").innerHTML = position.coords.latitude;
//経度をHTMLに書き出し
document.getElementById("lng").innerHTML = position.coords.longitude;
//高度をHTMLに書き出し
document.getElementById("alt").innerHTML = position.coords.altitude;
//速度をHTMLに書き出し
document.getElementById("speed").innerHTML = position.coords.speed;
//処理回数を書き出し
document.getElementById("count").innerHTML = ++i;
}
//失敗した時の関数
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);
</script>
</head>
<body>
<h1>watchPosition()のサンプルデモ</h1>
<p>お使いの端末の、位置情報を追跡して、HTML上に最新の結果を書き出し続けます。スマホなどの端末で、移動しながらこの画面を確認してみて下さい。リアルタイムで数値が更新されていきます。初回アクセスの場合、位置情報の利用を許可して下さい。</p>
<p>(解説:<a href="http://syncer.jp/how-to-use-geolocation-api" target="_blank" rel="nofollow">Syncer</a>)</p>
<h2>取得したデータ</h2>
<dl>
<dt>緯度</dt>
<dd id="lat"></dd>
<dt>経度</dt>
<dd id="lng"></dd>
<dt>高度</dt>
<dd id="alt"></dd>
<dt>速度</dt>
<dd id="speed"></dd>
<dt>実行回数</dt>
<dd><span id="count">0</span>回</dd>
</dl>
</body>
</html>