Re: lat lon function
| From: | Hugh Bothwell | Date: | Fri, 11 Apr 2003 03:58:47 +0000 |
| Subject: | Re: lat lon function | ||
| References: | 1 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-143439@lists.php.net to get a copy of this message | ||
"Edward Peloke" <epeloke@echoman.com> wrote in message
news:NFBBIIKNALMFFNANEKEFGEAGDMAA.epeloke@echoman.com...
> Hello all,
>
> I currently have a php function that takes two airport codes and returns
> their distance in miles. The function gets the longitude and latitude for
> the airports from a mysql db. My current problem is I have to show the
user
> all airports within a certain mile radius of the one they selected. I
can't
> run this function against all 7000+ rows in the db and return only the
ones
> needed, how can I do this? I know I have seen this several places online.
Is the radius a constant value, or chosen from a short list of
constant values? If the user can enter whatever radius they
want, you pretty much have to calculate this dynamically; otherwise
I would really consider precalculating and storing this for each
airport (it's not like the airports are likely to move on short notice).
For fun, I will now derive the surface-distance formula; this requires trig
and basic vector math.
For each airport, we must convert the polar coordinates of
latitude and longitude to rectangular coordinates. We will assume the
Earth is a perfect sphere. Let R = the Earth's radius, then for each
x = R cos(lon) cos(lat)
y = R sin(lon) cos(lat)
z = R sin(lat)
Because the sphere's center is the original, we can also consider
these coordinates as vectors from the center to the surface; so we
can find the angle between the two vectors.
By the dot product, A1 (dot) A2 = |A1| |A2| cos(theta),
so theta = acos( ( A1 (dot) A2 ) / ( |A1| |A2| ) ).
We know that |A1| == |A2| == R; also,
A1 (dot) A2 = x1 x2 + y1 y2 + z1 z2 and each
of these components has an R. Simplifying, we get
theta = acos(
cos(lon1)cos(lat1)cos(lon2)cos(lat2)
+ sin(lon1)cos(lat1)sin(lon2)cos(lat2)
+ sin(lat1)sin(lat2)
)
= acos(
[sin(lon1)sin(lon2) + cos(lon1)cos(lon2)] cos(lat1)cos(lat2)
+ sin(lat1)sin(lat2)
)
then if theta is expressed in radians, the distance between
the airports = R theta, and if R is expressed in miles, so
will the distance be.
From here on I will assume that latitude and longitude
are angles in (-90..90) and [-180..180) degrees.
<?php
define("R", 3960); // Earth's radius in miles
// Calculate distance between two points:
// lat/lon, lat/lon in decimal-degrees.
// Returns distance in miles.
deg_dist($lat1, $lon1, $lat2, $lon2) {
return( rad_dist(
deg2rad($lat1), deg2rad($lon1),
deg2rad($lat2), deg2rad($lon2)
));
}
// Calculate distance between two points:
// lat/lon, lat/lon in radians.
// Returns distance in miles.
rad_dist($lat1, $lon1, $lat2, $lon2) {
return( R * acos(
( sin($lon1)*sin($lon2) + cos($lon1)*cos($lon2) ) *
cos($lat1)*cos($lat2)
+ sin($lat1)*sin($lat2)
));
}
?>