PHP, Math, and Navagation
In my spare time I've been starting the write my own web based geocaching software in PHP so I can do some semi-automated statistical analysis on geocaches I've found.
I was looking for some pre-built functions do to some things like calculate distance between two lon/lat pairs as well as bearing and midpoints. Why re-invent the wheel if someone has already done it, right?
I found the mathematical calculation for how to calculate some if the things I was looking for at pilotsweb.com
Distance:
Where:
D = Distance (in Nautical Miles)
L1 = Original Latitude
L2 = Destination Latitude
= Origin Longitude
= Destination Longitude Latitude
Direction:
Where:
C = Initial Bearing (in degrees)
D = Distance
L1 = Original Latitude
L2 = Destination Latitude
But that doesn't really help too much for writing code... I know I could figure it out, but when Joel De Gan has already figured it out and published his code, why not use that?
Here's some code from his site that I've changed a bit, re-formatted to my coding preferences, and added a bit of functionality too:
/*
Distance between two points
*/
function distance($lat1, $lon1, $lat2, $lon2, $units = 'miles')
{
$lat1 = rad($lat1); $lon1 = rad($lon1);
$lat2 = rad($lat2); $lon2 = rad($lon2);
switch ($units)
{
case "miles":
case "m":
case "M":
$r = 3963.1;
break;
case "nmiles":
case "n":
case "N":
$r = 3443.9; break;
case "kilo":
case "k":
case "K":
$r = 6378;
break;
}
return acos(sin($lat1)*sin($lat2) + cos($lat1)*cos($lat2)*cos($lon2-$lon1)) * $r;
}
/*
Bearing from point 1 to point 2
*/
function bearing($lat1,$lon1, $lat2, $lon2)
{
$y = sin($lon2-$lon1) * cos($lat2);
$x = cos($lat1)*sin($lat2) - sin($lat1)*cos($lat2)*cos($lon2-$lon1);
return atan2($y, $x);
}
/*
Midpoint for two locations
*/
function midpoint($lat1, $lon1, $lat2, $lon2)
{
$lat1 = rad($lat1); $lon1 = rad($lon1);
$lat2 = rad($lat2); $lon2 = rad($lon2);
$dLon = $lon2 - $lon1;
$Bx = (cos($lat2) * cos($dLon));
$By = (cos($lat2) * sin($dLon));
$lat3 = atan2( sin($lat1) + sin($lat2), sqrt( (cos($lat1)+$Bx) * (cos($lat1)+$Bx) + ($By * $By)) );
$lon3 = $lon1 + atan2($By, cos($lat1) + $Bx);
if (!$lat3 || !$lon3) return false;
return array($lat3 * 180 / M_PI, $lon3 * 180 / M_PI);
}
/*
Support functions
*/
function rad($v)
{
return ($v * M_PI / 180);
}
/*
Degree, Minute, Seconds to decimal degrees
*/
function dms2deg($D, $M, $S, $dir)
{
if(strpos(‘ WsSs’, $dir)>0)
return(-1 * ($D + ($M + $S/60)/60));
else
return($D + ($M + $S/60)/60);
}
function dms($rad)
{
$d = abs($rad * 180 / M_PI);
$d += 1/7200; // add 1/2 second for rounding
$deg = floor($d);
$min = floor(($d-$deg)*60);
$sec = floor(($d-$deg-$min/60)*3600);
// add leading zeros if required
if ($deg< 100) $deg = '0' + $deg;
if ($deg< 10) $deg = '0' + $deg;
if ($min< 10) $min = '0' + $min;
if ($sec< 10) $sec = '0' + $sec;
return $deg + '\u00B0' + $min + '\u2032' + $sec + '\u2033';
}
Thanks for the help, Joel!

= Origin Longitude
= Destination Longitude Latitude



January 12th, 2008 - 16:30
Navigation
January 16th, 2008 - 20:48
Does that take into account the curvature of the earth’s surface? And why is it using nautical miles?
April 14th, 2008 - 16:43
glad it helps..
I sort of wish I had been able to finish up the original app for handling this data and testing the theory I was presenting.
However, I left that company where I was doing all this real-world location work and have kind of dropped most of it.
Glad it helped someone though!