# -*- perl -*- # # $Id: MPS.pm,v 1.7 2005/06/06 22:19:25 eserte Exp $ # Author: Slaven Rezic # # Copyright (C) 2003,2005 Slaven Rezic. All rights reserved. # This package is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # # Mail: slaven@rezic.de # WWW: http://www.rezic.de/eserte/ # package GPS::MPS; use strict; use vars qw($VERSION $DEBUG); $VERSION = sprintf("%d.%02d", q$Revision: 1.7 $ =~ /(\d+)\.(\d+)/); use constant SEEK_CUR => 1; # no Fcntl for 5.005 compatibility use vars qw($magic); $magic = qr{^MsRc[df]\0}; #$DEBUG=100;#XXXX sub check { my $self = shift; my $file = shift; my(%args) = @_; open(F, $file) or return 0; read(F, my $buf, 6); return 0 if ($buf !~ $magic); 1; } sub convert_to_route { my($self, $file, %args) = @_; require GPS::GpsmanData; require File::Temp; my($fh,$tmpfile) = File::Temp::tempfile(UNLINK => 1, SUFFIX => ".trk"); open(INFH, $file) or die "Can't read $file: $!"; binmode INFH; print $fh $self->convert_to_gpsman(\*INFH); close $fh; my @res = GPS::GpsmanMultiData->convert_to_route($tmpfile, %args); unlink $tmpfile; @res; } sub convert_to_gpsman { my $self = shift; my $fh = shift; my $out = <\n" if $DEBUG; $buf = substr($buf, length($name)); # skip name $buf = substr($buf, 12*2+($version>=2?1:0)); # skip 00 and ff my $coords = substr($buf, 0, 16); my @c = unpack("V*", $coords); my $lat = semicirc_deg($c[0]); my $long = semicirc_deg($c[1]); if (!defined $last_type || $last_type ne 'W') { $out .= "!W:\n"; $last_type = 'W'; } $out .= uc($name) . "\t\tN$lat\tE$long\n"; if (substr($buf, 17) !~ /^\0/) { warn "Comment: " . substr($buf, 17) if $DEBUG; } } elsif ($type eq 'T') { my $dist = 0; my($name) = substr($buf, 1) =~ /^([^\0]+)/; warn "Track $name\n" if $DEBUG; $out .= "!T:\t$name\n"; $last_type = 'T'; $buf = substr($buf, length($name)); my($lastx,$lasty); my $reclen = $version <= 2 ? 31 : 24; #XXX del # for (0..$reclen) { # my$rec=substr($buf,$_,$reclen); # my @f = unpack("V*", substr($rec, -5*4));#-5 # #warn join(", ", @f),"\n" if $DEBUG; # my $lat = semicirc_deg($f[0]); # my $long = semicirc_deg($f[1]); # warn "$lat $long\n"; # } while($buf =~ /(.{$reclen})/gs) { my $rec = $1; #warn $rec if $DEBUG; my @f = unpack("V*", $version <= 2 ? substr($rec, -5*4) : substr($rec, 11)); #warn join(", ", @f),"\n" if $DEBUG; my $lat = semicirc_deg($f[0]); my $long = semicirc_deg($f[1]); #XXX del: warn "$lat/$long"; $out .= "\t31-Dec-1989 01:00:00\tN$lat\tE$long\t0.0\n"; if (0) { #warn join(", ", unpack("c*", pack("V", $f[1]))); my @h = unpack("v*", pack("V", $f[-2])); $h[1]-=16384; # XXX wahrscheinlich height warn join(", ", @h); #warn scalar localtime($f[-1]-1040684395); if (defined $lastx) { $dist += sqrt(sqr($lastx-$f[0])+ sqr($lasty-$f[1])); } ($lastx,$lasty) = @f[0,1]; } } # warn "Dist: $dist"; } else { warn "Unhandled type $type"; } } $out; } sub semicirc_deg { return shift() * (180/2**31); } sub deg_semicirc { return shift() * (2**31/180); } sub strip0 { $_[0] =~ s/\0+// } # REPO BEGIN # REPO NAME sqr /home/e/eserte/src/repository # REPO MD5 846375a266b4452c6e0513991773b211 sub sqr { $_[0] * $_[0] } # REPO END 1; __END__