NMEA-0183のパーサーが出来たよ。

ので、下記にソースを載せてみるテスト。
時間が無い(or歳を取った)ので実装はPerlで。時間があれば(or若ければ)、VC++&Win32APIで書いてバイナリを8KB以内に納めたいのだけど。(ぉぃ
動作確認環境(=開発環境)は、

といったところ。10/13時点でWindowsUpdate&VAIO Updateが最新の環境。
注意事項としては、予め「VAIOの設定」→「VAIO Location Searchの設定」→「位置情報取得のサービス」→「サービスを常駐する」をOFFにすること。COMポート番号はデバイスマネージャを見て、実行環境に合わせてください。
あと、Win32::APIがインストール済みじゃないと駄目だけど、おそらくStrawberry Perlに付いてくるハズ。Win32::SerialPortも必要。CPANで入れようとしたら、入らなくて手動で入れた(適当にファイルをコピー)気がする。なんか流行ってるっぽいので、Strawberry Perlにしたけど、ActivePerlでも動くハズ。
当然無保証。利用は自己責任で。チェックサムのチェックもしてません。(汗
サポートはたぶん、出来ないと思います。(笑
Windowsで動かしたけど、シリアルポートの記述とかをちょっと変えればLinuxとかでも動くハズ。あと、NMEA-0183形式のGPSならBluetooth GPSを含めて、たいてい動くハズ。BT-338が手元にあるから試してみようと思いつつ、暇無くてやってません。スイマセン。



use strict;
use Win32::SerialPort;

my $PortObj = new Win32::SerialPort("COM6") || die "Can't open COM6: $^E\n";
$PortObj->databits(8);
$PortObj->baudrate(9600);
$PortObj->parity("none");
$PortObj->stopbits(1);
$PortObj->handshake("none");
$PortObj->buffers(4096, 4096);
$PortObj->write_settings;

my $time; # 測位時刻(UTC)
my $lat; # 緯度
my $lon; # 経度
my $accu; # 0=受信不能/1=単独測位/2=DGPS
my $num_of_sat; # 受信衛星数
my $hdop; # HDOP(Horizontal Dilution of Precision)=水平精度劣化率
my $alt; # 平均海水面からの高度

my $stat; # A=有効/V=無効
my $date; # 日付(UTC)

my $direc; # 真北に対する進行方向
my $speed; # 対地速度(km/h)

my $pdop; # PDOP(Position Dilution of Precision)=位置精度劣化率
my $vdop; # VDOP(Vertical Dilution of Precision)=垂直精度劣化率

while (1) {

my $line;
do{
select(undef, undef, undef, 0.1);
$line = $PortObj->streamline;
} until(length($line) > 0);
# print $line . "\n";

my @param = split(/,/, $line);

if ($param[0] eq '$GPGGA') {
my $hour = substr($param[1], 0, 2);
my $min = substr($param[1], 2, 2);
my $sec = substr($param[1], 4, 2);
my $sec00 = substr($param[1], 7, 2);
$time = sprintf("%02d:%02d:%02d\.%d", $hour, $min, $sec, $sec00);

my $deg = substr($param[2], 0, 2);
$min = substr($param[2], 2, 9);
$lat = sprintf("%s%f", $param[3], $deg + $min / 60);

$deg = substr($param[4], 0, 3);
$min = substr($param[4], 3, 9);
$lon = sprintf("%s%f", $param[5], $deg + $min / 60);

$accu = $param[6];
$num_of_sat = $param[7];
$hdop = $param[8];
$alt = $param[9];
} elsif ($param[0] eq '$GPRMC') {
$stat = $param[2];

my $day = substr($param[9], 0, 2);
my $month = substr($param[9], 2, 2);
my $year = substr($param[9], 4, 2) + 2000;
$date = "$year/$month/$day";
} elsif ($param[0] eq '$GPVTG') {
$direc = $param[1];
$speed = $param[7];
} elsif ($param[0] eq '$GPGSA') {
$pdop = $param[15];
($vdop, my $csum) = split(/\*/, $param[17]);
}

print "${date}T${time}|${lat}|${lon}|${accu}|${pdop}|${hdop}|${vdop}|${alt}m|${stat}|${direc}|${speed}km/h\n";
}

$PortObj->close;
undef $PortObj;


しかし、何年かおきにプラットフォームを変えて、全く同じモノを何度も作り直している気がする。まるで賽の河原だ。(汗
昔、SONY IPS-5000(くらい)のときにパーサーを書いた時は、C++だった気がする。「ぶるじょわまっぷ」の時は、結局ありもののモジュールで済ませたから、パーサーは書かなくても良かったけど。しかし、Perl強力過ぎ。テキスト処理は最強。正規表現を駆使すれば、1行で書けるんじゃないかと思う。(うそ
ちなみに、CPANにも同じようなものはあったんだけど。なぜかうまく動かなかった。ので、作った方が早いなと思ったんだけど、本当にすぐ出来た。
さて、クライアント側はある程度出来たので、次はサーバ側だ〜