こんにちは。
個人的な話で恐縮ですが、最近ケータイをDoCoMoのP904iに買い換えました。
904シリーズはGPSが標準搭載です。
こりゃ
なかにしの記事もあったことですし、DoCoMoのケータイ版も試してみなけりゃ漢がすたるってなもんです。
ただ使ってみたいだけですが(^^;)
今回は、携帯からURLにアクセスして、コメントを送信すると、位置情報とともにDBへ格納してみます。
その情報の最終10件をgoogleMapsに表示してみるというのをやってみたいとおもいます。
チャリンコで旅してるとき(?)に行った場所の情報をポストしておき、それをリアルタイムで自分のblogに表示させておく、なーんて使い方もできるかもしれません。
さて、GPS対応のDoCoMoの携帯から、以下のURLへアクセスしてください。
http://www.lockon.co.jp/blog/source/docomoGmaps/gps.php
地図ページで送信した位置とコメントがマッピングされていれば成功です。
簡単に解説します。
まずデータの格納領域を用意します。
前回はCSVにはき出していましたが、今回はPostgreSQLに書き出してみたいと思います。
せっかく位置情報を扱うのでPostGISをインストールしたいところですが用意が面倒なので、ここでは幾何データ型を利用してみます。
これで応用編も視野に入れていますが、本当にあるかはわかりません。w
create table dtb_geo (
id serial primary key
,geo point NOT NULL
,comment text
,access_time timestamp NOT NULL DEFAULT NOW()
);
これで、DBの用意は完了です。
次に携帯から呼び出すページの作成です。
流れをおいやすくするためにエラー処理は最小限にしています。
●gps.php
<?php
require_once("DB.php");
if ( $_GET["mode"]=='confirm' ){
if ( isset($_GET["lat"]) && isset($_GET["lon"]) ){
// connect DB
$dsn = "pgsql://user:pass@127.0.0.1/dbname";
$conn = DB::connect($dsn);
// Get location
$lat = str_replace("+", "", $_GET["lat"]);
$lon = str_replace("+", "", $_GET["lon"]);
$lat = split("\.", $lat); $lat[2] = $lat[2].".".$lat[3];
$lon = split("\.", $lon); $lon[2] = $lon[2].".".$lon[3];
$lat = $lat[0] + $lat[1]/60 + $lat[2]/3600;
$lon = $lon[0] + $lon[1]/60 + $lon[2]/3600;
$sql = "INSERT INTO dtb_geo (comment,geo) VALUES (?, point(?,?) )";
$result = $conn->query($sql, array($_GET["comment"], $lat, $lon) );
if ( $conn->isError($result) ){
$body = "登録に失敗しました";
} else {
$body = "緯度:${lat}、経度:${lon}を登録しますた";
}
// write XML
$sql = "SELECT geo[0] as lat, geo[1] as lon, comment, to_char(access_time, 'YYYY/MM/DD HH24:MI') as access_time FROM dtb_geo ORDER BY access_time DESC LIMIT 10";
$result = $conn->getAll($sql, DB_FETCHMODE_ASSOC);
$fp = fopen("marker.xml", "w");
fwrite($fp, "<markers>\n");
for ( $i=0; $i<count($result); $i++){
$no = $i + 1;
$lat = $result[$i]["lat"];
$lon = $result[$i]["lon"];
$comment = mb_convert_encoding($result[$i]["comment"], "UTF-8", "EUC-JP");
$access_time = $result[$i]["access_time"];
fwrite($fp, "<marker lon='${lon}' lat='${lat}' no='${no}' comment='${comment}' time='${access_time}' />\n");
}
fwrite($fp, "</markers>\n");
fclose($fp);
} else {
$body = "位置情報がありません";
}
} else {
$body = '<form method="get" action="./gps.php" lcs>
<input type="hidden" name="mode" value="confirm" />
<input type="text" name="comment" value="" />
<input type="submit" name="test" value="送信" />
</form>';
}
?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.1//EN' 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=EUC-JP" />
<title>GPSテスト</title>
</head>
<body>
<?php echo $body ?>
</body>
ポイントは
<form method="get" action="./gps.php" lcs>
です。formタグにlcs属性をつけてやることで確認ダイアログが表示されるようになり,
位置情報を送出するようになります。
Aタグにつける方法もあります。
あとは、渡されてきた位置情報を利用するだけです。,
さて、これで、登録した情報を格納し登録できるようになりましたので、あとは表示です。
googleMapsのキーは取得しておいてください。残り必要なファイルは2つです。
まずは、画像を表示させるための、htmlです。
●sample.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp" />
<title>足あと</title>
<script src="http://maps.google.com/maps?file=api&v=1&key=xxxxxxx" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="Gmaps.js"></script>
</head>
<body onload="init()" >
<div id="map" style="width:800px; height:600px; white-space: nowrap;"></div>
</body>
つぎにXMLファイルを読み込んでマッピングするjsファイルです。
●Gmaps.js
var map;
var markers;
function loadData(entryURL){
var request = GXmlHttp.create();
var filename = "marker.xml";
filename += "?rand=" + Math.random(); //add random
request.open("GET", filename, true);
request.send(null);
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
var xmlDoc = request.responseXML;
markers = xmlDoc.documentElement.getElementsByTagName("marker");
plotMarkers();
}
}
}
function plotMarkers(){
if(markers != null && markers.length > 0){
map.centerAndZoom(new GPoint(parseFloat(markers[0].getAttribute("lon")),parseFloat(markers[0].getAttribute("lat"))),2);
for (var i = 0; i < markers.length; i++) {
var point = new GPoint(parseFloat(markers[i].getAttribute("lon")),
parseFloat(markers[i].getAttribute("lat")));
var iconFlag = 0;
if ( markers[i].getAttribute("no") == "1" ){
map.centerAndZoom(new GPoint(parseFloat(markers[i].getAttribute("lon")),parseFloat(markers[i].getAttribute("lat"))),2);
iconFlag = 1;
}
var title = markers[i].getAttribute("no") + '<br />' + markers[i].getAttribute("comment") + "<br />" + markers[i].getAttribute("time")
var marker = createMarker(point, i, title, iconFlag);
map.addOverlay(marker);
}
}
}
function createMarker(point, index, title, iconFlag) {
var icon = new GIcon();
var icon_uri = "http://labs.google.com/ridefinder/images/mm_20_blue.png";
if ( iconFlag == 1 ){
icon_uri = 'http://labs.google.com/ridefinder/images/mm_20_red.png'
}
icon.image = icon_uri;
icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
icon.iconSize = new GSize(12, 20);
icon.shadowSize = new GSize(22, 20);
icon.iconAnchor = new GPoint(6, 20);
icon.infoWindowAnchor = new GPoint(5, 1);
var marker = new GMarker(point, icon);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(title);
});
return marker;
}
function init(){
loadData();
map = new GMap(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
var types = map.getMapTypes() ;
map.setMapType(types[0]);
}
かなり即席なので、間違っている点があるかもしれませんが、その際は、ぜひご指摘ください。
次回は、せっかくDBに放り込んでいるので、そのデータを利用して、ごにょごにょやってみたいと思います。
【参考】
作ろうiモードコンテンツ-GPS
Web屋のネタ帳 -
データベース上の位置情報を効率的に検索する方法(PostgreSQL編)