Geolocation API は「ブラウザに“今どこにいるか”を教えてもらう窓口」
まずイメージからいきます。
Geolocation API は、
ブラウザに対して「このユーザーが今どこにいるか教えて」とお願いするための仕組みです。
スマホなら GPS や Wi‑Fi、基地局情報
PC なら Wi‑Fi や IP アドレス
など、デバイスが持っている情報をブラウザがうまく組み合わせて、
「だいたいこのあたりにいるよ」という位置を返してくれます。
ただし、位置情報はかなりセンシティブな情報なので、
ユーザーの明示的な許可が必須
基本的に HTTPS(安全なコンテキスト)でしか動かない
という強めの制限がかかっています。
この「許可」と「HTTPS」をちゃんと意識できるかどうかが、
Geolocation API を扱ううえでの最初の関門です。
まずは「今の位置を 1 回だけ取得する」getCurrentPosition
一番シンプルな使い方の全体像
現在地を 1 回だけ知りたいときに使うのがnavigator.geolocation.getCurrentPosition() です。
基本形はこうなります。
navigator.geolocation.getCurrentPosition(
successCallback,
errorCallback,
options
);
JavaScript第 1 引数が「成功したときに呼ばれる関数」
第 2 引数が「失敗したときに呼ばれる関数」
第 3 引数が「オプション(精度やタイムアウトなど)」です。
初心者のうちは、まず第 1・第 2 引数だけを押さえれば十分です。
実際に緯度・経度を表示してみる例
HTML:
<button id="getLocationBtn">現在地を取得</button>
<p id="result">ボタンを押すと現在地を表示します</p>
JavaScript:
const btn = document.querySelector("#getLocationBtn");
const result = document.querySelector("#result");
btn.addEventListener("click", () => {
if (!("geolocation" in navigator)) {
result.textContent = "このブラウザは位置情報に対応していません";
return;
}
result.textContent = "位置情報を取得中…";
navigator.geolocation.getCurrentPosition(
(position) => {
const coords = position.coords;
result.textContent =
`緯度: ${coords.latitude}\n` +
`経度: ${coords.longitude}\n` +
`精度: 約 ${coords.accuracy} m`;
},
(error) => {
switch (error.code) {
case error.PERMISSION_DENIED:
result.textContent = "ユーザーが位置情報の取得を拒否しました";
break;
case error.POSITION_UNAVAILABLE:
result.textContent = "位置情報を取得できませんでした";
break;
case error.TIMEOUT:
result.textContent = "位置情報の取得がタイムアウトしました";
break;
default:
result.textContent = "不明なエラーが発生しました";
}
},
{
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
}
);
});
JavaScriptここで押さえてほしいポイントを整理します。
"geolocation" in navigator で対応しているかどうかを最初にチェックしていること。
成功時の position.coords から、latitude(緯度)・longitude(経度)・accuracy(精度)などを取り出していること。
失敗時には error.code を見て、ユーザー拒否・取得不能・タイムアウトを分けてメッセージを出していること。
特に「エラーをちゃんと分けて扱う」感覚は、
位置情報系ではかなり重要です。
ユーザーが拒否するのは“普通に起こること”なので、
それを前提に UI とメッセージを設計します。
位置情報で何が取れるのかをちゃんと知っておく
coords に入っている主なプロパティ
position.coords には、緯度・経度以外にもいろいろ入っています。
代表的なものを挙げると、こんな感じです。
緯度: coords.latitude(−90〜90)
経度: coords.longitude(−180〜180)
精度: coords.accuracy(メートル単位の誤差)
高度: coords.altitude(海抜、メートル。取れないことも多い)
高度の精度: coords.altitudeAccuracy
移動方向: coords.heading(度。0〜360。取れないことも多い)
速度: coords.speed(m/s。取れないことも多い)
ここで大事なのは、「全部が必ず取れるわけではない」ということです。
PC だと高度や速度は null のことが多い
スマホでも、状況によっては精度が悪かったり一部が null だったりする
なので、実装するときは
「この値は null かもしれない」という前提で扱う
「精度(accuracy)」を見て、あまりに誤差が大きい場合は注意書きを出す
といった配慮が必要になります。
位置を“監視し続ける” watchPosition
「一度だけ」ではなく「動いたら都度教えてほしい」
getCurrentPosition は「今の位置を 1 回だけ」ですが、
ユーザーが移動するアプリ(ランニングログ、配達追跡など)では
「位置が変わるたびに教えてほしい」ことが多いです。
そのときに使うのが navigator.geolocation.watchPosition() です。
基本形はこうです。
const watchId = navigator.geolocation.watchPosition(
successCallback,
errorCallback,
options
);
// 監視をやめたいとき
navigator.geolocation.clearWatch(watchId);
JavaScriptwatchPosition は「監視を開始する」関数で、
戻り値として「監視 ID(watchId)」を返します。
この ID を clearWatch に渡すことで、
「もう位置情報の監視はやめていいよ」とブラウザに伝えられます。
実際に「現在位置を追跡して表示する」例
HTML:
<button id="startWatchBtn">追跡開始</button>
<button id="stopWatchBtn" disabled>追跡停止</button>
<pre id="log">まだ追跡していません</pre>
JavaScript:
const startWatchBtn = document.querySelector("#startWatchBtn");
const stopWatchBtn = document.querySelector("#stopWatchBtn");
const log = document.querySelector("#log");
let watchId = null;
startWatchBtn.addEventListener("click", () => {
if (!("geolocation" in navigator)) {
log.textContent = "このブラウザは位置情報に対応していません";
return;
}
if (watchId !== null) {
log.textContent = "すでに追跡中です";
return;
}
log.textContent = "位置情報の追跡を開始します…";
watchId = navigator.geolocation.watchPosition(
(position) => {
const c = position.coords;
log.textContent =
`緯度: ${c.latitude}\n` +
`経度: ${c.longitude}\n` +
`精度: 約 ${c.accuracy} m\n` +
`取得時刻: ${new Date(position.timestamp).toLocaleString()}`;
},
(error) => {
log.textContent = `エラー: ${error.message}`;
},
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
}
);
startWatchBtn.disabled = true;
stopWatchBtn.disabled = false;
});
stopWatchBtn.addEventListener("click", () => {
if (watchId !== null) {
navigator.geolocation.clearWatch(watchId);
watchId = null;
log.textContent = "追跡を停止しました";
startWatchBtn.disabled = false;
stopWatchBtn.disabled = true;
}
});
JavaScriptここでの重要ポイントは、
watchPosition は「何度も successCallback を呼ぶ」ことclearWatch(watchId) を呼ばない限り、監視が続き、バッテリーも消費し続けること
です。
モバイル端末では、位置情報の監視はバッテリーに直結します。
「いつ開始して、いつ止めるか」をきちんと設計するのが大事です。
options(enableHighAccuracy / timeout / maximumAge)を深掘りする
enableHighAccuracy: 精度とバッテリーのトレードオフ
enableHighAccuracy は、「できるだけ正確な位置が欲しいかどうか」を
ブラウザに伝えるフラグです。
true にすると、可能なら GPS などをフル活用して
より高精度な位置を返そうとしますが、そのぶん
取得に時間がかかる
バッテリー消費が増える
といったコストが上がります。
false(デフォルト)の場合は、
多少精度は落ちても、より軽く・速く位置を返そうとします。
ざっくりした使い分けのイメージはこうです。
地図アプリやナビのように「数メートル単位の精度」が欲しい → true
「だいたいこの街にいる」程度でよい店舗検索など → false
「とりあえず全部 true にしておけばいいや」ではなく、
アプリの用途に合わせてちゃんと選ぶのがプロっぽい設計です。
timeout: いつまで待つかを決める
timeout は、「位置情報が返ってくるまで最大何ミリ秒待つか」です。
指定しないと Infinity(無限に待つ)扱いになるので、
ユーザー体験的にはあまりよくありません。
例えば 5 秒でタイムアウトさせたいなら、こう書きます。
const options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
JavaScriptタイムアウトすると、エラーコールバックがerror.code === error.TIMEOUT で呼ばれます。
「電波が悪くて位置が取れない」
「屋内で GPS が入らない」
といった状況は普通に起こるので、
「一定時間待ってダメなら諦める」という設計はとても大事です。
maximumAge: キャッシュをどこまで許すか
maximumAge は、「どれくらい古い位置情報までなら再利用していいか」を
ミリ秒で指定します。
0(デフォルト)の場合は、
「毎回最新の位置を取りに行く」動きになります。
10000(10 秒)などにすると、
「10 秒以内に取得した位置があれば、それを再利用してよい」
という意味になります。
これをうまく使うと、
位置情報の取得回数を減らしてバッテリーを節約する
多少古くてもいい用途(店舗検索など)でパフォーマンスを上げる
といった調整ができます。
逆に、「ランニングの軌跡を正確に取りたい」ような用途ではmaximumAge: 0 にして、常に最新を取りに行くほうがよいです。
セキュリティ・権限・HTTPS まわりの“落とし穴”を先に知っておく
HTTPS でないと動かない(localhost は例外)
Geolocation API は「安全なコンテキスト」でしか動きません。
つまり、基本的に https:// で提供されているページでのみ有効です。
file:// で直接 HTML を開いたり、http://example.com のような非 HTTPS だと、
navigator.geolocation が undefined になる
あるいはエラーになって位置が取れない
といった状態になります。
開発中は http://localhost だけ特別に許されているので、
ローカルサーバーを立ててそこで試すのが定番です。
ユーザーの許可は“一度きり”ではない
ブラウザは、初回アクセス時に
「このサイトに位置情報の利用を許可しますか?」
というダイアログを出します。
ユーザーが「許可」を選べば以後はスムーズですが、
「ブロック」を選んだ場合は、その後の呼び出しが
常に PERMISSION_DENIED エラーになります。
この状態を変えるには、
ユーザー自身がブラウザの設定から権限を変更する必要があります。
なので、アプリ側としては
「もし拒否されていたら、ブラウザの設定から位置情報を許可してください」
といったガイドを出すのが親切です。
Geolocation API を“アプリっぽく”使う小さな例
現在地を地図に表示する(Google Maps 風の最小パターン)
ここでは、あえて外部地図サービスは使わず、
「現在地の緯度・経度を画面に出す」だけのミニマップ風 UI を作ってみます。
HTML:
<button id="locateBtn">現在地を取得</button>
<div id="status">まだ取得していません</div>
<div id="map" style="width:300px; height:300px; border:1px solid #ccc; position:relative;">
<div id="marker" style="
width:10px; height:10px; border-radius:50%;
background:red; position:absolute; left:145px; top:145px;
"></div>
</div>
<pre id="coords"></pre>
JavaScript(かなり単純化した「なんちゃってマップ」です):
const locateBtn = document.querySelector("#locateBtn");
const statusEl = document.querySelector("#status");
const coordsEl = document.querySelector("#coords");
const mapEl = document.querySelector("#map");
const markerEl = document.querySelector("#marker");
locateBtn.addEventListener("click", () => {
if (!("geolocation" in navigator)) {
statusEl.textContent = "このブラウザは位置情報に対応していません";
return;
}
statusEl.textContent = "現在地を取得中…";
navigator.geolocation.getCurrentPosition(
(position) => {
const c = position.coords;
statusEl.textContent = "現在地を取得しました";
coordsEl.textContent =
`緯度: ${c.latitude}\n` +
`経度: ${c.longitude}\n` +
`精度: 約 ${c.accuracy} m`;
const latNorm = (c.latitude + 90) / 180;
const lngNorm = (c.longitude + 180) / 360;
const x = lngNorm * mapEl.clientWidth;
const y = (1 - latNorm) * mapEl.clientHeight;
markerEl.style.left = `${x - markerEl.offsetWidth / 2}px`;
markerEl.style.top = `${y - markerEl.offsetHeight / 2}px`;
},
(error) => {
statusEl.textContent = `位置情報の取得に失敗しました: ${error.message}`;
},
{
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
}
);
});
JavaScriptこれは実用的な地図ではありませんが、
位置情報を取得する
UI に「取得中」「成功」「失敗」を表示する
取得した値を何らかの形で可視化する
という一連の流れを体験するにはちょうどいい練習です。
初心者として「Geolocation API」で本当に掴んでほしいこと
Geolocation API の本質は、
「ブラウザに“今どこにいるか”を聞いて、その結果をアプリの体験に結びつけること」
です。
そのうえで、まず次の感覚をしっかり持っておいてほしいです。
navigator.geolocation.getCurrentPosition で「今の位置を 1 回だけ」取得できること。navigator.geolocation.watchPosition で「位置が変わるたびに」コールバックが呼ばれること。 enableHighAccuracy / timeout / maximumAge で「精度・速度・バッテリー」のバランスを調整できること。
HTTPS とユーザー許可が前提であり、拒否やタイムアウトは“普通に起こるもの”として扱うべきこと。
練習としては、
現在地を 1 回だけ取得して表示する
watchPosition で追跡し、ボタンで開始・停止できるようにする
この 2 つを書けるようになるだけで、
位置情報系のアプリの「土台」はほぼ押さえたと言っていいです。
そこから先は、地図 API と組み合わせたり、
サーバーに位置を送って他ユーザーと共有したりと、
あなたのアイデア次第でいくらでも広げていけます。
「位置情報」は、現実世界と Web アプリをつなぐ強いフックです。
ここを押さえておくと、作れるものの幅が一気に広がります。

