【JavaScript】Geolocation APIで位置情報を取得する方法を解説

【JavaScript】Geolocation APIで位置情報を取得する方法を解説

公開: 更新:
CodeCampが提供するDX人材育成が可能なプログラミングやITが学べる公開講座

JavaScriptで位置情報を取得したいと考えているWeb開発者にとって、Geolocation APIは非常に便利な機能です。このAPIを活用することによって、ユーザーの現在地を取得し、地図アプリや店舗検索、配達サービスなど様々なWebアプリケーションに応用できます。

しかし、位置情報の取得方法は複数あり、どのメソッドを使えば良いのか、エラー処理はどう実装すべきか、など実装時に迷うポイントも多いです。ブラウザの対応状況やプライバシーへの配慮など、注意すべき点も理解しておく必要があります。

この記事では、JavaScriptで位置情報を取得する具体的な方法、Geolocation APIの基本的な仕組み、実装時の注意点、実際にコピーして使える完全版のサンプルコードまで詳しく解説していきます。



JavaScriptのGeolocation APIとは

Geolocation APIとは、GPSやWi-Fi、IPアドレスなど、複数の情報源を組み合わせて位置情報を推定するAPIです。デバイスやブラウザが利用可能な情報源を自動的に選択し、最も精度の高い結果を返します。

位置情報の取得には、必ずユーザーの明示的な許可が必要になります。ブラウザは初回アクセス時、位置情報の共有を求めるダイアログを表示し、ユーザーが許可または拒否を選択する流れです。許可された場合のみAPIが動作し、拒否された場合はエラーが返されます。

セキュリティの観点から、Geolocation APIは「HTTPS環境でのみ動作」するように設計されています。HTTP接続では位置情報の取得ができないため、本番環境では必ずSSL証明書を導入する必要があります。開発環境ではlocalhostでも動作するため、テストには問題ありません。

取得できる位置情報の種類

Geolocation APIから取得できる位置情報は、緯度・経度だけではなく複数の属性が含まれています。これらの情報を活用することによって、より詳細な位置ベースの機能を実装できます。

取得できる主な位置情報は、以下の通りです。

プロパティ 説明 単位
latitude 緯度 度(-90から90)
longitude 経度 度(-180から180)
altitude 高度(海抜) メートル
accuracy 位置の精度 メートル
altitudeAccuracy 高度の精度 メートル
heading 移動方向 度(0から360)
speed 移動速度 メートル毎秒

これらのプロパティは、position.coordsオブジェクトからアクセスできますが、デバイスによっては一部の値がnullになる場合があります。特に高度や移動方向は、GPS機能を持つデバイスでのみ取得できるため、実装時には値の存在確認が必要です。

ブラウザの対応状況と確認方法

Geolocation APIは、古いブラウザだと利用できない場合があります。実装前にブラウザの対応状況を確認し、非対応の場合の代替手段を用意しておくことが重要です。

ブラウザ対応を確認するコードは、以下の通りです。

if ("geolocation" in navigator) {
    // Geolocation APIが利用可能
    console.log("位置情報機能が利用できます");
    navigator.geolocation.getCurrentPosition(function(position) {
        console.log("緯度: " + position.coords.latitude);
        console.log("経度: " + position.coords.longitude);
    });
} else {
    // Geolocation APIが利用不可
    console.log("このブラウザでは位置情報機能が利用できません");
    alert("お使いのブラウザは位置情報機能に対応していません");
}

このコードでは、navigatorオブジェクトに「geolocationプロパティが存在するか」を確認しています。存在する場合はAPIが利用可能と判断し、存在しない場合はユーザーにメッセージを表示する処理を実装しています。ChromeやFirefox、Safari、Edgeなどの主要ブラウザは全てサポートしているため、一般的な用途では問題なく利用できるでしょう。

【PR】プログラミングや生成AIを無料で学べる「コードキャンプフリー」

JavaScriptで位置情報を取得する方法

JavaScriptで位置情報を取得するには、Geolocation APIが提供する専用のメソッドを使用します。位置情報の取得方法は、取得のタイミングや頻度によって使い分ける必要があり、以下3つの方法があります。

  • getCurrentPosition()で現在位置を取得する
  • watchPosition()で位置情報を継続的に監視する
  • clearWatch()で位置情報の監視を停止する

それぞれの方法は用途が異なり、getCurrentPosition()は1回だけ位置情報を取得したい場合、watchPosition()はリアルタイムで位置情報を追跡したい場合に適しています。clearWatch()は監視を停止するために使用します。

それでは各項目について、詳しく解説していきます。

getCurrentPosition()で現在位置を取得する

getCurrentPosition()メソッドは、ユーザーの現在位置を1回だけ取得するために使用します。このメソッドは非同期で動作し、位置情報の取得が完了すると、コールバック関数が実行される仕組みです。

基本的な使い方は、以下の通りです。

navigator.geolocation.getCurrentPosition(
    function(position) {
        // 取得成功時の処理
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        console.log("緯度:" + latitude + ", 経度:" + longitude);
    },
    function(error) {
        // 取得失敗時の処理
        console.error("位置情報の取得に失敗しました: " + error.message);
    }
);

このコードでは、第1引数に成功時のコールバック関数、第2引数に失敗時のコールバック関数を指定しています。成功時にはposition.coords.latitudeで緯度、position.coords.longitudeで経度を取得できます。

ユーザーが位置情報の共有を許可すると、自動的に成功時のコールバックが実行され、拒否するとエラーコールバックが実行されるため、両方のケースに対応した実装が必要です。

watchPosition()で位置情報を継続的に監視する

watchPosition()メソッドは、ユーザーの位置情報を継続的に監視し、位置が変化するたびにコールバック関数を実行します。このメソッドはGPSアプリやナビゲーションシステムなど、リアルタイムで位置を追跡する必要がある場合に便利です。

基本的な使い方は、以下の通りです。

var watchId = navigator.geolocation.watchPosition(
    function(position) {
        // 位置更新時の処理
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        console.log("現在地が更新されました: 緯度" + latitude + ", 経度" + longitude);
    },
    function(error) {
        // エラー時の処理
        console.error("位置情報の監視に失敗しました: " + error.message);
    },
    {
        enableHighAccuracy: true,
        timeout: 20000,
        maximumAge: 0
    }
);

watchPosition()メソッドは監視IDを返すため、変数に保存しておきます。第3引数のオプションでは、enableHighAccuracyで高精度モードを有効化し、timeoutで取得のタイムアウト時間をミリ秒単位で設定しています。位置情報は定期的に更新され、移動するたびにコールバック関数が実行されるため、動的なアプリケーションに適した方法です。

clearWatch()で位置情報の監視を停止する

clearWatch()メソッドは、watchPosition()で開始した位置情報の監視を停止するために使用します。監視を続けるとバッテリー消費が増加するため、不要になったタイミングで必ず停止する必要があります。

基本的な使い方は、以下の通りです。

// 監視を開始
var watchId = navigator.geolocation.watchPosition(
    function(position) {
        console.log("位置が更新されました");
    }
);

// 監視を停止
navigator.geolocation.clearWatch(watchId);

clearWatch()メソッドには、watchPosition()で取得した監視IDを引数として渡します。この処理により、位置情報の監視が完全に停止され、それ以降はコールバック関数が実行されなくなるため、リソースの無駄な消費を防げます。ページを離れる前やユーザーが停止ボタンを押したときなど、適切なタイミングで監視を終了することで、パフォーマンスの向上が期待できるでしょう。

【PR】『Python』を学べる企業・個人向けのプログラミングコース

JavaScriptで位置情報を取得する際の注意点

JavaScriptで位置情報を取得する際には、エラーハンドリングやプライバシー保護、精度設定など、いくつか注意すべきポイントがあります。これらを適切に実装することによって、ユーザーに安全で快適な体験を提供できます。

  • エラー処理を実装する
  • ユーザーのプライバシーを保護する
  • 位置情報の精度を高める設定をする

それぞれの注意点を理解し、適切に対処することで、位置情報機能の品質が向上します。特にエラー処理は必須の実装項目であり、プライバシー保護はユーザーの信頼を得るために重要です。

それでは各項目について、詳しく解説していきます。

エラー処理を実装する

位置情報の取得は、様々な理由で失敗する可能性があるため、必ずエラー処理を実装する必要があります。ユーザーが位置情報の共有を拒否した場合、タイムアウトが発生した場合、など適切なメッセージを表示することが重要です。

エラー処理の実装例は、以下の通りです。

navigator.geolocation.getCurrentPosition(
    function(position) {
        // 成功時の処理
        console.log("位置情報を取得しました");
    },
    function(error) {
        // エラー時の処理
        switch(error.code) {
            case error.PERMISSION_DENIED:
                alert("位置情報の使用が拒否されました");
                break;
            case error.POSITION_UNAVAILABLE:
                alert("位置情報が取得できませんでした");
                break;
            case error.TIMEOUT:
                alert("位置情報の取得がタイムアウトしました");
                break;
            default:
                alert("不明なエラーが発生しました");
                break;
        }
    }
);

エラーオブジェクトにはcodeプロパティが含まれており、エラーの種類を判別できます。

PERMISSION_DENIEDはユーザーが許可を拒否した場合、POSITION_UNAVAILABLEは技術的な問題で位置情報を取得できなかった場合、TIMEOUTは指定時間内に取得できなかった場合に発生するため、それぞれに応じた対応が求められるでしょう。

