/[drupal]/contributions/modules/geonames_cck/geonames_cck_earth.inc
ViewVC logotype

Contents of /contributions/modules/geonames_cck/geonames_cck_earth.inc

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


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

  ViewVC Help
Powered by ViewVC 1.1.2