File Coverage

blib/lib/Geo/Coordinates/Transform.pm
Criterion Covered Total %
statement 73 79 92.4
branch 14 18 77.7
condition 4 9 44.4
subroutine 13 13 100.0
pod 0 1 0.0
total 104 120 86.6


line stmt bran cond sub pod time code
1             package Geo::Coordinates::Transform;
2             #
3             # Troxel
4             # Thu Apr 1 10:31:35 2010
5             #
6             # Geo::Coordinates::Transform - Transform to/from various lat/long formats in a list oriented way.
7             #
8              
9 1     1   23179 use strict;
  1         2  
  1         35  
10 1     1   5 use warnings;
  1         2  
  1         28  
11 1     1   923 use diagnostics;
  1         221355  
  1         9  
12 1     1   507 use Exporter;
  1         2  
  1         46  
13 1     1   4 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  1         2  
  1         75  
14              
15 1     1   1039 use Data::Dumper;
  1         9023  
  1         63  
16              
17 1     1   7 use vars qw($AUTOLOAD);
  1         2  
  1         268  
18              
19             $VERSION = '0.10';
20             @ISA = qw(Exporter);
21             @EXPORT = ();
22             @EXPORT_OK = ();
23            
24             sub new
25             {
26 1     1 0 21 my $caller = shift;
27              
28             # In case someone wants to sub-class
29 1         3 my $caller_is_obj = ref($caller);
30 1   33     8 my $class = $caller_is_obj || $caller;
31              
32             # Passing reference or hash
33 1         2 my %arg_hsh;
34 1 50       6 if ( ref($_[0]) eq "HASH" ) { %arg_hsh = %{ shift @_ } }
  0         0  
  0         0  
35 1         4 else { %arg_hsh = @_ }
36              
37             # The object data structure
38 1   50     20 my $self = bless {
      50        
      50        
39             'dd_fmt' => $arg_hsh{dd_fmt} || '%3.7f',
40             'dm_fmt' => $arg_hsh{dm_fmt} || '%3.5f',
41             'ds_fmt' => $arg_hsh{ds_fmt} || '%3.5f',
42             }, $class;
43            
44 1         4 return $self;
45             }
46              
47             # - - - - - - - - - - - - - - - - - - - - - - - - - -
48             # Use Autoload to wrap a common loop and validation
49             # around input for the three transform functoins.
50             # - - - - - - - - - - - - - - - - - - - - - - - - - -
51             sub AUTOLOAD
52             {
53 5     5   2924 my $self = shift @_;
54 5         9 my $lst_ref = shift @_;
55              
56 5         26 my ($func_ptr) = $AUTOLOAD =~ /.*::(.*)$/;
57 5         11 $func_ptr = "_$func_ptr";
58              
59             # Act on only on resident functions
60 5 50       9 unless( grep { $_ eq $func_ptr } qw( _cnv_to_dd _cnv_to_ddm _cnv_to_dms ) ) { return }
  15         39  
  0         0  
61              
62             # Validate input
63 5 50       16 if ( ref $lst_ref ne 'ARRAY' ) { die "Array reference is expected as input" }
  0         0  
64            
65 5         8 my @ll_out_lst;
66 5         6 foreach my $ll ( @{$lst_ref} )
  5         11  
67             {
68 40 50       128 if ( $ll =~ /([^-+\s\d\.]+)/ )
69             {
70 0         0 push @ll_out_lst, 'NaN';
71 0         0 warn "Illegal char in $ll";
72             }
73             else
74             {
75 1     1   8 no strict 'refs';
  1         2  
  1         524  
76 40         98 push @ll_out_lst, $self->${func_ptr}($ll);
77             }
78             }
79            
80 5         21 return \@ll_out_lst;
81             }
82              
83             # - - - - - - - -
84             sub _cnv_to_ddm
85             {
86 8     8   12 my $self = shift @_;
87 8         11 my $in = shift @_;
88            
89 8         20 $in = $self->_cnv_to_dd($in);
90            
91 8         17 my $deg = int($in);
92 8         15 my $dm = abs($in - $deg) * 60;
93            
94 8         58 return sprintf("%d $self->{'dm_fmt'}",$deg, $dm);
95             }
96              
97             # - - - - - - - -
98             sub _cnv_to_dms
99             {
100 8     8   32 my $self = shift @_;
101 8         9 my $in = shift @_;
102            
103 8         16 $in = $self->_cnv_to_dd($in);
104            
105 8         13 my $deg = int($in);
106 8         14 my $dm = abs($in - $deg) * 60;
107            
108 8         10 my $mm = int($dm);
109 8         14 my $ss = abs($mm - $dm) * 60;
110            
111 8         52 return sprintf("%d %d $self->{'ds_fmt'}",$deg, $mm, $ss);
112             }
113              
114             # - - - - - - - -
115             sub _cnv_to_dd
116             {
117 40     40   51 my $self = shift @_;
118 40         50 my $in = shift @_;
119            
120 40         41 my $sign;
121 40 100       155 if ($in =~ s/([-]+)//) { $sign = $1; }
  20         44  
122              
123 40         55 my $dd = $in;
124 40 100       218 if ( $in =~ /([\d+-]+)\s+(\d+)\s+([\d\.]+)/ ) # -dd dd dd
    100          
125             {
126 20         66 $dd = $1 + $2/60 + $3/3600;
127             }
128             elsif ( $in =~ /([\d+-]+)\s+(\d+[\d\.]+)/ ) # -dd dd.ddd
129             {
130 14         47 $dd = $1 + $2/60;
131             }
132            
133 40 100       81 if ($sign ) { $dd = -1 * $dd }
  20         32  
134 40 100       395 if ( (caller(1))[3] !~ /_cnv_to/ ) { $dd = sprintf("$self->{'dd_fmt'}",$dd);}
  24         120  
135            
136 40         132 return $dd;
137             }
138              
139              
140             1;
141              
142             __END__