Webアプリを公開しよう! Chrome Web Store/Apps入門

第4回 Webアプリを作ろう#1──Geolocation API,Notification API

この記事を読むのに必要な時間:およそ 15.5 分

Geolocation API

Geolocation APIは,緯度や経度といった位置情報を取得するAPIです。window.navigator.geocation以下のメソッドを使って取得することができます。Webアプリの実際のソースコードを例に解説します。

位置情報の取得

まずは,Geolocation APIを使って最初に現在地を取得して表示します。現在地を取得している部分は,以下の通りです。

odometer.js(該当部分のみ抜粋)

//オプション
var geoOptions = {
    enableHighAccuracy: true,   //高精度要求
    timeout: 6000,          //タイムアウト(ミリ秒)
    maximumAge: 0       //キャッシュ有効期限(ミリ秒)
}

if (navigator.geolocation) {
    
    //現在地の位置情報取得
    navigator.geolocation.getCurrentPosition(
        init,       //成功時コールバック
        onError,    //失敗時コールバック
        geoOptions  //オプション
    );
} else {
    return;
}

現在の位置情報を取得する場合は,navigator.geolocation.getCurrentPositionメソッドを使用します。第1引数に取得成功時のコールバック,第2引数に取得失敗時のコールバック,第3引数にオプションを指定します。成功時のコールバックメソッドの引数に与えられるイベントオブジェクトから位置情報を取り出します。ここでは成功時のコールバックにinitメソッドを指定しています。

/*
 * 初期表示
 */
function init(position){
    
    //地図作成
    createMap(position.coords.latitude, position.coords.longitude);
    
    //現在地情報表示
    showCurrentPosition(position);
    
    //現在地を保持
    currentPos.lat = position.coords.latitude;
    currentPos.lng = position.coords.longitude;
    
}

/*
 * エラーコールバック
 */
function onError(e) {
    alert(e.message + '(' + e.code + ')');
}

/*
 * 現在地情報表示
 */
function showCurrentPosition(position){
    
    //現在地を表示
    //緯度
    document.getElementById('latitude').textContent = 
        position.coords.latitude;
    
    //経度
    document.getElementById('longitude').textContent = 
        position.coords.longitude;
    
    //精度
    document.getElementById('accuracy').textContent = 
        position.coords.accuracy;
    
    //移動方向
    document.getElementById('heading').textContent = 
        position.coords.heading;
    
    //移動速度
    document.getElementById('speed').textContent = 
        position.coords.speed;
    
    //取得日時
    var dt = new Date(position.timestamp);
    document.getElementById('timestamp').textContent =
        dt.getFullYear() + '年' + (dt.getMonth()+1) + '月' + dt.getDate() + '日' + 
        dt.getHours() + '時' + dt.getMinutes() + '分' + dt.getSeconds() + '秒';
}

initメソッド内では,createMapメソッドでGoogle Mapsを使って地図を作成しています。HTMLに位置情報を表示しているのはshowCurrentPositionメソッドになります。ここでは,イベントオブジェクト内の各プロパティをHTMLにセットしているだけです。取得可能な位置情報は緯度,経度といった基本的な情報に加え,精度や移動方向,移動速度なども取得することができます。詳細は下記表を参照してください。注意点として,navigator.geolocation.getCurrentPositionメソッドでは移動している状態を認識していないため,移動方向,移動速度を取得することができません。これらを取得するには,navigator.geolocation.watchPositionメソッドを使って継続的に位置情報を取得する必要があります。navigator.geolocation.watchPositionメソッドについては後述します。

表1 位置情報のイベントオブジェクト

プロパティ 説明
coords.latitude 緯度
coords.longitude 経度
coords.accuracy 精度(誤差をメートル単位で表示)
coords.altitude 高度(GPS高度)
※標高ではないことに注意
coords.altitudeAccuracy 高度の精度(誤差をメートル単位で表示)
coords.heading 移動方向(真北を0度とした右回りの角度)
coords.spped 移動速度(m/s)
timestamp 取得日時(数値)
※本来の仕様上はDate型を返す

目的地の設定と距離の算出

目的地の設定は,地図上をクリックすることによって行います。Google Mapsのクリックイベントから緯度と経度を取得することができるので,現在地情報の表示と同様にshowDestinationPositionメソッドで目的地の緯度,経度を表示します。また,同時にshowDistanceメソッドで目的地までの距離を算出して表示します。

/*
 * 目的地情報表示
 */
function showDestinationPosition(lat, lng) {
    
    //目的地を表示
    document.getElementById('dest-latitude').textContent = lat;
    document.getElementById('dest-longitude').textContent = lng;
}

/*
 * 目的地までの距離表示
 */
function showDistance(currentPos, destPos){
    
    //単位をkmに変換して表示
    document.getElementById('distance').textContent =
        Math.round(getDistance(currentPos.lat, currentPos.lng, destPos.lat, destPos.lng)) / 1000;
}

/*
 * 2点間距離計算(m)
 */
function getDistance(lat, lng, dLat, dLng){
    
    //緯度1度あたり111km、経度1度あたり91kmの概算
    var h = Math.abs(dLat - lat) * 111000;
    var v = Math.abs(dLng - lng) * 91000;
    
    return Math.sqrt(Math.pow(h, 2) + Math.pow(v, 2));
}

目的地までの距離の算出については,厳密な計算方法は非常に複雑なため,ここでは緯度1度あたり111km,経度1度あたり91kmの概算で計算しています。そのため,日本以外の場所では誤差が大きくなります。

参考:Google Mapsを使った地図の作成

/*
 * Google Maps
 */
var map,
    marker;
var mapOptions = {
    zoom: 13,
    mapTypeId: google.maps.MapTypeId.ROADMAP
};

/*
 * 地図作成
 */
function createMap(lat, lng) {
    
    //地図作成
    var infowindow = new google.maps.InfoWindow(),
        latLng = new google.maps.LatLng(lat, lng);
    map = new google.maps.Map(document.getElementById("map"), mapOptions);
    
    //マーカー作成
    marker = new google.maps.Marker(
        {
            title: '現在地',
            position: latLng,
            map: map
        }
    );
    
    /*
     * クリックで目的地設定
     */
    var destMarker = null;
    google.maps.event.addListener(map, "click", function(event){
        if ( destMarker ) {
            destMarker.setMap(null);
        }
        destMarker = new google.maps.Marker(
            {
                title: '目的地',
                position: event.latLng,
                map: map
            }
        );
        
        //目的地情報表示
        showDestinationPosition(event.latLng.lat(), event.latLng.lng());
        
        //目的地までの距離表示
        destPos.lat = event.latLng.lat();
        destPos.lng = event.latLng.lng();
        showDistance(currentPos, destPos);
    });
    
    map.setCenter(latLng);
    infowindow.open(map);
}

著者プロフィール

吉川徹(よしかわとおる)

普段は,普通のSIer。Webからローカルアプリケーション,データベースからインフラ周りに至るまで,何でも担当する雑食系。主にHTML5開発者コミュニティ「HTML5-developers-jp」で活動中。同コミュニティ主催の「HTML5とか勉強会」のスタッフを務め,HTML5の最新動向を追っている。

コメント

コメントの記入