File Coverage

blib/lib/Religion/Islam/Qibla.pm
Criterion Covered Total %
statement 12 66 18.1
branch 0 14 0.0
condition 0 9 0.0
subroutine 4 13 30.7
pod 0 9 0.0
total 16 111 14.4


line stmt bran cond sub pod time code
1             # Copyright Infomation
2             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3             # Author : Dr. Ahmed Amin Elsheshtawy, Ph.D.
4             # Website: http://www.mewsoft.com
5             # Email : support@mewsoft.com
6             # Copyrights (c) 2000-2015 Mewsoft Corporation. All rights reserved.
7             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8             package Religion::Islam::Qibla;
9              
10 1     1   17267 use Carp;
  1         2  
  1         74  
11 1     1   4 use strict;
  1         1  
  1         27  
12 1     1   3 use warnings;
  1         4  
  1         22  
13 1     1   523 use Math::Trig;
  1         15204  
  1         750  
14              
15             our $VERSION = '3.0';
16             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17             sub new {
18 0     0 0   my ($class, %args) = @_;
19 0           my $self = bless {}, $class;
20             # Default destination point is the Kabah Lat=21 Deg N, Long 40 Deg E
21 0 0         $self->{DestLat} = $args{DestLat}? $args{DestLat}: 21.423333; # 21.423333;
22 0 0         $self->{DestLong} = $args{DestLong}? $args{DestLong}: 39.823333; # 39.823333;
23 0           return $self;
24             }
25             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26             sub DestLat {
27 0     0 0   my ($self) = shift;
28 0 0         $self->{DestLat} = shift if @_;
29 0           return $self->{DestLat};
30             }
31             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32             sub DestLong {
33 0     0 0   my ($self) = shift;
34 0 0         $self->{DestLong} = shift if @_;
35 0           return $self->{DestLong};
36             }
37             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38             #Converting from Degrees, Minutes and Seconds to Decimal Degrees
39             sub DegreeToDecimal {
40 0     0 0   my ($self, $degrees, $minutes, $seconds) = @_;
41 0           return $degrees + ($minutes / 60) + ($seconds / 3600);
42             }
43             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44             #Converting from Decimal Degrees to Degrees, Minutes and Seconds
45             sub DecimalToDegree {
46 0     0 0   my ($self, $decimal_degree) = @_;
47 0           my ($degrees, $minutes, $seconds, $ff);
48            
49 0           $degrees = int($decimal_degree);
50 0           $ff = $decimal_degree - $degrees;
51 0           $minutes = int(60 * $ff);
52 0           $seconds = 60 * ((60 * $ff) - $minutes);
53 0           return ($degrees, $minutes, $seconds);
54             }
55             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56             # The shortest distance between points 1 and 2 on the earth's surface is
57             # d = arccos{cos(Dlat) - [1 - cos(Dlong)]cos(lat1)cos(lat2)}
58             # Dlat = lab - lat2
59             # Dlong = 10ng - long2
60             # lati, = latitude of point i
61             # longi, = longitude of point i
62              
63             #Conversion of grad to degrees is as follows:
64             #Grad=400-degrees/0.9 or Degrees=0.9x(400-Grad)
65              
66             #Latitude is determined by the earth's polar axis. Longitude is determined
67             #by the earth's rotation. If you can see the stars and have a sextant and
68             #a good clock set to Greenwich time, you can find your latitude and longitude.
69              
70             # one nautical mile equals to:
71             # 6076.10 feet
72             # 2027 yards
73             # 1.852 kilometers
74             # 1.151 statute mile
75              
76             # Calculates the distance between any two points on the Earth
77             sub GreatCircleDistance {
78 0     0 0   my ($self, $orig_lat , $dest_lat, $orig_long, $dest_long) = @_;
79 0           my ($d, $l1, $l2, $i1, $i2);
80            
81 0           $l1 = deg2rad($orig_lat);
82 0           $l2 = deg2rad($dest_lat);
83 0           $i1 = deg2rad($orig_long);
84 0           $i2 = deg2rad($dest_long);
85            
86 0           $d = acos(cos($l1 - $l2) - (1 - cos($i1 - $i2)) * cos($l1) * cos($l2));
87             # One degree of such an arc on the earth's surface is 60 international nautical miles NM
88 0           return rad2deg($d * 60);
89             }
90             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
91             #Calculates the direction from one point to another on the Earth
92             # a = arccos{[sin(lat2) - cos(d + lat1 - 1.5708)]/cos(lat1)/sin(d) + 1}
93             # Great Circle Bearing
94             sub GreatCircleDirection {
95 0     0 0   my ($self, $orig_lat, $dest_lat, $orig_long, $dest_long, $distance) = @_;
96 0           my ($a, $b, $d, $l1, $l2, $i1, $i2, $result, $dlong);
97            
98 0           $l1 = deg2rad($orig_lat);
99 0           $l2 = deg2rad($dest_lat);
100 0           $d = deg2rad($distance / 60); # divide by 60 for nautical miles NM to degree
101              
102 0           $i1 = deg2rad($orig_long);
103 0           $i2 = deg2rad($dest_long);
104 0           $dlong = $i1 - $i2;
105              
106 0           $a = sin($l2) - cos($d + $l1 - pi / 2);
107 0           $b = acos($a / (cos($l1) * sin($d)) + 1);
108 0 0 0       if ((abs($dlong) < pi && $dlong < 0) || (abs($dlong) > pi && $dlong > 0) ) {
      0        
      0        
109             #$b = (2 * pi) - $b;
110             }
111 0           $result = rad2deg($b);
112              
113 0           return $result;
114             }
115             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
116             #The Equivalent Earth redius is 6,378.14 Kilometers.
117             # Calculates the direction of the Qibla from any point on
118             # the Earth From North Clocklwise
119             sub QiblaDirection_ {
120 0     0 0   my ($self, $orig_lat, $orig_long) = @_;
121 0           my ($distance, $bearing);
122            
123             # Kabah Lat=21 Deg N, Long 40 Deg E
124 0           $distance = $self->GreatCircleDistance($orig_lat, $self->{DestLat}, $orig_long, $self->{DestLong});
125 0           $bearing = $self->GreatCircleDirection($orig_lat, $self->{DestLat}, $orig_long, $self->{DestLong}, $distance);
126              
127 0 0         if ($orig_lat > $self->{DestLat}) {
128             #$bearing += 180;
129             }
130              
131 0           return $bearing;
132             }
133             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
134             # Determine Qibla direction using basic spherical trigonometric formula
135             # Return float Qibla Direction from the north direction in degrees
136             sub QiblaDirection {
137            
138 0     0 0   my ($self, $orig_lat, $orig_long) = @_;
139              
140             #$orig_lat = 35.3833;
141             #$orig_long = 119.0166;
142             #Saudi Arabia, Riyadh Qibla = 245, Qibla Direction: 244.53 degees from true North, Distance from Ka'bah in Makkah: 790.18 km
143              
144 0           my $numerator = sin(deg2rad($self->{DestLong} - $orig_long));
145 0           my $denominator = (cos(deg2rad($orig_lat)) * tan(deg2rad($self->{DestLat}))) -
146             (sin(deg2rad($orig_lat)) * cos(deg2rad($self->{DestLong} - $orig_long)));
147              
148 0           my $q = rad2deg(atan($numerator / $denominator));
149              
150 0 0         if ($orig_lat > $self->{DestLat}) {
151 0           $q += 180;
152             }
153              
154 0           return $q;
155             }
156             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157             =cuts
158             public function getQibla ()
159             {
160             // The geographical coordinates of the Ka'ba
161             $K_latitude = 21.423333;
162             $K_longitude = 39.823333;
163            
164             $latitude = $this->lat;
165             $longitude = $this->long;
166              
167             $numerator = sin(deg2rad($K_longitude - $longitude));
168             $denominator = (cos(deg2rad($latitude)) * tan(deg2rad($K_latitude))) -
169             (sin(deg2rad($latitude))
170             * cos(deg2rad($K_longitude - $longitude)));
171              
172             $q = atan($numerator / $denominator);
173             $q = rad2deg($q);
174            
175             if ($this->lat > 21.423333) {
176             $q += 180;
177             }
178            
179             return $q;
180             }
181            
182             =cut
183              
184             1;
185              
186             =head1 NAME
187              
188             Religion::Islam::Qibla - Calculates the Muslim Qiblah Direction, Great Circle Distance, and Great Circle Direction
189              
190             =head1 SYNOPSIS
191              
192             use Religion::Islam::Qibla;
193             #create new object with default options, Destination point is Kabah Lat=21 Deg N, Long 40 Deg E
194             my $qibla = Religion::Islam::Qibla->new();
195            
196             # OR
197             #create new object and set your destination point Latitude and/or Longitude
198             my $qibla = Religion::Islam::Qibla->new(DestLat => 21, DestLong => 40);
199            
200             # Calculate the Qibla direction From North Clocklwise for Cairo : Lat=30.1, Long=31.3
201             my $Latitude = 30.1;
202             my $Longitude = 31.3;
203             my $QiblaDirection = $qibla->QiblaDirection($Latitude, $Longitude);
204             print "The Qibla Direction for $Latitude and $Longitude From North Clocklwise is: " . $QiblaDirection ."\n";
205            
206             # Calculates the distance between any two points on the Earth
207             my $orig_lat = 31; my $dest_lat = 21; my $orig_long = 31.3; $dest_long = 40;
208             my $distance = $qibla->GreatCircleDistance($orig_lat , $dest_lat, $orig_long, $dest_long);
209             print "The distance is: $distance \n";
210              
211             # Calculates the direction from one point to another on the Earth. Great Circle Bearing
212             my $direction = $qibla->GreatCircleDirection($orig_lat, $dest_lat, $orig_long, $dest_long, $distance);
213             print "The direction is: $direction \n";
214            
215             # You can get and set the distination point Latitude and Longitude
216             # $qibla->DestLat(21); # set distination Latitude
217             # $qibla->DestLong(40); # set distincatin Longitude
218             print "Destination Latitude:" . $qibla->DestLat();
219             print "Destination Longitude:" . $qibla->DestLong();
220              
221             =head1 DESCRIPTION
222              
223             This module calculates the Qibla direction where muslim prayers directs their face. It
224             also calculates and uses the Great Circle Distance and Great Circle Direction.
225              
226             =head1 SEE ALSO
227              
228             L
229             L
230             L
231             L
232              
233             =head1 AUTHOR
234              
235             Ahmed Amin Elsheshtawy,
236             Website: http://www.islamware.com http://www.mewsoft.com
237              
238             =head1 COPYRIGHT AND LICENSE
239              
240             Copyright (C) 2006-2015 by Ahmed Amin Elsheshtawy support@islamware.com, support@mewsoft.com
241             L L
242              
243             This library is free software; you can redistribute it and/or modify
244             it under the same terms as Perl itself.
245              
246             =cut