/** * Calculate the distance between two * points using the Great Circle formula. * * Supply instances of the coordinate class. * * http://www.ga.gov.au/earth-monitoring/geodesy/geodetic-techniques/distance-calculation-algorithms.html#circle * * @param Treffynnon\Navigator\Coordinate $point1 * @param Treffynnon\Navigator\Coordinate $point2 * @return float */ public function calculate(N\LatLong $point1, N\LatLong $point2) { $celestialBody = $this->getCelestialBody(); $degrees = acos(sin($point1->getLatitude()->get()) * sin($point2->getLatitude()->get()) + cos($point1->getLatitude()->get()) * cos($point2->getLatitude()->get()) * cos($point2->getLongitude()->get() - $point1->getLongitude()->get())); $d = $degrees * $celestialBody->volumetricMeanRadius; return $d * 1000; }
public function testPrimeCoordinateParsers() { $latitude = new N\Coordinate(10.03); $longitude = new N\Coordinate('10 10 1.2S', new C\DmsParser()); $LatLong = new N\LatLong($latitude, $longitude); $this->assertEquals($LatLong->getLongitude()->getParser()->getDirection(), T\Navigator::Long); $this->assertEquals($LatLong->getLatitude()->getParser()->getDirection(), T\Navigator::Lat); }
/** * Calculate the distance between two * points using the Haversine formula. * * Supply instances of the coordinate class. * * http://en.wikipedia.org/wiki/Haversine_formula * * @param Treffynnon\Navigator\Coordinate $point1 * @param Treffynnon\Navigator\Coordinate $point2 * @return float */ public function calculate(N\LatLong $point1, N\LatLong $point2) { $celestialBody = $this->getCelestialBody(); $deltaLat = $point2->getLatitude()->get() - $point1->getLatitude()->get(); $deltaLong = $point2->getLongitude()->get() - $point1->getLongitude()->get(); $a = sin($deltaLat / 2) * sin($deltaLat / 2) + cos($point1->getLatitude()->get()) * cos($point2->getLatitude()->get()) * sin($deltaLong / 2) * sin($deltaLong / 2); $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); $d = $celestialBody->volumetricMeanRadius * $c * 1000; return $d; }
/** * Calculate the distance between two * points using Vincenty's formula. * * Supply instances of the coordinate class. * * http://www.movable-type.co.uk/scripts/LatLongVincenty.html * * @param Treffynnon\Navigator\Coordinate $point1 * @param Treffynnon\Navigator\Coordinate $point2 * @return float */ public function calculate(N\LatLong $point1, N\LatLong $point2) { $celestialBody = $this->getCelestialBody(); $a = $celestialBody->equatorialRadius; $b = $celestialBody->polarRadius; $f = $celestialBody->flattening; //flattening of the ellipsoid $L = $point2->getLongitude()->get() - $point1->getLongitude()->get(); //difference in longitude $U1 = atan((1 - $f) * tan($point1->getLatitude()->get())); //U is 'reduced latitude' $U2 = atan((1 - $f) * tan($point2->getLatitude()->get())); $sinU1 = sin($U1); $sinU2 = sin($U2); $cosU1 = cos($U1); $cosU2 = cos($U2); $lambda = $L; $lambdaP = 2 * pi(); $i = 20; while (abs($lambda - $lambdaP) > 1.0E-12 && --$i > 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); $sinAlpha = $cosU1 * $cosU2 * $sinLambda / $sinSigma; $cosSqAlpha = 1 - $sinAlpha * $sinAlpha; $cos2SigmaM = $cosSigma - 2 * $sinU1 * $sinU2 / $cosSqAlpha; if (is_nan($cos2SigmaM)) { $cos2SigmaM = 0; } //equatorial line: cosSqAlpha=0 (6) $c = $f / 16 * $cosSqAlpha * (4 + $f * (4 - 3 * $cosSqAlpha)); $lambdaP = $lambda; $lambda = $L + (1 - $c) * $f * $sinAlpha * ($sigma + $c * $sinSigma * ($cos2SigmaM + $c * $cosSigma * (-1 + 2 * $cos2SigmaM * $cos2SigmaM))); } if ($i == 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))); $d = $b * $A * ($sigma - $deltaSigma); return $d; }
public function testFromString() { $latitude = '42.77'; $longitude = '-2.86844'; $LatLong = N\LatLong::createFromString($latitude . ',' . $longitude); $this->assertInstanceOf('Treffynnon\\Navigator\\LatLong', $LatLong); $this->assertEquals($latitude, (string) $LatLong->getLatitude()); $this->assertEquals($longitude, (string) $LatLong->getLongitude()); }