Re: Math_LatLong ?
| From: | James Carr | Date: | Fri, 13 Jan 2006 18:02:46 +0000 |
| Subject: | Re: Math_LatLong ? | ||
| References: | 1 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-40954@lists.php.net to get a copy of this message | ||
Sorry, seems my last replies were actually off list (Seth is probably
wondering why I sent him all my emails). :(
So, as a quick repost to those:
On 1/11/06, bertrand Gugger <bertrand@toggg.com>
>Dunno how how much it is math :)
It's a little too much math! Take a peek:
/*
* Calculate geodesic distance (in m) between two points specified by
latitude/longitude with Vincenty formula
*
* from: Vincenty inverse formula - T Vincenty, "Direct and Inverse
Solutions of Geodesics on the
* Ellipsoid with application of nested equations", Survey
Review, vol XXII no 176, 1975
* http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
*
* @access public
* @static
* @param LatLong $p1 - starting point
* @param LatLong $p2 - ending point
*/
function distVincenty ($p1, $p2)
{
$a = 6378137;
$b = 6356752.3142;
$f = 1/298.257223563;
$L = $p2->lon - $p1->long;
$U1 = atan((1-$f) * tan($p1->lat));
$U2 = atan((1-$f) * tan($p2->lat));
$sinU1 = sin($U1); $cosU1 = cos($U1);
$sinU2 = sin($U2); $cosU2 = cos($U2);
$lambda = $L; $lambdaP = 2*PI;
$iterLimit = 20;
while (abs($lambda-$lambdaP) > 1e-12 && --$iterLimit>0)
{
$sinLambda = sin($lambda);
$cosLambda = cos($lambda);
$sinSigma = sqrt(($cosU2*$sinLambda) * ($cosU2*$sinLambda) +
($cosU1*$sinU2-$sinU1*$cosU2*$cosLambda) *
($cosU1*$sinU2-$sinU1*$cosU2*$cosLambda));
if ($sinSigma==0)
{
return 0; // co-incident points
}
$cosSigma = $sinU1*$sinU2 + $cosU1*$cosU2*$cosLambda;
$sigma = atan2($sinSigma, $cosSigma); // was atan2
$alpha = asin($cosU1 * $cosU2 * $sinLambda /
$sinSigma);
$cosSqAlpha = cos($alpha) * cos($alpha);
$cos2SigmaM = $cosSigma - 2*$sinU1*$sinU2/$cosSqAlpha;
$C = $f/16*$cosSqAlpha*(4+$f*(4-3*$cosSqAlpha));
$lambdaP = $lambda;
$lambda = $L + (1-$C) * $f * sin($alpha) *
($sigma + $C*$sinSigma*($cos2SigmaM+$C*$cosSigma*
(-1+2*$cos2SigmaM*$cos2SigmaM)));
}
if ($iterLimit==0) return false; // formula failed to
converge
$uSq = $cosSqAlpha * ($a*$a - $b*$b) / ($b*$b);
$A = 1 + $uSq/16384*(4096+$uSq*(-768+$uSq*(320-175*$uSq)));
$B = $uSq/1024 * (256+$uSq*(-128+$uSq*(74-47*$uSq)));
$deltaSigma =
$B*$sinSigma*($cos2SigmaM+$B/4*($cosSigma*(-1+2*$cos2SigmaM*$cos2SigmaM)-
$B/6*$cos2SigmaM*(-3+4*$sinSigma*$sinSigma)*(-3+4*$cos2SigmaM*$cos2SigmaM)));
$s = $b*$A*($sigma-$deltaSigma);
$s = round( $s, 3); // round to 1mm precision
return $s;
}
(yeah, a bit nasty. I'm working on cleaning up the readability).
Anyway, I've signed up for an account and would like to move forward and
submit code. I've refactored the current class a bit, but plan on
refactoring it into a package that provides a LatitudeLongitude object with
associated attributes, and encapsulate all the realted algorithms to perform
calculations on latitude longitude coordinates (i.e. finding lat/long
coordinate given a starting point, bearing, and distance... as well as
mutiple ways to calculate the distance between two points, and even type
conversion between types like NAD83, WGS84, UMT, etc).
Thanks,
JC
On 1/11/06, James Carr <james.r.carr@gmail.com> wrote:
>
> Hi,
>
> I have a small class I cooked up sometime back to do latitude/longitude
> related calculations, and was wondering if there would be any interest in
> putting this in PEAR? I need to do a bit of cleaning up on it, but it's
> pretty solid and contains around 8 algorithms for latitude/logtitude related
> calculations (and I am sure all the new google maps api people would enjoy
> it).
>
> Thanks,
> JC
>