nmea2xyzt Perl Script
#!/usr/bin/perl
# takes data logged with optional timestamp on each data string and
# produces an tab delimited xyzt file using lat/long for xy and meters
# for
# Ben Smith - S/V Mother of Perl, January 2006
#######################################################################
use strict;
use Getopt::Long;
use NMEAfields;
my $scan = 1; # scan each line for the begining of the NMEA string
my $I = NMEAfields->new(); # one one interpreter needed
my $line;
my $dataP;
my $lastLong = 0;
my $Long = 0;
my $lastLat = 0;
my $Lat = 0;
my $lastGPStime = 0;
my $GPStime = 0;
my $Depth;
my $timestamp = 0;
my $nmeastr = "";
our @zList = ();
our $useFeet;
our $Timestamp = undef;
our $Verbose = 0;
our $Debug = 0;
my $result = GetOptions("timestamp=i" => \$Timestamp, #numeric
"verbose" => \$Verbose,
"feet" => \$useFeet,
"debug" => \$Debug);
$|=1;
while($line = <>){
$line =~ s/^\s*//; # remove leading whitespace
$line =~ s/\s*$//; # remove trailing whitespace
next if $line =~ /^$/; # skip blank lines
print "\nProcessing line: \"$line\"\n" if $Verbose & 2;
my(@fields) = split(/\s+/,$line); # break out any leading fields
$nmeastr = pop(@fields) ; # the last field
if($Timestamp) {
$timestamp = $fields[$Timestamp];
}
if($dataP = $I->Interp($nmeastr)) { # get a data object
if($dataP->ElementCode eq 'RMC') {
# RMC contains a time and position in one string
$lastLong = $Long;
$Long = sprintf("%.6f",$dataP->{LongDecDeg});
$lastLat = $Lat;
$Lat = sprintf("%.6f",$dataP->{LatDecDeg});
$lastGPStime = $GPStime;
$GPStime = $dataP->UNIXtime;
if($lastLat && $lastLong && scalar @zList) {
my $items = scalar @zList;
# interpolate positions and times for each depth
for(my $n = 0; $n < $items; ++ $n) {
my $thisLat =
($n/$items) * ($Lat - $lastLat) + $lastLat;
my $thisLong =
($n/$items) * ($Long - $lastLong) + $lastLong;
my $thisGPStime =
($n/$items) * ($GPStime - $lastGPStime) + $lastGPStime;
if($Timestamp) {
print join("\t",$thisLong,$thisLat,
$zList[$n],$timestamp,"\n");
} else {
print join("\t",$thisLong,$thisLat,
$zList[$n],$thisGPStime,"\n");
}
}
}
@zList = ();
}elsif($dataP->{DBTmeters}) {
if($useFeet) {
$Depth = sprintf("%.2f",$dataP->{DBTmeters}*3.28084);
} else {
$Depth = sprintf("%.2f",$dataP->{DBTmeters});
}
push(@zList,$Depth);
}
}
}