このページの本文へ

iPhoneがJavaScript+SQLiteでGPSレコーダーに! (4/5)

2009年07月13日 16時09分更新

文●古籏一浩

  • この記事をはてなブックマークに追加
本文印刷

位置情報をデータベースに保存し地図に表示する

 今回の仕上げとして、GPS機能で取得した現在地の情報をデータベースに記録し、一覧で表示していくプログラムを作成しましょう。といっても、前回紹介したスクリプトでGPSデータを取得し、保存先をデータベースにするだけです。なお、ここまでのサンプルプログラムと区別するため、データベース名は「gpsDB」に変更しています。

 ただし、navigator.geolocation.watchPosition() によって記録される位置情報は、いつの間にか膨大になってしまいます。サンプル05ではすべてのデータを読み出していましたが、数万レコードにもなると読み出して表示するのに時間がかかります。そこで、最新10件だけを取得して表示するようにSQL文を変更します。


SELECT * from gpstable order by time desc limit 10;


 また、これまでのサンプルでは時刻がミリ秒単位でしたので、ミリ秒単位のGPS時刻情報を Date()メソッドで日付オブジェクトに変換し、日時情報として扱いやすくします。


var dt = new Date(row.time);		// 記録された時間の日付オブジェクトを生成
var M = dt.getMonth() + 1;	// 月を求める
var D = dt.getDate();	// 日にちを求める
var h = dt.getHours();	// 時を求める
var m = dt.getMinutes();	// 分を求める
var s = dt.getSeconds();	// 秒を求める


 以上で、iPhoneを持ってあちこち動き回れば自動的に位置情報がデータベースに記録されるプログラムができました。画面には最新の記録10件が表示され、Googleマップに現在地点が表示されます。Safariを終了すれば記録は中断されますが、データベースに記録した位置情報は電源を落としても消えません。

 完成したスクリプトがサンプル06です。画面レイアウトなどは自由に変更できますので、自分の使いやすいようにするとよいでしょう。

 また、記録したデータを読み出し、Googleマップの表示に反映させるプログラム(サンプル07)も掲載しておきますので参考にしてください。

iPhoneを持って動き回ると位置情報が記録され、マップにも現在地が矢印で示される(左)。記録されたデータをもとに、どのように動いたかを表示する(右)



●サンプル06のソースコード


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<title>Safari + GPS + Database</title>
<style type="text/css"><!--
h1 { font-size:16pt; }
#pos, #msg { font-size:9pt; }
#gpsData { font-size:8pt;line-height:110%; }
--></style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript"><!--
// GPSデータ保存用データベース作成
var myDB = openDatabase("gpsDB","1.0","GPSデータ");
myDB.transaction(
    function(transaction){
        transaction.executeSql('CREATE TABLE gpstable(lat REAL, lng REAL, time REAL );');
    },
    function (err){
        var ele = document.getElementById("msg");
        if (err.code == 1) {
            ele.innerHTML = "データベースはすでにあるのでデータベースをオープンしました";
        }else{
            ele.innerHTML = "データベースエラーです : "+err.code;
        }
    },
    function (){ document.getElementById("msg").innerHTML = "新規にデータベースgpsDBを作成しました" }
)
// データベースにGPSデータを保存
function saveDB(lat, lng){
    myDB.transaction(
        function(tx){
            var time = parseInt((new Date()).getTime());
            tx.executeSql('INSERT INTO gpstable values ('+lat+','+lng+','+time+')');
        },
        function(err){ document.getElementById("msg").innerHTML = "DB Error : "+err.code; }
    );
}
// データベースからGPSデータを読み出し最新10件を表示
function readDB(){
    myDB.transaction(
        function(tx){
            tx.executeSql('SELECT * from gpstable order by time desc limit 10;',
            [ ],
            function (tx, rs){
                var txt = "";
                for (var i=0; i<rs.rows.length; i++){
                    var row = rs.rows.item(i);
                    var dt = new Date(row.time);    // 記録された時間の日付オブジェクトを生成
                    var M = dt.getMonth() + 1;  // 月を求める
                    var D = dt.getDate(); // 日にちを求める
                    var h = dt.getHours();  // 時を求める
                    var m = dt.getMinutes();    // 分を求める
                    var s = dt.getSeconds();    // 秒を求める
                    var tmsg = M+"月"+D+"日 "+h+"時"+m+"分"+s+"秒";
                    // 緯度、経度と時間を組み合わせた文字列を生成
                    txt = txt + (i+1) + " : "+row.lat+","+row.lng+" : "+tmsg+"<br>";
                }
                // 画面にデータを表示する
                document.getElementById("gpsData").innerHTML = txt;
            });
        }
    );
}
// ページが読み込まれたときの処理
window.onload = function(){
    // グーグルマップ ver 3の構築と表示
    var defPos = new google.maps.LatLng(36, 137); // 座標値はどこでもよい
    gmap = new google.maps.Map(document.getElementById("map_canvas"), {
        zoom : 17,
        center : defPos,
        mapTypeId : google.maps.MapTypeId.ROADMAP
    });
    gmarker = new google.maps.Marker({
        positon : defPos,
        map:gmap,
        icon : "./arrow.png"
    });
    navigator.geolocation.watchPosition(update);
    setInterval("readDB()", 5 * 1000);  // 5秒に一回データベース内のGPSデータを表示する
}
// GPSデータを受信した時の処理
function update(position){
    var lat = position.coords.latitude;
    var lng = position.coords.longitude;
    saveDB(lat, lng); // 現在地をデータベースに保存
    var currentPos = new google.maps.LatLng(lat, lng);
    var acc = position.coords.accuracy;   // 誤差を表示する
    gmap.set_center(currentPos);    // 地図の中心を現在地にする
    gmarker.set_position(currentPos);
    document.getElementById("pos").innerHTML = lat+","+lng+",誤差:"+acc;
}
// --></script>
</head>
<body>
<div id="map_canvas" style="width:90%;height:75%"></div>
<div id="pos">lat, lng</div>
<div id="gpsData"></div>
<div id="msg"></div>
</body>
</html>


この連載の記事

一覧へ
Web Professionalトップページバナー

この記事の編集者は以下の記事をオススメしています

Webディレクター江口明日香が行く