File Coverage

blib/lib/Religion/Islam/Qibla.pm
Criterion Covered Total %
statement 18 65 27.6
branch 0 10 0.0
condition 0 3 0.0
subroutine 6 15 40.0
pod 0 9 0.0
total 24 102 23.5


line stmt bran cond sub pod time code
1             #=Copyright Infomation
2             #==========================================================
3             #Module Name : Religion::Islam::Qibla
4             #Program Author : Dr. Ahmed Amin Elsheshtawy, Ph.D. Physics, E.E.
5             #Home Page : http://www.islamware.com, http://www.mewsoft.com
6             #Contact Email : support@islamware.com, support@mewsoft.com
7             #Copyrights © 2006-2013 IslamWare. All rights reserved.
8             #==========================================================
9             package Religion::Islam::Qibla;
10              
11 1     1   21887 use Carp;
  1         3  
  1         93  
12 1     1   6 use strict;
  1         1  
  1         36  
13 1     1   5 use warnings;
  1         5  
  1         86  
14              
15             our $VERSION = '2.0';
16              
17 1     1   5 use constant PI => 4 * atan2(1, 1); #3.1415926535897932 PI=22/7, Pi = Atn(1) * 4
  1         2  
  1         115  
18 1     1   5 use constant DtoR => PI / 180; # Degree to Radians
  1         1  
  1         43  
19 1     1   5 use constant RtoD => 180 / PI; # Radians to Degrees
  1         1  
  1         744  
