File Coverage

blib/lib/Geo/Coordinates/DecimalDegrees.pm
Criterion Covered Total %
statement 26 26 100.0
branch 2 2 100.0
condition n/a
subroutine 6 6 100.0
pod 4 4 100.0
total 38 38 100.0


line stmt bran cond sub pod time code
1             package Geo::Coordinates::DecimalDegrees;
2              
3             require Exporter;
4             require Carp;
5              
6             @ISA = qw(Exporter);
7              
8             @EXPORT = qw( decimal2dms decimal2dm dms2decimal dm2decimal
9             dec2dms dec2dm dms2dec dm2dec);
10              
11             $VERSION = '0.11';
12              
13 3     3   379457 use strict;
  3         17  
  3         151  
14 3     3   17 use warnings;
  3         6  
  3         1438  
15              
16             sub decimal2dms {
17 63     63 1 160 my ($decimal) = @_;
18              
19 63         149 my $sign = $decimal <=> 0;
20 63         148 my $degrees = int($decimal);
21              
22             # convert decimal part to minutes
23 63         183 my $dec_min = abs($decimal - $degrees) * 60;
24 63         118 my $minutes = int($dec_min);
25 63         114 my $seconds = ($dec_min - $minutes) * 60;
26              
27 63         378 return ($degrees, $minutes, $seconds, $sign);
28             }
29              
30             sub decimal2dm {
31 36     36 1 76 my ($decimal) = @_;
32              
33 36         103 my $sign = $decimal <=> 0;
34 36         61 my $degrees = int($decimal);
35 36         75 my $minutes = abs($decimal - $degrees) * 60;
36              
37 36         202 return ($degrees, $minutes, $sign);
38             }
39              
40             sub dms2decimal {
41 72     72 1 435062 my ($degrees, $minutes, $seconds) = @_;
42 72         95 my $decimal;
43              
44 72 100       131 if ($degrees >= 0) {
45 57         118 $decimal = $degrees + $minutes/60 + $seconds/3600;
46             } else {
47 15         36 $decimal = $degrees - $minutes/60 - $seconds/3600;
48             }
49              
50 72         219 return $decimal;
51             }
52              
53             sub dm2decimal {
54 18     18 1 32 my ($degrees, $minutes) = @_;
55              
56 18         31 return dms2decimal($degrees, $minutes, 0);
57             }
58              
59             *dec2dms = \&decimal2dms;
60             *dec2dm = \&decimal2dm;
61             *dms2dec = \&dms2decimal;
62             *dm2dec = \&dm2decimal;
63              
64             1;
65              
66             =head1 NAME
67              
68             Geo::Coordinates::DecimalDegrees - convert between degrees/minutes/seconds and decimal degrees
69              
70             =head1 SYNOPSIS
71              
72             use Geo::Coordinates::DecimalDegrees;
73             ($degrees, $minutes, $seconds, $sign) = decimal2dms($decimal_degrees);
74             ($degrees, $minutes, $seconds, $sign) = dec2dms($decimal_degrees);
75              
76             ($degrees, $minutes, $sign) = decimal2dm($decimal_degrees);
77             ($degrees, $minutes, $sign) = dec2dm($decimal_degrees);
78              
79             $decimal_degrees = dms2decimal($degrees, $minutes, $seconds);
80             $decimal_degrees = dms2dec($degrees, $minutes, $seconds);
81              
82             $decimal_degrees = dm2decimal($degrees, $minutes);
83             $decimal_degrees = dm2dec($degrees, $minutes);
84              
85             =head1 DESCRIPTION
86              
87             Latitudes and longitudes are most often presented in two common
88             formats: decimal degrees, and degrees, minutes and seconds. There are
89             60 minutes in a degree, and 60 seconds in a minute. In decimal
90             degrees, the minutes and seconds are presented as a fractional number
91             of degrees. For example, 1 degree 30 minutes is 1.5 degrees, and 30
92             minutes 45 seconds is 0.5125 degrees.
93              
94             This module provides functions for converting between these two
95             formats.
96              
97             =head1 FUNCTIONS
98              
99             This module provides the following functions, which are all exported
100             by default when you call C:
101              
102             =over 4
103              
104             =item decimal2dms($decimal_degrees)
105              
106             Converts a floating point number of degrees to the equivalent number
107             of degrees, minutes, and seconds, which are returned as a 3-element
108             list. Typically used as follows:
109              
110             ($degrees, $minutes, $seconds) = decimal2dms($decimal_degrees);
111              
112             If $decimal_degrees is negative, only $degrees will be negative.
113             $minutes and $seconds will always be positive.
114              
115             If $decimal_degrees is between 0 and -1, $degrees will be returned as
116             0. If you need to know the sign in these cases, you can use this
117             longer version, where $sign is 1, 0, or -1 depending on whether
118             $decimal_degrees is positive, 0, or negative:
119              
120             ($degrees, $minutes, $seconds, $sign) = decimal2dms($decimal_degrees);
121              
122             =item dec2dms($decimal_degrees)
123              
124             An alias for decimal2dms().
125              
126             =item decimal2dm($decimal_degrees)
127              
128             Converts a floating point number of degrees to the equivalent number
129             of degrees and minutes which are returned as a 2-element list.
130             Typically used as follows:
131              
132             ($degrees, $minutes) = decimal2dm($decimal_degrees);
133              
134             If $decimal_degrees is negative, only $degrees will be negative.
135             $minutes will always be positive.
136              
137             If $decimal_degrees is between 0 and -1, $degrees will be returned as
138             0. If you need to know the sign in these cases, you can use this
139             longer version, where $sign is 1, 0, or -1 depending on whether
140             $decimal_degrees is positive, 0, or negative:
141              
142             ($degrees, $minutes, $sign) = decimal2dm($decimal_degrees);
143              
144             =item dec2dm($decimal_degrees)
145              
146             An alias for decimal2dm().
147              
148             =item dms2decimal($degrees, $minutes, $seconds)
149              
150             Converts degrees, minutes, and seconds to the equivalent number of
151             decimal degrees:
152              
153             $decimal_degrees = dms2decimal($degrees, $minutes, $seconds);
154              
155             If $degrees is negative, then $decimal_degrees will also be negative.
156              
157             =item dms2dec($degrees, $minutes, $seconds)
158              
159             An alias for dms2decimal().
160              
161             =item dm2decimal($degrees, $minutes)
162              
163             Converts degrees and minutes to the equivalent number of
164             decimal degrees:
165              
166             $decimal_degrees = dm2decimal($degrees, $minutes);
167              
168             If $degrees is negative, then $decimal_degrees will also be negative.
169              
170             =item dm2dec($degrees, $minutes)
171              
172             An alias for dm2decimal().
173              
174             =back
175              
176             =head1 CAVEATS
177              
178             The functions don't do any sanity checks on their arguments. If you
179             have a good reason to convert 61 minutes -101 seconds to decimal, go
180             right ahead.
181              
182             =head1 AUTHOR
183              
184             Walt Mankowski, Ewaltman@pobox.comE
185              
186             =head1 COPYRIGHT AND LICENSE
187              
188             Copyright 2003-2024 by Walt Mankowski
189              
190             This library is free software; you can redistribute it and/or modify
191             it under the same terms as Perl itself.
192              
193             =head1 THANKS
194              
195             Thanks to Andy Lester for telling me about pod.t
196              
197             Thanks to Paulie Pena IV for pointing out that I could remove a
198             division in decimal2dms().
199              
200             Thanks to Tim Flohrer for reporting the bug in decimal2dms() and
201             decimal2dm() when $decimal_degrees is between 0 and -1.
202              
203             =cut