/[drupal]/contributions/modules/location/earth.inc
ViewVC logotype

Contents of /contributions/modules/location/earth.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.10 - (show annotations) (download) (as text)
Tue May 20 22:55:25 2008 UTC (18 months, 1 week ago) by bdragon
Branch: MAIN
CVS Tags: DRUPAL-5--3-0-RC2, DRUPAL-5--3-0-RC1, DRUPAL-5--3-0-test2, DRUPAL-5--3-0-test3, DRUPAL-5--3-0-test1, DRUPAL-5--3-0, DRUPAL-5--3-0-UNSTABLE4, DRUPAL-6--3-0, DRUPAL-6--3-1-RC1, DRUPAL-5--3-1-RC1, DRUPAL-6--3-0-test3, DRUPAL-6--3-0-UNSTABLE4, DRUPAL-6--3-0-RC2, DRUPAL-6--3-0-RC1, HEAD
Branch point for: DRUPAL-6--3, DRUPAL-5--3
Changes since 1.9: +9 -1 lines
File MIME type: text/x-php
Talked with ankur today, apparently earth.inc is indeed licenced under the GPL.
1 <?php
2 // $Id: earth.inc,v 1.9 2008/01/24 09:29:47 bdragon Exp $
3
4 /**
5 * License clarification:
6 *
7 * On Feb 13, 2005, in message <Pine.LNX.4.58.0502131827510.5072@server1.LFW.org>,
8 * the creator of these routines, Ka-Ping Yee, authorized these routines to be
9 * distributed under the GPL.
10 */
11
12 /**
13 * @file
14 * Trigonometry for calculating geographical distances.
15 * All function arguments and return values measure distances in metres
16 * and angles in degrees. The ellipsoid model is from the WGS-84 datum.
17 * Ka-Ping Yee, 2003-08-11
18 */
19
20 //$earth_radius_semimajor = 6378137.0;
21 //$earth_flattening = 1/298.257223563;
22 //$earth_radius_semiminor = $earth_radius_semimajor * (1 - $earth_flattening);
23 //$earth_eccentricity_sq = 2*$earth_flattening - pow($earth_flattening, 2);
24
25 // I don't know what's up: PHP is hating on my global variables (commented out above),
26 // so I have to write functions that return them! (-Ankur)
27 // Commenting out the global variables above and replacing them with functions that
28 // return the same values is the only thing I changed since, for some reason, my
29 // PHP wasn't acknowledging these global variables.
30 // This library is an original implementation of UCB CS graduate student, Ka-Ping Yee (http://www.zesty.ca).
31
32 function earth_radius_semimajor() {
33 return 6378137.0;
34 }
35
36 function earth_flattening() {
37 return (1/298.257223563);
38 }
39
40 function earth_radius_semiminor() {
41 return (earth_radius_semimajor() * (1 - earth_flattening()));
42 }
43
44 function earth_eccentricity_sq() {
45 return (2*earth_flattening() - pow(earth_flattening(), 2));
46 }
47
48 // Latitudes in all of U. S.: from -7.2 (American Samoa) to 70.5 (Alaska).
49 // Latitudes in continental U. S.: from 24.6 (Florida) to 49.0 (Washington).
50 // Average latitude of all U. S. zipcodes: 37.9.
51
52 function earth_radius($latitude=37.9) {
53 //global $earth_radius_semimajor, $earth_radius_semiminor;
54 // Estimate the Earth's radius at a given latitude.
55 // Default to an approximate average radius for the United States.
56
57 $lat = deg2rad($latitude);
58
59 $x = cos($lat)/earth_radius_semimajor();
60 $y = sin($lat)/earth_radius_semiminor();
61 return 1 / (sqrt($x*$x + $y*$y));
62 }
63
64 function earth_xyz($longitude, $latitude, $height = 0) {
65 // Convert longitude and latitude to earth-centered earth-fixed coordinates.
66 // X axis is 0 long, 0 lat; Y axis is 90 deg E; Z axis is north pole.
67 //global $earth_radius_semimajor, $earth_eccentricity_sq;
68 $long = deg2rad($longitude);
69 $lat = deg2rad($latitude);
70
71 $coslong = cos($long);
72 $coslat = cos($lat);
73 $sinlong = sin($long);
74 $sinlat = sin($lat);
75 $radius = earth_radius_semimajor() /
76 sqrt(1 - earth_eccentricity_sq() * $sinlat * $sinlat);
77 $x = ($radius + $height) * $coslat * $coslong;
78 $y = ($radius + $height) * $coslat * $sinlong;
79 $z = ($radius * (1 - earth_eccentricity_sq()) + $height) * $sinlat;
80 return array($x, $y, $z);
81 }
82
83 function earth_arclength($angle, $latitude=37.9) {
84 // Convert a given angle to earth-surface distance.
85 return deg2rad($angle) * earth_radius($latitude);
86 }
87
88 function earth_distance($longitude1, $latitude1, $longitude2, $latitude2) {
89 // Estimate the earth-surface distance between two locations.
90 $long1 = deg2rad($longitude1);
91 $lat1 = deg2rad($latitude1);
92 $long2 = deg2rad($longitude2);
93 $lat2 = deg2rad($latitude2);
94 $radius = earth_radius(($latitude1 + $latitude2) / 2);
95
96 $cosangle = cos($lat1)*cos($lat2) *
97 (cos($long1)*cos($long2) + sin($long1)*sin($long2)) +
98 sin($lat1)*sin($lat2);
99 return acos($cosangle) * $radius;
100 }
101
102 /*
103 * Returns the SQL fragment needed to add a column called 'distance'
104 * to a query that includes the location table
105 *
106 * @param $longitude The measurement point
107 * @param $latibude The measurement point
108 * @param $tbl_alias If necessary, the alias name of the location table to work from. Only required when working with named {location} tables
109 */
110 function earth_distance_sql($longitude, $latitude, $tbl_alias = '') {
111 // Make a SQL expression that estimates the distance to the given location.
112 $long = deg2rad($longitude);
113 $lat = deg2rad($latitude);
114 $radius = earth_radius($latitude);
115
116 // If the table alias is specified, add on the separator.
117 $tbl_alias = empty($tbl_alias) ? $tbl_alias : ($tbl_alias .'.');
118
119 $coslong = cos($long);
120 $coslat = cos($lat);
121 $sinlong = sin($long);
122 $sinlat = sin($lat);
123 return "(IFNULL(ACOS($coslat*COS(RADIANS({$tbl_alias}latitude))*($coslong*COS(RADIANS({$tbl_alias}longitude)) + $sinlong*SIN(RADIANS({$tbl_alias}longitude))) + $sinlat*SIN(RADIANS({$tbl_alias}latitude))), 0.00000)*$radius)";
124 }
125
126 function earth_longitude_range($longitude, $latitude, $distance) {
127 // Estimate the min and max longitudes within $distance of a given location.
128 $long = deg2rad($longitude);
129 $lat = deg2rad($latitude);
130 $radius = earth_radius($latitude);
131
132 $angle = $distance / $radius;
133 $diff = asin(sin($angle)/cos($lat));
134 $minlong = $long - $diff;
135 $maxlong = $long + $diff;
136 if ($minlong < -pi()) { $minlong = $minlong + pi()*2; }
137 if ($maxlong > pi()) { $maxlong = $maxlong - pi()*2; }
138 return array(rad2deg($minlong), rad2deg($maxlong));
139 }
140
141 function earth_latitude_range($longitude, $latitude, $distance) {
142 // Estimate the min and max latitudes within $distance of a given location.
143 $long = deg2rad($longitude);
144 $lat = deg2rad($latitude);
145 $radius = earth_radius($latitude);
146
147 $angle = $distance / $radius;
148 $minlat = $lat - $angle;
149 $maxlat = $lat + $angle;
150 $rightangle = pi()/2;
151 if ($minlat < -$rightangle) { // wrapped around the south pole
152 $overshoot = -$minlat - $rightangle;
153 $minlat = -$rightangle + $overshoot;
154 if ($minlat > $maxlat) { $maxlat = $minlat; }
155 $minlat = -$rightangle;
156 }
157 if ($maxlat > $rightangle) { // wrapped around the north pole
158 $overshoot = $maxlat - $rightangle;
159 $maxlat = $rightangle - $overshoot;
160 if ($maxlat < $minlat) { $minlat = $maxlat; }
161 $maxlat = $rightangle;
162 }
163 return array(rad2deg($minlat), rad2deg($maxlat));
164 }

  ViewVC Help
Powered by ViewVC 1.1.2