20             #==========================================================
21             #==========================================================
22             sub new {
23 0     0 0   my ($class, %args) = @_;
24            
25 0           my $self = bless {}, $class;
26             # Default destination point is the Kabah Lat=21 Deg N, Long 40 Deg E
27 0 0         $self->{DestLat} = $args{DestLat}? $args{DestLat}: 21;
28 0 0         $self->{DestLong} = $args{DestLong}? $args{DestLong}: 40;
29 0           return $self;
30             }
31             #==========================================================
32             sub DestLat {
33 0     0 0   my ($self) = shift;
34 0 0         $self->{DestLat} = shift if @_;
35 0           return $self->{DestLat};
36             }
37             #==========================================================
38             sub DestLong {
39 0     0 0   my ($self) = shift;
40 0 0         $self->{DestLong} = shift if @_;
41 0           return $self->{DestLong};
42             }
43             #==========================================================
44             #Inverse Cosine, ArcCos
45             sub acos {
46 0     0 0   my ($self, $x) = @_;
47 0 0 0       return ($x<-1 or $x>1) ? undef : (atan2(sqrt(1-$x*$x),$x) );
48             }
49             #==========================================================
50             #Converting from Degrees, Minutes and Seconds to Decimal Degrees
51             sub DegreeToDecimal {
52 0     0 0   my ($self, $degrees, $minutes, $seconds) = @_;
53 0           return $degrees + ($minutes / 60) + ($seconds / 3600);
54             }
55             #==========================================================
56             #Converting from Decimal Degrees to Degrees, Minutes and Seconds
57             sub DecimalToDegree {
58 0     0 0   my ($self, $decimal_degree) = @_;
59 0           my ($degrees, $minutes, $seconds, $ff);
60            
61 0           $degrees = int($decimal_degree);
62 0           $ff = $decimal_degree - $degrees;
63 0           $minutes = int(60 * $ff);
64 0           $seconds = 60 * ((60 * $ff) - $minutes);
65 0           return ($degrees, $minutes, $seconds);
66             }
67             #==========================================================
68             # The shortest distance between points 1 and 2 on the earth's surface is
69             # d = arccos{cos(Dlat) - [1 - cos(Dlong)]cos(lat1)cos(lat2)}
70             # Dlat = lab - lat2
71             # Dlong = 10ng• - long2
72             # lati, = latitude of point i
73             # longi, = longitude of point i
74              
75             #Conversion of grad to degrees is as follows:
76             #Grad=400-degrees/0.9 or Degrees=0.9x(400-Grad)
77              
78             #Latitude is determined by the earth's polar axis. Longitude is determined
79             #by the earth's rotation. If you can see the stars and have a sextant and
80             #a good clock set to Greenwich time, you can find your latitude and longitude.
81              
82             # one nautical mile equals to:
83             # 6076.10 feet
84             # 2027 yards
85             # 1.852 kilometers
86             # 1.151 statute mile
87              
88             # Calculates the distance between any two points on the Earth
89             sub GreatCircleDistance {
90 0     0 0   my ($self, $orig_lat , $dest_lat, $orig_long, $dest_long) = @_;
91 0           my ($d, $l1, $l2, $i1, $i2);
92            
93 0           $l1 = $orig_lat * DtoR;
94 0           $l2 = $dest_lat * DtoR;
95 0           $i1 = $orig_long * DtoR;
96 0           $i2 = $dest_long * DtoR;
97            
98 0           $d = $self->acos(cos($l1 - $l2) - (1 - cos($i1 - $i2)) * cos($l1) * cos($l2));
99             # One degree of such an arc on the earth's surface is 60 international nautical miles NM
100 0           return $d * 60 * RtoD;
101             }
102             #==========================================================
103             #Calculates the direction from one point to another on the Earth
104             # a = arccos{[sin(lat2) - cos(d + lat1 - 1.5708)]/cos(lat1)/sin(d) + 1}
105             # Great Circle Bearing
106             sub GreatCircleDirection {
107 0     0 0   my ($self, $orig_lat, $dest_lat, $orig_long, $dest_long, $distance) = @_;
108 0           my ($a, $b, $d, $l1, $l2, $i1, $i2, $result, $dlong);
109            
110 0           $l1 = $orig_lat * DtoR;
111 0           $l2 = $dest_lat * DtoR;
112 0           $d = ($distance / 60) * DtoR; # divide by 60 for nautical miles NM to degree
113              
114 0           $i1 = $orig_long * DtoR;
115 0           $i2 = $dest_long * DtoR;
116 0           $dlong = $i1 - $i2;
117              
118 0           $a = sin($l2) - cos($d + $l1 - PI / 2);
119 0           $b = $self->acos($a / (cos($l1) * sin($d)) + 1);
120              
121             #If (Abs(Dlong) < pi And Dlong < 0) Or (Abs(Dlong) > pi And Dlong > 0) Then
122             # Result = (2 * pi) - B
123             #Else
124             # Result = B
125             #End If
126              
127 0           $result = $b;
128 0           return $result * RtoD;
129             }
130             #==========================================================
131             #The Equivalent Earth redius is 6,378.14 Kilometers.
132             # Calculates the direction of the Qibla from any point on
133             # the Earth From North Clocklwise
134             sub QiblaDirection {
135 0     0 0   my ($self, $orig_lat, $orig_long) = @_;
136 0           my ($distance, $bearing);
137            
138             # Kabah Lat=21 Deg N, Long 40 Deg E
139 0           $distance = $self->GreatCircleDistance($orig_lat, $self->{DestLat}, $orig_long, $self->{DestLong});
140 0           $bearing = $self->GreatCircleDirection($orig_lat, $self->{DestLat}, $orig_long, $self->{DestLong}, $distance);
141 0           return $bearing;
142             }
143             #==========================================================
144             #==========================================================
145              
146             1;
147              
148             =head1 NAME
149              
150             Religion::Islam::Qibla - Calculates the Muslim Qiblah Direction, Great Circle Distance, and Great Circle Direction
151              
152             =head1 SYNOPSIS
153              
154             use Religion::Islam::Qibla;
155             #create new object with default options, Destination point is Kabah Lat=21 Deg N, Long 40 Deg E
156             my $qibla = Religion::Islam::Qibla->new();
157            
158             # OR
159             #create new object and set your destination point Latitude and/or Longitude
160             my $qibla = Religion::Islam::Qibla->new(DestLat => 21, DestLong => 40);
161            
162             # Calculate the Qibla direction From North Clocklwise for Cairo : Lat=30.1, Long=31.3
163             my $Latitude = 30.1;
164             my $Longitude = 31.3;
165             my $QiblaDirection = $qibla->QiblaDirection($Latitude, $Longitude);
166             print "The Qibla Direction for $Latitude and $Longitude From North Clocklwise is: " . $QiblaDirection ."\n";
167            
168             # Calculates the distance between any two points on the Earth
169             my $orig_lat = 31; my $dest_lat = 21; my $orig_long = 31.3; $dest_long = 40;
170             my $distance = $qibla->GreatCircleDistance($orig_lat , $dest_lat, $orig_long, $dest_long);
171             print "The distance is: $distance \n";
172              
173             # Calculates the direction from one point to another on the Earth. Great Circle Bearing
174             my $direction = $qibla->GreatCircleDirection($orig_lat, $dest_lat, $orig_long, $dest_long, $distance);
175             print "The direction is: $direction \n";
176            
177             # You can get and set the distination point Latitude and Longitude
178             # $qibla->DestLat(21); # set distination Latitude
179             # $qibla->DestLong(40); # set distincatin Longitude
180             print "Destination Latitude:" . $qibla->DestLat();
181             print "Destination Longitude:" . $qibla->DestLong();
182              
183             =head1 DESCRIPTION
184              
185             This module calculates the Qibla direction where muslim prayers directs their face. It
186             also calculates and uses the Great Circle Distance and Great Circle Direction.
187              
188             =head1 SEE ALSO
189              
190             L
191             L
192             L
193             L
194              
195             =head1 AUTHOR
196              
197             Ahmed Amin Elsheshtawy,
198             Website: http://www.islamware.com http://www.mewsoft.com
199              
200             =head1 COPYRIGHT AND LICENSE
201              
202             Copyright (C) 2006-2013 by Ahmed Amin Elsheshtawy support@islamware.com, support@mewsoft.com
203             L L
204              
205             This library is free software; you can redistribute it and/or modify
206             it under the same terms as Perl itself.
207              
208             =cut