2007年10月8日月曜日

つくもノヲ”X="1≠ 224



GPSの自動取得cgiの成功で満足したわけではない。
せっかくGPS情報が取れるのだから、これを地図に表示できないかと
いろいろと探ってみた。

PCのブラウザなら、サーバに置いたGPSのログファイルをgooglemap
で検索すれば、地図上に表示させることができる。

しかし携帯電話からだと事情が異なる。

携帯電話用のgooglemap

まずはこのリンクを開いてみて欲しい。
Googleが提供している携帯電話ブラウザ専用の検索窓が表示される。
ここに例えばキーワードに「駅」、場所に「渋谷」と入れてみる。
すると、渋谷駅周辺の検索結果のリンクが出ている。
試しに「JR渋谷駅」をクリックしてみる。すると携帯用だけに
小さいサイズの地図が表示されている。

まず注目したのはこの地図のURLだ。次のようになっている

http://maps.google.com/mapdata?
Point=b&Point.latitude_e6=35658092
&Point.longitude_e6=139701518
&Point.iconid=15
&Point=e&latitude_e6=35658092
&longitude_e6=139701518
&zm=90
&w=250&h=125
&cc=&min_priority=2&client=internal-mobilefe


もう、この時点で赤字部分から攻めていけそうな予感をもつ。
案の定、赤字部分の数値を色々と変えてみると予想したとおりの
表示をしてくれる。

つまり、
Point.latitude_e6とPoint.longitude_e6はそれぞれ表示する
アイコンの緯度、経度を表す。ちなみ度(degree)形式で8桁を指定する。
上の例では35.658092 → 35658092にして指定している。

Point.iconidは表示するアイコンのID。
番号を変えることで表示するアイコンが変わる。

latitude_e6とlongitude_e6は地図を表示する際にどこを中心にするかを
緯度、経度で表している。こちらも同じく度形式で9桁指定する。
同じく例では139.701518 → 139701518にして指定している。
どちらの緯度・経度にしても桁が1桁でも少なかったり、
多かったりするとエラーになるので要注意。

zmはおそらくzoomの略だろう。数値を小さくすると10で最大ズームになる。

wは表示する幅、hは表示する高さを表している。

あとはcgiに組む込むことになる。
処理はまず、取得したGPS情報から必要な緯度、経度を度形式のままURLの
まずパラメータに代入して、imgタグによって地図を表示させるところから
試してみた。これは難なくクリア。むしろ、指定する緯度・経度の形式が
度形式であることを突き止めるのにだいぶ時間がかかってしまった。

あとは他のパラメータに値を代入させて、ズームアップしたり、
表示のサイズをユーザ操作によって変えることができれば、
EZwebのナビウォークにはだいぶ劣るが、GPS情報によって数字だけでなく、
地図で位置を確認することができる。
これもいろいろと試行錯誤したが、HTMLライクにinputタグを使うことで解決。
HTMLのタグと同じように、ユーザにテキストボックスに値を入力してもらい
「地図表示」ボタンが押されると入力した値がURLとともに渡されて、
地図を表示することができる。説明だけだとわかりにくいので、
ひとまずcgiのソースコードを晒しておく。
もしこのコードを使う場合、表示の都合で改行しているところがあるので
注意しておく。


#!/usr/local/bin/perl --

print "Content-type: text/html\n\n";

#ブラウザ情報取得

print "GPS情報<br>\n";
print "--------------------<br>";
print "$ENV{'HTTP_USER_AGENT'}<br>\n";
print "--------------------<br>";

my $agent = $ENV{'HTTP_USER_AGENT'};
my $addr = $ENV{'REMOTE_ADDR'};
my $addr2 = $ENV{'HTTP_X_FORWARDED_FOR'};

#GPS情報取得

my $str = $ENV{'QUERY_STRING'};

$str =~ s/&/<br>/g;

my @k = split(/<br>/, $str);

