Help us understand the problem. What is going on with this article?

Gelocationのデモアプリ

More than 1 year has passed since last update.

はじめに

位置情報を用いたアプリケーションを作りたいと考えています。
アプリケーションは、ブラウザ、iOS、Androidを想定しています。
まずブラウザに着手しました。ブラウザならクロスプラットフォームですしね。
ブラウザの位置情報の機能は、JavaScriptのGeolocationが標準かと思います。
機能の調査を行い、デモアプリを作成しました。

IMG_0049.PNG

概要

  • Geolocationの紹介
  • index.html
  • index.js
  • GitHub

詳細

Geolocationの紹介

以下の機能があります。

  • getCurrentPosition
    • 現在地を1回取得します。
  • watchPosition
    • 現在地を複数回取得します。
  • clearWatch
    • watchPositionの更新を停止します。

取得する現在地の情報の一覧です。

  • latitude
    • 緯度
  • longitude
    • 経度
  • altitude
    • 高度(メートル)
  • accuracy
    • latitude と longitude の精度(メートル)
  • altitudeAccuracy
    • altitude の精度(メートル)
  • heading
    • デバイスの移動方向
      • 真北 0
      • 東 90
      • 西 270
  • speed
    • デバイスの移動速度(メートル/秒)

詳細は、下記のドキュメントが参考になると思います。
W3C https://www.w3.org/TR/geolocation-API/
MDN https://developer.mozilla.org/en-US/docs/Web/API/Geolocation

index.html

デモアプリでは、jQuery、Bootstrap、Animate CSSを使っています。解説は行いません。

ボタンを3つ作成し、それぞれ上記の機能の起動に対応させました。

<button type="button" class="btn btn-outline-primary" id="current">Current</button>
<button type="button" class="btn btn-outline-primary" id="watch">Watch</button>
<button type="button" class="btn btn-outline-primary" id="clear">Clear</button>

機能が実行されると現在地の情報で画面を更新します。

<div>latitude: <span class="latitude"></span></div>
<div>longitude: <span class="longitude"></span></div>
<div>altitude: <span class="altitude"></span></div>
<div>accuracy: <span class="accuracy"></span></div>
<div>altitudeAccuracy: <span class="altitudeAccuracy"></span></div>
<div>heading: <span class="heading"></span></div>
<div>speed: <span class="speed"></span></div>
<div>timestamp: <span class="timestamp"></span></div>

また、関連するメッセージを下部に表示します。

<div>message: <span class="message"></span></div>

index.js

共通のオプションの値です。
enableHighAccuracyは、高精度を指定できます。
ただし、消費電力が増えたり、時間がかかったりします。この辺りは、トレードオフですね。
デフォルトは、falseです。
timeoutは、デフォルトは、無期限です。
maximumAgeは、位置情報のキャッシュ情報の期限です。0だと、キャッシュを利用しません。

var options = {
    enableHighAccuracy: true,
    timeout: 10000, // milliseconds
    maximumAge: 0 // 0 = the device cannot use a cached position
};

ブラウザがGeolocationを使えるか確認しています。
最近のブラウザはほぼ対応しているので、念の為のおまじないです。
確認後、画面の下部にメッセージを表示しています。
また、clear()は後半で説明します。

function geolocation() {
    clear();
    if (navigator.geolocation) {
        $('.message').html('Geolocation is available').animateCss('flash');
        return true
    } else {
        $('.message').html('Geolocation IS NOT available').animateCss('flash');
        return false
    }
}

getCurrentPositionです。画面のCurrentボタンをクリックすると起動します。
まず、上記のgeolocation()でブラウザが対応しているかチェックしています。
現在地の取得を実施し、成功したらsuccess()、失敗したらerror()を実行しています。
また、optionsは、上記で説明した通りです。

$('#current').on('click', function () {
    if (!geolocation()) {
        return
    }
    navigator.geolocation.getCurrentPosition(
        function (pos) {success(pos, 'current')},
        function (err) {error(err)},
        options
    );
});

watchPositionです。画面のWatchボタンをクリックすると起動します。
getCurrentPositionとほぼ一緒ですが、実行後の返却値をwatchIdに保存しています。
clearWatch()は、このwatchIdを利用して現在地の取得を中止します。

var watchId = null;
$('#watch').on('click', function () {
    if (!geolocation()) {
        return
    }
    watchId = navigator.geolocation.watchPosition(
        function (pos) {success(pos, 'watch')},
        function (err) {error(err)},
        options
    );
});

getCurrentPositionとwatchPositionを実行し、成功した場合に実行されます。
画面の情報を更新する部分です。
watchPositionの場合は、位置情報が更新されるたびに実行されます。

function success(pos, method) {
    $('.latitude').html(pos.coords.latitude);
    $('.longitude').html(pos.coords.longitude);
    $('.altitude').html(pos.coords.altitude);
    $('.accuracy').html(pos.coords.accuracy);
    $('.altitudeAccuracy').html(pos.coords.altitudeAccuracy);
    $('.heading').html(pos.coords.heading);
    $('.speed').html(pos.coords.speed);
    $('.timestamp').html(pos.timestamp);
    switch(method)
    {
        case 'current':
        $('.message').html('Current OK').animateCss('flash');
        break;
        case 'watch':
        $('.message').html('Watch OK').animateCss('flash');
        break;
    }
}

getCurrentPositionとwatchPositionを実行し、失敗した場合に実行されます。
エラーコードは、1、2、3が存在します。
1は、PERMISSION_DENIEDが定義されていて、主に、SSL環境出ない場合に表示されるようです。
2は、POSITION_UNAVAILABLEが定義されていて、何らかの内部エラーの場合に表示されるようです。
3は、optionsのtimeoutで指定を超過した場合に表示されるようです。
1、2、3以外は返却されないようですが、デバッグ用にerr.messageと言う値があります。通常は利用しないはずですが、一応表示するようにしてみました。

function error(err) {
    switch(err.code)
    {
        case 1:
        $('.message').html('PERMISSION_DENIED').animateCss('flash');
        break;
        case 2:
        $('.message').html('POSITION_UNAVAILABLE').animateCss('flash');
        break;
        case 3:
        $('.message').html('TIMEOUT').animateCss('flash');
        break;
        $('.message').html(err.message).animateCss('flash');
        break;
    }
}

clearWatchです。画面のClearボタンをクリックすると起動します。
画面と各種変数の初期化を行なっています。

$('#clear').on('click', function () {
    clear();
    $('.message').html('Clear OK').animateCss('flash');
});

上記で度々clear()がありましたが、ここでは、画面の初期化とwatchPositionの初期化をwatchIdを利用しておこなっています。

function clear() {
    $('.latitude').html('');
    $('.longitude').html('');
    $('.altitude').html('');
    $('.accuracy').html('');
    $('.altitudeAccuracy').html('');
    $('.heading').html('');
    $('.speed').html('');
    $('.timestamp').html('');
    if (watchId) {
        navigator.geolocation.clearWatch(watchId);
        watchId = null;
    }
}

GitHub

上記のソースコードの完全版は下記にありますので、参考にしてください。
https://github.com/maedamikio/public/tree/master/geolocation

おわりに

Geolocationの基本的な使い方が理解出来ました。
この知見をベースにアプリケーションの作成へ進みたいと思います。

実は、初めてJavaScriptを使ってみました。正確に言うと、今までもコピペで何となく利用していましたが、理解しながら使ったのは初めてです。
jQuery、Bootstrap、Animate CSSも使うことになり、良い勉強になりました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away