ユーザーのプライバシーを保護する

位置情報は個人を特定できる重要なデータであるため、取り扱いには細心の注意が必要です。なぜ位置情報が必要なのかを明確に説明し、ユーザーの同意を得た上で取得することが求められます。

プライバシー保護のために実施すべき対策は、以下の通りです。

  • 位置情報の利用目的を事前に明示する
  • 必要最小限の頻度で取得する
  • 取得した位置情報を暗号化して保存する
  • 不要になった位置情報は速やかに削除する
  • 第三者への提供には明示的な同意を得る

特にHTTPS環境での実装は必須であり、HTTP接続では位置情報を取得できません。位置情報をサーバーに送信する場合は、通信経路全体を暗号化し、データベースに保存する際も適切な暗号化を施す必要があります。プライバシーポリシーで位置情報の取り扱いを明記し、ユーザーが安心して利用できる環境を整えることが、信頼性の高いサービスを提供する上で不可欠です。

位置情報の精度を高める設定をする

位置情報の精度は、Geolocation APIのオプション設定によって調整できます。高精度モードを有効にすることによってGPSを優先的に使用し、より正確な位置情報を取得できますが、バッテリー消費が増加するトレードオフがあります。

精度を高める設定例は、以下の通りです。

var options = {
    enableHighAccuracy: true,
    timeout: 10000,
    maximumAge: 0
};

navigator.geolocation.getCurrentPosition(
    function(position) {
        console.log("精度: " + position.coords.accuracy + "メートル");
    },
    function(error) {
        console.error("エラー: " + error.message);
    },
    options
);

enableHighAccuracytrueに設定すると、デバイスはGPSなどの高精度な情報源を優先的に使用します。timeoutは位置情報取得のタイムアウト時間をミリ秒単位で指定し、maximumAgeキャッシュされた位置情報の有効期限を設定するオプションです。

maximumAge0にすると常に最新の位置情報を取得しますが、取得に時間がかかる場合があるため、アプリケーションの要件に応じて適切な値を設定する必要があります。

JavaScriptで位置情報を取得する完全版サンプルコード

これまで解説した「JavaScriptによる位置情報の取得機能」を全て組み合わせた、コピペで使える完全版のサンプルコードを作成しました。

このコードはブラウザのGeolocation APIを利用して、ユーザーの現在位置(緯度・経度・高度・精度など)をリアルタイムに取得・表示する仕組みになっています。位置情報は継続的に監視され、移動に応じて自動更新されるため、ナビゲーションアプリなどに活用できます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>位置情報取得サンプル</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
            max-width: 600px;
            margin: 0 auto;
        }
        button {
            padding: 10px 20px;
            margin: 5px;
            font-size: 16px;
            cursor: pointer;
        }
        #position_view {
            margin-top: 20px;
            padding: 15px;
            background-color: #f5f5f5;
            border-radius: 5px;
            white-space: pre-wrap;
            font-family: monospace;
        }
    </style>
</head>
<body>
    <h1>位置情報取得デモ</h1>
    <button onclick="getCurrentPos()">現在位置を取得</button>
    <button onclick="startWatch()">位置監視を開始</button>
    <button onclick="stopWatch()">位置監視を停止</button>
    <div id="position_view">ボタンをクリックして位置情報を取得してください</div>

    <script>
        var watchId;
        var updateCount = 0;

        // ブラウザ対応チェック
        if (!("geolocation" in navigator)) {
            document.getElementById('position_view').innerHTML = 
                "お使いのブラウザは位置情報機能に対応していません";
        }

        // 現在位置を1回だけ取得
        function getCurrentPos() {
            navigator.geolocation.getCurrentPosition(
                displayPosition,
                handleError,
                {
                    enableHighAccuracy: true,
                    timeout: 10000,
                    maximumAge: 0
                }
            );
        }

        // 位置情報の継続監視を開始
        function startWatch() {
            updateCount = 0;
            watchId = navigator.geolocation.watchPosition(
                displayPosition,
                handleError,
                {
                    enableHighAccuracy: true,
                    timeout: 20000,
                    maximumAge: 2000
                }
            );
            document.getElementById('position_view').innerHTML = "位置情報の監視を開始しました...";
        }

        // 位置情報の監視を停止
        function stopWatch() {
            if (watchId) {
                navigator.geolocation.clearWatch(watchId);
                document.getElementById('position_view').innerHTML += "\n\n位置情報の監視を停止しました";
            }
        }

        // 位置情報を表示
        function displayPosition(position) {
            updateCount++;
            
            var geoText = "=== 位置情報 ===\n";
            geoText += "緯度: " + position.coords.latitude + "°\n";
            geoText += "経度: " + position.coords.longitude + "°\n";
            geoText += "高度: " + (position.coords.altitude ? position.coords.altitude + "m" : "取得不可") + "\n";
            geoText += "位置精度: " + position.coords.accuracy + "m\n";
            geoText += "高度精度: " + (position.coords.altitudeAccuracy ? position.coords.altitudeAccuracy + "m" : "取得不可") + "\n";
            geoText += "移動方向: " + (position.coords.heading ? position.coords.heading + "°" : "取得不可") + "\n";
            geoText += "速度: " + (position.coords.speed ? position.coords.speed + "m/s" : "取得不可") + "\n";
            
            var date = new Date(position.timestamp);
            geoText += "取得時刻: " + date.toLocaleString("ja-JP") + "\n";
            geoText += "更新回数: " + updateCount + "回";

            document.getElementById('position_view').innerHTML = geoText;
        }

        // エラーハンドリング
        function handleError(error) {
            var errorMessage = "エラーが発生しました: ";
            
            switch(error.code) {
                case error.PERMISSION_DENIED:
                    errorMessage += "位置情報の使用が拒否されました";
                    break;
                case error.POSITION_UNAVAILABLE:
                    errorMessage += "位置情報が取得できませんでした";
                    break;
                case error.TIMEOUT:
                    errorMessage += "位置情報の取得がタイムアウトしました";
                    break;
                default:
                    errorMessage += "不明なエラー (" + error.message + ")";
                    break;
            }
            
            document.getElementById('position_view').innerHTML = errorMessage;
        }
    </script>