for(my $j=0; $j<=$#k; $j=$j+1)
{
my @k1 = split(/=/, $k[$j]);

$k[$j] = $k1[1];
}

#緯度・経度・時刻情報の整形

my @ido = split(/\./, $k[3]);

$ido[0] =~ s/%2b//g;

$k[3] = $ido[0]+$ido[1]/60+$ido[2]/3600+$ido[3]/360000;

my @keido = split(/\./, $k[4]);

$keido[0] =~ s/%2b//g;

$k[4] = $keido[0]+$keido[1]/60+$keido[2]/3600+$keido[3]/360000;

my $year = substr($k[6], 0, 4);
my $month = substr($k[6], 4, 2);
my $day = substr($k[6], 6, 2);
my $hour = substr($k[6], 8, 2);
my $min = substr($k[6], 10, 2);
my $sec = substr($k[6], 12, 2);

print "緯度・経度degree変換<br>\n";
print "$year年$month月$day日$hour時$min分$sec秒 
    緯度(degree変換):$k[3] 経度(degree変換):$k[4]<br>\n";


my $pido = int($k[3]*1000000);
my $pkeido = int($k[4]*1000000);


#ログファイルへの書き込み

open(FP ,"<location.txt") || die "not opened!!<br>\n";
close(FP);

if(open(FP ,">>location.txt"))
{
flock(FP, 2);

print FP "--------------------<br>\n";
print FP "$agent<br>\n";
print FP "REMOTE_ADDR:$addr<br>\n";
print FP "HTTP_X_FORWARDED_FOR:$addr2<br>\n";
print FP "--------------------<br>\n";
print FP "取得日時 経度(degree変換) 緯度(degree変換)<br>\n";
print FP "$year年$month月$day日$hour時$min分$sec秒 $k[4],$k[3]<br>\n";

flock(FP, 8);

close(FP);
}


print<<EOM;

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"
"http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">

<html>
<head>
<title>現在地周辺地図</title>
</head>

<body>

<wml>

<img alt="map" src="http://maps.google.com/mapdata?Point=b
&Point.latitude_e6=$pido&Point.longitude_e6=$pkeido
&Point.iconid=15&Point=e&latitude_e6=$pido
&longitude_e6=$pkeido&zm=90&w=300&h=300&cc=&min_priority=1
&image_format=3&client=internal-mobilefe" />

<form action="http://maps.google.com/mapdata" method="GET">
<input type="hidden" name="Point" value="1" />
<input type="hidden" name="Point.latitude_e6" value="$pido" />
<input type="hidden" name="Point.longitude_e6" value="$pkeido" />
<p>アイコン(15から指定)</p>
<input type="text" name="Point.iconid" value="15" format="5N" />
<input type="hidden" name="Point" value="e" />
<input type="hidden" name="latitude_e6" value="$pido" />
<input type="hidden" name="longitude_e6" value="$pkeido" />
<p>ズーム値(10:最大ズーム 大きい値ほど全域へ)</p>
<input type="text" name="zm" value="90" format="100N" />
<p>地図表示幅</p>
<input type="text" name="w" value="300" format="10N" />
<p>地図表示高さ</p>
<input type="text" name="h" value="300" format="10N" />
<input type="hidden" name="cc" value="" />
<input type="hidden" name="min_priority" value="1" />
<input type="hidden" name="image_format" value="3" />
<input type="hidden" name="client" value="internal-mobilefe" />
<input type="submit" value="地図表示"/>
</form>

</wml>

</body>

</html>

EOM


GPS情報の下に地図が表示され、そのしたに値を入力する
テキストボックスと「地図表示」ボタンが表示される。
このテキストボックスにそれぞれ値を入力して、「地図表示」を
押すとGET方式で送信するため、formタグのactionのURLの後ろに
?が付き、続けてパラーメータ=値&パラーメータ=値&パラーメータ=値
・・・の形でくっ付けて、それをURLとしてアクセスする。

つまり、コードにあるように
http://maps.google.com/mapdata?Point=b
&Point.latitude_e6=$pido&Point.longitude_e6=$pkeido
&Point.iconid=15&Point=e&latitude_e6=$pido
&longitude_e6=$pkeido&zm=90&w=300&h=300&cc=
&min_priority=1&image_format=3&client=internal-mobilefe

をURLとしてサーバに送るわけだ。

あとはPCのブラウザからできるようなマウスによる地図の移動
機能ができればなおいいが、もしできたとしても
マウスのようなスムーズな移動は無理だ。
「←」「→」「↑」「↓」のようなリンクを表示させて
そのリンクを踏むたびに地図の画像を表示する形式になる。

GPSを使っているだけに地図ではなく、ユーザーが移動すれば
この機能はなしということで(笑)

0 件のコメント: