File Coverage

blib/lib/GPS/NMEA.pm
Criterion Covered Total %
statement 60 72 83.3
branch 8 16 50.0
condition 1 2 50.0
subroutine 12 14 85.7
pod 0 7 0.0
total 81 111 72.9


line stmt bran cond sub pod time code
1             # Copyright (c) 1999-2000 João Pedro Gonçalves .
2             #All rights reserved. This program is free software;
3             #you can redistribute it and/or modify it under the same terms as Perl itself.
4              
5             package GPS::NMEA;
6              
7 2     2   2388 use GPS::Base ();
  2         3  
  2         43  
8 2     2   382 use GPS::Serial ();
  2         4  
  2         38  
9 2     2   1037 use GPS::NMEA::Handler ();
  2         5  
  2         56  
10              
11 2     2   12 use strict;
  2         3  
  2         49  
12 2     2   9 use Carp;
  2         6  
  2         126  
13 2     2   11 use vars qw($VERSION @ISA);
  2         4  
  2         163  
14              
15             require Exporter;
16              
17             @ISA = qw(GPS::Base GPS::Serial GPS::NMEA::Handler);
18              
19             $VERSION = sprintf("%d.%02d", q$Revision: 1.11 $ =~ /(\d+)\.(\d+)/);
20              
21 2     2   26 use FileHandle;
  2         2  
  2         6  
22              
23             sub new {
24 3     3 0 1988 my $class = shift;
25 3         9 my %param = @_;
26 3   50     17 $param{'Protocol'} ||= 'NMEA';
27              
28 3         18 my $self = $class->SUPER::common_new(%param);
29 3         4 bless $self, $class;
30              
31 3         8 $self;
32             }
33              
34             sub parse {
35 14     14 0 36 my $self = shift;
36 14         58 my $line = $self->_readline; #from GPS::Serial
37              
38 14         32 my ($csum,$cmd,$short_cmd);
39              
40             #remove trailing chars
41 14         62 chomp($line);$line =~ s/\r//g;
  14         115  
42              
43             #Test checksum
44 14 50       235 if ($line =~ s/\*(\w\w)$//) {
45 14         69 $csum = $1;
46 14 50       82 return $self->parse(@_) unless $csum eq $self->checksum($line);
47             }
48              
49 14         133 $cmd = (split ',',$line)[0];
50 14         97 ($short_cmd = $cmd) =~ s/^\$//;
51              
52 14 50       72 print "COMMAND: $short_cmd ($line)\n" if $self->verbose;
53 14 50       460 if ($self->can($short_cmd)) {
    0          
54 14         91 $self->$short_cmd($line);
55             } elsif ($self->verbose) {
56 0         0 print "Can't handle $short_cmd\n";
57             }
58 14         79 $short_cmd;
59             }
60              
61              
62             sub get_position {
63             #($latsign,$lat,$lonsign,$lon)
64 2     2 0 1815 my $self = shift;
65              
66 2         7 until ($self->parse eq 'GPRMC') {
67 12         57 1;
68             }
69             ; #Recommended minimum specific
70 2         7 my $d = $self->{NMEADATA};
71             return ($d->{lat_NS},
72             $self->parse_ddmm_coords($d->{lat_ddmm}),
73             $d->{lon_EW},
74 2         49 $self->parse_ddmm_coords($d->{lon_ddmm}));
75             }
76              
77             sub get_altitude {
78 0     0 0 0 my $self = shift;
79 0         0 until ($self->parse eq 'PGRMZ') {
80 0         0 1;
81             }
82             ; #Altitude
83 0         0 my $d = $self->{NMEADATA};
84 0         0 return ($d->{alt}/0.3048); #Metric
85             }
86              
87             sub parse_ddmm_coords {
88 4     4 0 11 my $self = shift;
89 4         8 $_ = shift;
90 4         4 my $deg;
91 4         16 my ($dm,$sec) = split(/\./);
92              
93 4 100       15 if (length($dm) == 4) { #Lat (ddmm)
    50          
94 2         7 $deg = substr($dm,0,2,'');
95             } elsif (length($dm) == 5) { #Lon (dddmm)
96 2         5 $deg = substr($dm,0,3,'');
97              
98             } else {
99 0         0 carp "Invalid coords\n";
100             }
101              
102 4         21 $deg = sprintf("%d",$deg);
103 4         27 return "$deg.$dm$sec";
104             }
105              
106              
107              
108             sub nmea_data_dump {
109             #dumps data received
110 0     0 0 0 my $self = shift;
111 0         0 my $d = $self->{NMEADATA};
112 0         0 print map {"$_ => $$d{$_}\n"} sort keys %{$self->{NMEADATA}};
  0         0  
  0         0  
113             }
114              
115             # Calculate the checksum
116             #
117             sub checksum {
118 14     14 0 30 my ($self,$line) = @_;
119 14         30 my $csum = 0;
120 14         422 $csum ^= unpack("C",(substr($line,$_,1))) for(1..length($line)-1);
121              
122 14 50       87 print "Checksum: $csum\n" if $self->verbose;
123 14         280 return (sprintf("%2.2X",$csum));
124             }
125              
126              
127              
128             1;
129             __END__