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