</body>
</html>

このコードをHTMLファイルとして保存し、ブラウザで開くと3つのボタンが表示されます。「現在位置を取得」ボタンで1回だけ位置情報を取得し、「位置監視を開始」ボタンで継続的な監視を開始できます。「位置監視を停止」ボタンで監視を終了すれば、バッテリー消費を抑えられるでしょう。

位置情報には緯度・経度・精度・取得時刻などが表示され、GPSを搭載したスマートフォンやタブレットでは、高度や移動方向も取得できます。エラー処理も実装されているため、ユーザーが位置情報の共有を拒否した場合でも適切なメッセージが表示され、このコードをベースに様々な位置情報機能を開発できるはずです。

※上記コンテンツの内容やソースコードはAIで確認・デバッグしておりますが、間違いやエラー、脆弱性などがある場合は、コメントよりご報告いただけますと幸いです。

ITやプログラミングに関するコラム


ITやプログラミングに関するニュース

ブログに戻る

コメントを残す

コメントは公開前に承認される必要があることにご注意ください。

CodeCampが提供するDX人材育成が可能なプログラミングやITが学べる公開講座 - IT・プログラミングを知って学べるコネクトメディア コードキャンプが提供する無料で学べるプログラミングスクール講座 - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア 配属3ヶ月で30%の生産性向上を実現するいよぎんコンピュータサービスの新人研修に迫る - IT・プログラミングを知って学べるコネクトメディア 金融業界の業務効率化を加速するニッセイアセットマネジメントの生成AI×GAS活用研修事例 - IT・プログラミングを知って学べるコネクトメディア 【製造業のDX人材育成事例】デジタル人材の即戦力化を実現する、日本ガイシ株式会社の異動者向オンボーディング研修 - ITやプログラミングを知って学べるコネクトメディア フューチャーアーキテクト株式会社が実現した新入社員向けIT研修プログラムでタスクフォース制度が主体的な学びと成長を生み出す - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【IT新入社員研修】オンラインとオフラインの最適バランスを実現したFutureOneの導入事例 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【新入社員研修】柔軟なハイブリッド型Java研修で実現した新卒20名の成長と成果|サークレイス株式会社 - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/現場により近いところにデジタルを根付かせるDX基礎講座研修|株式会社ブリヂストン - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/業務の効率化・DX推進に向けたIT人材育成への第一歩|株式会社カナエ - ITやプログラミングを知って学べるコネクトメディア 企業・法人向けのIT・プログラミング研修 - ITやプログラミングを知って学べるコネクトメディア

新着記事

対象者別で探す

子供(小学生・中学生・高校生)向け
プログラミング教室検索する

子供(小学生・中学生・高校生)がロボットやプログラミング言語を学ぶことができるオフラインからオンラインスクールを検索、比較することが可能です。

子供(小学生・中学生・高校生)
プログラミング教室検索する

ITやプログラムなどの
最新情報を検索する

日々、新しいITやプログラミング言語の情報が流れていきますが、特定の情報を時系列でニュースやコラムを確認することができます。

ITやプログラムなどの
最新情報を検索する