#!/usr/bin/perl -w ############################################################################### # THIS SOFTWARE IS FREE SOFTWARE! IT IS LICENCED UNDER THE GNU PUBLIC LICENCE # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### # (c) Hartmut Schimmel, 30.09.2007 # TODO: # - implement and test W-long and S-lati # - detect SRIFIII- and Nemerix data automatically # * kml and trackmaker support # * calulate step distance and total distance use strict; ( my $prg = $0 ) =~ s/^.*\/([^\/]+)$/$1/g; ############################################################################### # Usage ############################################################################### die < Currently the following output formates are supported: print - values on the screen, no file writing csv - comma separated value for Excel (exact as the original csv for applications which rely on this) ecsv - comma separated value for Excel, extension will be .csv too (fit better than csv into _e_nglish Excel settings) dcsv - semicolon separated values for Excel, extension will be .csv too (fit better than csv into german (_d_eutsche) Excel settings) track - Trackmaker format, extension will be .txt kml - GoogleEarth format Example: $prg csv iTu4l_Nemerix_20070410204511.dump or: $prg dcsv SortDB.sr This software is published under the GPL V2.0 EOF ############################################################################### # Parse command line ############################################################################### my $format = shift; my $srfile = shift; ( my $outfile = $srfile ) =~ s/\.\w+$/.$format/g; my $header; ############################################################################### # Write headers depending on format ############################################################################### if ( $format eq "csv" ) { $header = "Longitude,Latitude,Speed(kilometer),DD/MM/YY,HH:MM:SS," . "Distance(meter)\r\n"; } elsif ( $format eq "ecsv" ) { $outfile =~ s/\.ecsv$/.csv/g; $header = "Longitude,Latitude,Speed(kph),YYYY/MM/DD,HH:MM:SS," . "Distance(meter),\r\n"; } elsif ( $format eq "dcsv" ) { $outfile =~ s/\.dcsv$/.csv/g; $header = "Longitude;Latitude;Geschwindigkeit(kmh);DD/MM/YYYY;HH:MM:SS;" . "Strecke(Meter);\r\n"; } elsif ( $format eq "track" ) { $outfile =~ s/\.track$/.txt/g; $header = "blabla\r\n"; die "Format $format not __yet__ supported.\n"; } elsif ( $format eq "kml" ) { $header = "blabla\r\n"; die "Format $format not __yet__ supported.\n"; } elsif ( $format eq "txt" ) { die "Format $format not supported, did you mean \"track\" ?\n"; } elsif ( $format eq "print" ) { $header = "Longitude,Latitude,Speed(kph),DD/MM/YYYY,HH:MM:SS," . "Distance(meter)\r\n"; } else { die "Format $format not supported.\n"; } if ( $format eq "print" ) { print $header; } else { stat $outfile and die "$outfile already exists - Abort\n"; open OUTFILE, ">$outfile" or die $!; print OUTFILE $header; } ############################################################################### # Read sr-File ############################################################################### open SRFILE, "$srfile" or die $!; # each record is 16 byte long my $record; while( sysread( SRFILE, $_, 16) != 15 ) { # parse the record, this trick took me one whole day... my ($long, $lati, $year, $month, $day, $hour, $minute, $second, $speed, $e) = unpack( " V V C C C C C C C C", $_ ); # _Longitude_ _Latitude__ YY MM DD HH MM SS Spd # bf f3 b7 00 c1 df 02 03 07 09 1d 06 01 2a 00 ff # last if empty memory area found, detected by 0xFF last if $second eq 0xFF; # this should never happen die "Unexpected last byte in record no. $record, abort.\n" if $e ne 0xFF; # count the records readed $record++; # conversations $year += 2000; $speed = sprintf "%3d", $speed * 1.852; # convert speed from kt to kph # convert from degree.minutes to decimal degree $long = sprintf("%.6f", int($long/1000000) + ($long/1000000 - int($long/1000000)) * 100 / 60); $lati = sprintf("%.6f", int($lati/1000000) + ($lati/1000000 - int($lati/1000000)) * 100 / 60); # write out data depending on format if ( $format eq "print" ) { printf "%11.6f %11.6f %3d %02d/%02d/%04d %02d:%02d:%02d\n", $long, $lati, $speed, $day, $month, $year, $hour, $minute, $second; } elsif ( $format eq "csv" ) { printf OUTFILE "%.6f,%.6f,%d,%d/%d/%d,%d:%d:%d,??,\r\n", $long, $lati, $speed, $day, $month, $year, $hour, $minute, $second; } elsif ( $format eq "ecsv" ) { printf OUTFILE "%.6f,%.6f,%d,%04d/%02d/%02d,%02d:%02d:%02d,??,\r\n", $long, $lati, $speed, $year, $month, $day, $hour, $minute, $second; } elsif ( $format eq "dcsv" ) { ( my $long = $long ) =~ s/\./,/g; ( my $lati = $lati ) =~ s/\./,/g; printf OUTFILE "%s;%s;%d;%02d.%02d.%04d;%02d:%02d:%02d;??;\r\n", $long, $lati, $speed, $day, $month, $year, $hour, $minute, $second; } } close SRFILE; ############################################################################### # Write footers depending on format ############################################################################### my $total_distance = "TODO"; if ( $format eq "print" ) { print "Total distance : $total_distance Meter\r\n"; } else { if ( $format eq "csv" ) { print OUTFILE "Total distance : $total_distance Meter" . chr(0); } if ( $format eq "ecsv" ) { print OUTFILE "Total distance : $total_distance Meter\r\n"; } if ( $format eq "dcsv" ) { print OUTFILE "Gesamtstrecke : $total_distance Meter\r\n"; } close OUTFILE; print "Wrote $record records to $outfile\n"; } # all done exit 0;