ボタンクリックで位置とコメントを記録する
単純なGPSロガーとしてはサンプル01/02で完成ですが、最後におまけとして、位置情報と時間と一緒にコメントも記録できるようにしましょう。コメント機能を付ければ、訪問したラーメン店やレストランの食べ歩き情報を書き込む、といった使い方ができます。
実際のプログラムはサンプル03です。以降は差分のみ説明します。
まず、「現在地を記録」ボタンとコメントを記入するテキストエリアを用意します。どちらも処理しやすいようにID名を指定しておきます。
<input type="button" value="現在地を記録" id="saveButton"><br> <textarea cols="40" rows="10" id="shopComment"></textarea>
次に、入力されたコメントは以下のように読み出し、GPSデータを記録するsaveDB関数にパラメータとして渡します。
var txt = document.getElementById("shopComment").value; saveDB(lat, lng, time, txt)
saveDB関数には、localStorageに保存する部分にコメントを追加しています。
window.localStorage.setItem("jp.ascii.gpsData"+count, lat+","+lng+","+time+","+txt);
以上で完成です。サンプル03で記録したデータを読み出し、個別に表示する機能を付けたのがサンプル04です。基本的にはサンプル02とほとんど変わりません。テキストエリアにコメントを表示する処理が追加されているだけです。
サンプル03/04のプログラムを改良すると、電波が届かない場所でもお店の位置と感想などを記録/閲覧できるWebアプリケーションを作成できます。電波が受信できない状況では、サーバーなしで利用できるlocalStorageは非常に便利です。ぜひ試してみてください。
■サンプル03[HTML]
<!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <meta charset="utf-8" /> <title>Safari + GPS + localStorage (Shop Map)</title> <style type="text/css"> h1 { font-size:16pt; } #pos, #msg { font-size:9pt; } </style> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script> <script type="text/javascript"> // 記録数を読み出す var count = window.localStorage.getItem("jp.ascii.gpsDataCount") || 0; // 保存してあるデータ数を読み出す。なければ0 // ローカルストレージにGPSデータを保存(順序は1~) function saveDB(lat, lng, time, txt){ count++; // 保存するデータ数を増やす window.localStorage.setItem("jp.ascii.gpsData"+count, lat+","+lng+","+time+","+txt); // 位置を記録 window.localStorage.setItem("jp.ascii.gpsDataCount", count); // 記録データ数を保存 document.getElementById("msg").innerHTML = count+"番目のデータを保存しました"; } // ページが読み込まれたときの処理 window.addEventListener("load", 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,GPSerror,{ enableHighAccuracy: true // 高精度で取得 }); // 記録ボタンが押された場合の処理 document.getElementById("saveButton").addEventListener("click", function(){ var time = (new Date()).getTime(); // 1970年1月1日からの経過ミリ秒(timestampは使わず) var txt = document.getElementById("shopComment").value; saveDB(lat, lng, time, txt) readDB(); // データベースからデータを読み出し表示 }, true); }, true); // GPSデータを受信した時の処理 function update(position){ lat = position.coords.latitude; lng = position.coords.longitude; var currentPos = new google.maps.LatLng(lat, lng); var acc = position.coords.accuracy; // 誤差を表示する gmap.setCenter(currentPos); // 地図の中心を現在地にする gmarker.setPosition(currentPos); var dt = new Date(); 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+"秒"; document.getElementById("pos").innerHTML = lat+","+lng+",誤差:"+acc+"m<br>"+tmsg; } // GPSデータが受信できない場合のエラー処理 function GPSerror(err){ document.getElementById("msg").innerHTML = "位置を検出できません"; } </script> </head> <body> <div id="map_canvas" style="width:90%;height:300px;border:1px solid black;"></div> <div id="pos">lat, lng</div> <div id="msg"></div> <form> <input type="button" value="現在地を記録" id="saveButton"><br> <textarea cols="40" rows="10" id="shopComment"></textarea> </form> </body> </html>
■サンプル04[HTML]
<!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <meta charset="utf-8" /> <title>記録済みのデータをマップ上に表示する</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"> // 記録数を読み出す var count = window.localStorage.getItem("jp.ascii.gpsDataCount") || 0; // 保存してあるデータ数を読み出す。なければ0 var gpsNo = 1; // 表示する位置データの番号 // ページが読み込まれたときの処理 window.addEventListener("load", function(){ document.getElementById("msg").innerHTML = "データは"+count+"個記録されています"; // グーグルマップ 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" }); // 前のデータ表示ボタンが押された場合の処理 document.getElementById("prevButton").addEventListener("click", function(){ gpsNo--; if (gpsNo < 1){ gpsNo = 1; } // 最初のデータより前にならないように toMap(); }, true); // 次のデータ表示ボタンが押された場合の処理 document.getElementById("nextButton").addEventListener("click", function(){ gpsNo++; if (gpsNo > count){ gpsNo = count; } // 最後のデータまでしか表示しないように toMap(); }, true); }, true); // 地図上に表示 function toMap(){ try{ var data = window.localStorage.getItem("jp.ascii.gpsData"+gpsNo).split(","); }catch(e){ return; } document.getElementById("msg").innerHTML = gpsNo+"番目のデータ"; var lat = data[0]; // 緯度 var lng = data[1]; // 経度 var dt = new Date(parseInt(data[2])); // 記録された時間の日付オブジェクトを生成 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 = lat+","+lng+"<br>"+tmsg+"<br>"; var mapPos = new google.maps.LatLng(lat, lng); gmap.setCenter(mapPos); // 地図の中心を現在地にする gmarker.setPosition(mapPos); document.getElementById("pos").innerHTML = txt; document.getElementById("shopComment").value = data[3]; // コメントを表示 } </script> </head> <body> <div id="map_canvas" style="width:90%;height:300px;border:1px solid black;"></div> <div id="pos">lat, lng</div> <div id="msg"></div> <form> <input type="button" value="前のデータを表示" id="prevButton"> <input type="button" value="次のデータを表示" id="nextButton"><br> <textarea cols="40" rows="10" id="shopComment"></textarea> </form> </body> </html>