public static function line($x1, $y1, $x2, $y2, $chars = array('#')) { if ($x2 != $x1) { if ($x2 < $x1) { list($x1, $x2) = array($x2, $x1); list($y2, $y1) = array($y1, $y2); } $slope = ($y2 - $y1) / ($x2 - $x1); $radians = atan($slope); } else { $radians = pi() / 2; } $radians += 2 * pi(); $dist = sqrt(pow($x2 - $x1, 2) + pow($y2 - $y1, 2)); $last_x = false; $last_y = false; $j = 0; $chars_length = count($chars); for ($i = 0; $i <= abs(ceil($dist)); $i += 1) { $x = round($i * cos($radians) + $x1); $y = round($i * sin($radians) + $y1); if ($x != $last_x || $last_y != $y) { Output::string($chars[$j++ % $chars_length], $y, $x); } $last_x = $x; $last_y = $y; } }
public static function get_tile_nw($xtile, $ytile, $zoom) { $n = pow(2, $zoom); $lon = $xtile / $n * 360.0 - 180.0; $lat = rad2deg(atan(sinh(pi() * (1 - 2 * $ytile / $n)))); return array($lat, $lon); }
/** * Create a Distance object * * @param string latitude of first point * @param string longitude of first point * @param string latitude2 of second point * @param string longitude2 of second point * @param bool True if the distance is in Kms, otherwise returns Miles */ function __construct($latitude = 0, $longitude = 0, $latitude2 = 0, $longitude2 = 0, $in_kms = TRUE) { $EARTH_RADIUS_MILES = 3963; // Miles $miles2kms = 1.609; $dist = 0; //convert degrees to radians $latitude = $latitude * M_PI / 180; $longitude = $longitude * M_PI / 180; $latitude2 = $latitude2 * M_PI / 180; $longitude2 = $longitude2 * M_PI / 180; if ($latitude != $latitude2 || $longitude != $longitude2) { //the two points are not the same $dist = sin($latitude) * sin($latitude2) + cos($latitude) * cos($latitude2) * cos($longitude2 - $longitude); // Special case to prevent division by zero if ($dist == 1 || $dist == -1) { // lim $dist -> 1 or -1 atan($dist / sqrt(1 - $dist*$dist)) == M_PI / 2 // This means that the equation below will evaluate to zero $dist = 0; } else { $dist = $EARTH_RADIUS_MILES * (-1 * atan($dist / sqrt(1 - $dist * $dist)) + M_PI / 2); } } if ($in_kms) { $dist = $dist * $miles2kms; } $this->dist = round($dist, 2); }
static function metersToLatLon($mx, $my) { $lng = $mx / self::originShift() * 180.0; $lat = $my / self::originShift() * 180.0; $lat = 180 / pi() * (2 * atan(exp($lat * pi() / 180.0)) - pi() / 2.0); return new GoogleMapPoint($lat, $lng); }
public function MetersToLatLon($mx, $my) { $lon = $mx / $this->originShift * 180.0; $lat = $my / $this->originShift * 180.0; $lat = 180 / pi() * (2 * atan(exp($lat * pi() / 180.0)) - pi() / 2.0); return array($lat, $lon); }
function solphy($dj, &$lo, &$bo, &$p) { global $T2000, $DGRAD, $DPI; $t = ($dj - $T2000) / 3652500; $t2 = $t * $t; $t3 = pow($t, 3); $t4 = pow($t, 4); $t5 = pow($t, 5); $gi = 7.25 * $DGRAD; $go = 73 + 40.0 / 60.0 + 50.25 / 3600 * ($dj - 2396758.5) / 365.25; $gm = 112.766 + (2430000.5 - $dj) * 14.18439716 + 180; $go = fmod($go * $DGRAD, $DPI); $gm = fmod($gm * $DGRAD, $DPI); $a1 = 2.18 - 3375.7 * $t + 0.36 * $t2; $a2 = 3.51 + 125666.39 * $t + 0.1 * $t2; $dpsi = 1.0E-7 * (-834 * sin($a1) - 64 * sin($a2)); $epsv = 0.4090928 + 1.0E-7 * (-226938 * $t - 75 * $t2 + 96926 * $t3 - 2491 * $t4 - 12104 * $t5 + 446 * cos($a1) + 28 * cos($a2)); $gla = lonsol($dj); $gl = $gla - $dpsi; $c = cos($gl - $go); $s = sin($gl - $go); //print "a1: $a1 a2: $a2 dpsi: $dpsi gla: $gla gl: $gl c: $c s: $s<BR>"; $lo = atan2(-$s * cos($gi), -$c) + $gm; $lo = fmod($lo, $DPI); if ($lo < 0) { $lo += $DPI; } $bo = asin($s * sin($gi)); $x = atan(-cos($gla) * tan($epsv)); $y = atan(-$c * tan($gi)); $p = $x + $y; }
function gcBearingTo($from, $to) { global $PI, $DEG2RAD, $RAD2DEG; $x1 = $from["x"] * $DEG2RAD; $y1 = $from["y"] * $DEG2RAD; $x2 = $to["x"] * $DEG2RAD; $y2 = $to["y"] * $DEG2RAD; $a = cos($y2) * sin($x2 - $x1); $b = cos($y1) * sin($y2) - sin($y1) * cos($y2) * cos($x2 - $x1); if ($a == 0 && $b == 0) { $bearing = 0; return $bearing; } if ($b == 0) { if ($a < 0) { $bearing = 270; } else { $bearing = 90; } return $bearing; } if ($b < 0) { $adjust = $PI; } else { if ($a < 0) { $adjust = 2 * $PI; } else { $adjust = 0; } } $bearing = (atan($a / $b) + $adjust) * $RAD2DEG; return $bearing; }
public function inverse($p) { $Y = $p->x - $this->x0; $X = $p->y - $this->y0; $rotI = $Y / $this->R; $rotB = 2 * (atan(exp(X / $this->R)) - Sourcemap_Proj::PI / 4.0); $b = asin(cos($this->b0) * sin($rotB) + sin($this->b0) * cos($rotB) * cos($rotI)); $I = atan(sin($rotI) / (cos($this->b0) * cos($rotI) - sin($this->b0) * tan($rotB))); $lambda = $this->lambda0 + $I / $this->alpha; $S = 0.0; $phy = $b; $prevPhy = -1000.0; $iteration = 0; while (abs($phy - $prevPhy) > 1.0E-7) { if (++$iteration > 20) { throw new Exception("Infinity..."); } //S = log(tan(Sourcemap_Proj::PI / 4.0 + $phy / 2.0)); $S = 1.0 / $this->alpha * (log(tan(Sourcemap_Proj::PI / 4.0 + $b / 2.0)) - $this->K) + $this->e * log(tan(Sourcemap_Proj::PI / 4.0 + asin($this->e * sin($phy)) / 2.0)); $prevPhy = $phy; $phy = 2.0 * atan(exp($S)) - Sourcemap_Proj::PI / 2.0; } $p->x = $lambda; $p->y = $phy; return $p; }
function getPoint($xtile, $ytile, $zoom) { $n = pow(2, $zoom); $lon_deg = $xtile / $n * 360.0 - 180.0; $lat_deg = rad2deg(atan(sinh(pi() * (1 - 2 * $ytile / $n)))); return $lon_deg . "," . $lat_deg; }
/** * Create a Distance object * * @param string latitude of first point * @param string longitude of first point * @param string latitude2 of second point * @param string longitude2 of second point * @param bool True if the distance is in Kms, otherwise returns Miles */ public function __construct($latitude = 0, $longitude = 0, $latitude2 = 0, $longitude2 = 0, $in_kms = TRUE) { $EARTH_RADIUS_MILES = 3963; // Miles $miles2kms = 1.609; $dist = 0; // Convert degrees to radians $latitude = $latitude * M_PI / 180; $longitude = $longitude * M_PI / 180; $latitude2 = $latitude2 * M_PI / 180; $longitude2 = $longitude2 * M_PI / 180; if ($latitude != $latitude2 || $longitude != $longitude2) { // The two points are not the same $dist = sin($latitude) * sin($latitude2) + cos($latitude) * cos($latitude2) * cos($longitude2 - $longitude); // Safety check if ($dist > 0) { $sqrt = sqrt(1 - $dist * $dist); if ($sqrt > 0) { $dist = $EARTH_RADIUS_MILES * (-1 * atan($dist / $sqrt) + M_PI / 2); } } } if ($in_kms) { $dist = $dist * $miles2kms; } $this->dist = round($dist, 2); }
static function anglePolar($pointA, $pointB, $pointC) { if (!isset(self::$anglePolarTable[$pointA->guid . ';' . $pointB->guid . ';' . $pointC->guid])) { $Ax = $pointA->x - $pointB->x; $Ay = $pointA->y - $pointB->y; $Cx = $pointC->x - $pointB->x; $Cy = $pointC->y - $pointB->y; if ($Ax <= 0 && pow($Ay, 2) == 0) { $Apolar = 180; } else { $Apolar = rad2deg(2 * atan($Ay / ($Ax + sqrt(pow($Ax, 2) + pow($Ay, 2))))); } if ($Cx + sqrt(pow($Cx, 2) + pow($Cy, 2)) == 0) { $Cpolar = 180; } else { $Cpolar = rad2deg(2 * atan($Cy / ($Cx + sqrt(pow($Cx, 2) + pow($Cy, 2))))); } $result = $Cpolar - $Apolar; if ($result < 0) { $result += 360; } self::$anglePolarTable[$pointA->guid . ';' . $pointB->guid . ';' . $pointC->guid] = $result; } return self::$anglePolarTable[$pointA->guid . ';' . $pointB->guid . ';' . $pointC->guid]; }
public function fromPointToLatLon(Coord2D $point) { $origin = $this->_pixelOrigin; $lng = ($point->x - $origin->x) / $this->_pixelsPerLonDegree; $latRadians = ($point->y - $origin->y) / -$this->_pixelsPerLonRadian; $lat = $this->radiansToDegrees(2 * atan(exp($latRadians)) - pi() / 2); return new GeoPoint($lat, $lng); }
function fromPixelToLL($x, $y, $zoom) { $e = $this->zc[$zoom]; $f = ($x - $e) / $this->Bc[$zoom]; $g = ($y - $e) / -$this->Cc[$zoom]; $h = 180.0 / M_PI * (2 * atan(exp($g)) - 0.5 * M_PI); return array($f, $h); }
public function getAngle($out = 'rad') { if ($this->y === 0) { $angle = 0; } else { $angle = atan($this->x / $this->y); } return $out == 'rad' ? $angle : rad2deg($angle); }
public function fromPointToLatLng($point) { $me = $this; $origin = $me->pixelOrigin_; $lng = ($point->x - $origin->x) / $me->pixelsPerLonDegree_; $latRadians = ($point->y - $origin->y) / -$me->pixelsPerLonRadian_; $lat = radiansToDegrees(2 * atan(exp($latRadians)) - M_PI / 2); return new G_LatLng($lat, $lng); }
public function testTrigonometry() { $t = new IntMethods(); $this->assertEquals(sin(1), $t->getSin(1)); $this->assertEquals(cos(1), $t->getCos(1)); $this->assertEquals(tan(1), $t->getTan(1)); $this->assertEquals(asin(1), $t->getAsin(1)); $this->assertEquals(acos(1), $t->getAcos(1)); $this->assertEquals(atan(1), $t->getAtan(1)); }
public function inverse($p) { $p->x -= $this->x0; $p->y -= $this->y0; $lon = Proj4php::$common->adjust_lon($this->long0 + $p->x / $this->a); $lat = 2.5 * (atan(exp(0.8 * $p->y / $this->a)) - Proj4php::$common->PI / 4.0); $p->x = $lon; $p->y = $lat; return $p; }
public function inverse($p) { $p->x -= $this->x0; $p->y -= $this->y0; $lon = Sourcemap_Proj::adjust_lon($this->long0 + $p->x / $this->a); $lat = 2.5 * (atan(exp(0.8 * $p->y / $this->a)) - Sourcemap_Proj::PI / 4.0); $p->x = $lon; $p->y = $lat; return p; }
public function getDistance($lat1, $lng1, $lat2, $lng2) { /** * Ported from javascript * * Original JavaScript version * http://www.movable-type.co.uk/scripts/latlong-vincenty.html */ $lat1 = deg2rad($lat1); $lat2 = deg2rad($lat2); $lon1 = deg2rad($lon1); $lon2 = deg2rad($lon2); $a = 6378137; $b = 6356752.3142; $f = 1 / 298.257223563; $L = $lon2 - $lon1; $U1 = atan((1 - $f) * tan($lat1)); $U2 = atan((1 - $f) * tan($lat2)); $sinU1 = sin($U1); $cosU1 = cos($U1); $sinU2 = sin($U2); $cosU2 = cos($U2); $lambda = $L; $lambdaP = 2 * M_PI; $iterLimit = 20; while (abs($lambda - $lambdaP) > 1.0E-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); return round($s / 1609.344, 3); //miles }
public static function fromTileCoord($x, $y, $zoom) { // Alternative constructor - constructs a [GMapTile] with the given tile coordinates and zoom level. // The latitude and longitude of the new instance indicate the north-west corner of the tile. $x = $x * self::TILE_SIZE; $y = $y * self::TILE_SIZE; $long = ($x - self::$bitmapOrigo[$zoom]->x) / self::$pixelsPerLonDegree[$zoom]; $e = ($y - self::$bitmapOrigo[$zoom]->y) / (-1 * self::$pixelsPerLonRadian[$zoom]); $lat = (2 * atan(exp($e)) - M_PI / 2) / self::$Wa; return new GMapTile($lat, $long, $zoom); }
public function inverse($p) { $x = $p->x; $y = $p->y; $L = atan(Sourcemap_Proj::sinh(($x - $this->xs) / $this->n2) / cos(($y - $this->ys) / $this->n2)); $lat1 = asin(sin(($y - $this->ys) / $this->n2) / Sourcemap_Proj::cosh(($x - $this->xs) / $this->n2)); $LC = Sourcemap_Proj::latiso(0.0, $lat1, sin($lat1)); $p->x = $this->lc + $L / $this->rs; $p->y = Sourcemap_Proj::invlatiso($this->e, ($LC - $this->cp) / $this->rs); return $p; }
/** * Returns the arc tangent of a number. * * @param float $number * @param float $y optional * @return float The arc tangent of a number in radians. */ public function atan($number) { if (func_num_args() == 2) { // If the user has passed in two parameters, let's // assume that they want to calculate Atan2. return $this->atan2(func_get_arg(1), func_get_arg(2)); } // If the number of arguments is not two, just calculate // the atan as normal. return (double) atan($number); }
/** * Calculates the distance between two points on the Earth's surface * * The method used is due to H. Andoyer. * The relative error of the result is of the order of the square of the Earth's flattening. * * @param float $latitude_1 The geographical latitude 1 in degrees or radians * @param float $longitude_1 The geographical longitude 1 in degrees or radians * @param float $latitude_2 The geographical latitude 2 in degrees or radians * @param float $longitude_2 The geographical longitude 2 in degrees or radians * @param bool $is_radian True if the latitude is in radians, false if the latitude is in degrees * @return float The distance in meters */ function aa_distance_between_two_points($latitude_1, $longitude_1, $latitude_2, $longitude_2, $is_radian = false) { global $_aa_earth_ellipsoid; global $_aa_earth_ellipsoids; if ($latitude_1 == $latitude_2 and $longitude_1 == $longitude_2) { // the two points are the same return 0; } if (!$is_radian) { $latitude_1 = deg2rad($latitude_1); // Φ1 $longitude_1 = deg2rad($longitude_1); // L1 $latitude_2 = deg2rad($latitude_2); // Φ2 $longitude_2 = deg2rad($longitude_2); // L2 } list($equatorial_radius, , $inverse_flattening) = $_aa_earth_ellipsoids[$_aa_earth_ellipsoid]; // a, 1/f $flattening = 1 / $inverse_flattening; // f $F = ($latitude_1 + $latitude_2) / 2; $G = ($latitude_1 - $latitude_2) / 2; $lambda = ($longitude_1 - $longitude_2) / 2; $sin_G = sin($G); $sin2_G = $sin_G * $sin_G; $cos_lambda = cos($lambda); $cos2_lambda = $cos_lambda * $cos_lambda; $cos_F = cos($F); $cos2_F = $cos_F * $cos_F; $sin_lambda = sin($lambda); $sin2_lambda = $sin_lambda * $sin_lambda; $cos_G = cos($G); $cos2_G = $cos_G * $cos_G; $sin_F = sin($F); $sin2_F = $sin_F * $sin_F; $S = $sin2_G * $cos2_lambda + $cos2_F * $sin2_lambda; $C = $cos2_G * $cos2_lambda + $sin2_F * $sin2_lambda; $w = atan(sqrt($S / $C)); if ($w == 0) { // possible case (?) where the distance between the two points is so small // that w is null and cannot be used to calculate R below $distance = 0; } else { $R = sqrt($S * $C) / $w; $D = 2 * $w * $equatorial_radius; $R3 = 3 * $R; $H1 = ($R3 - 1) / (2 * $C); $H2 = ($R3 + 1) / (2 * $S); $distance = $D * (1 + $flattening * $H1 * $sin2_F * $cos2_G - $flattening * $H2 * $cos2_F * $sin2_G); } return $distance; }
function geo_dist($lon1, $lat1, $lon2, $lat2) { // check if polygon is in geo mode if (!$this->use_geo_mode()) { die('error: function geo_dist should not be used if vertices are not defined by latitudes and longitudes (geomode)'); } $a = 6378137; $b = 6356752.3142; $f = 1 / 298.257223563; // WGS-84 ellipsiod $L = deg2rad($lon2 - $lon1); $U1 = atan((1 - $f) * tan(deg2rad($lat1))); $U2 = atan((1 - $f) * tan(deg2rad($lat2))); $sinU1 = sin($U1); $cosU1 = cos($U1); $sinU2 = sin($U2); $cosU2 = cos($U2); $lambda = $L; $lambdaP = 2 * M_PI; $iterLimit = 20; while (abs($lambda - $lambdaP) > 1.0E-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); $sinAlpha = $cosU1 * $cosU2 * $sinLambda / $sinSigma; $cosSqAlpha = 1 - $sinAlpha * $sinAlpha; $cos2SigmaM = $cosSigma - 2 * $sinU1 * $sinU2 / $cosSqAlpha; if (is_numeric($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 ($iterLimit == 0) { return NULL; } // 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; }
public function inverse($p) { $x = $p->x; $y = $p->y; $L = atan(Proj4php::$common . sinh(($x - $this->xs) / $this->n2) / cos(($y - $this->ys) / $this->n2)); $lat1 = asin(sin(($y - $this->ys) / $this->n2) / Proj4php::$common . cosh(($x - $this->xs) / $this->n2)); $LC = Proj4php::$common . latiso(0.0, $lat1, sin($lat1)); $p->x = $this->lc + $L / $this->rs; $p->y = Proj4php::$common . invlatiso($this->e, ($LC - $this->cp) / $this->rs); return $p; }
function transToGoogle($x, $y, $scale) { $TILE_SIZE = 2048 / $scale; //print_r($TILE_SIZE."<br>"); $point = array("x" => $TILE_SIZE / 2, "y" => $TILE_SIZE / 2); $pixelsPerLonDegree_ = $TILE_SIZE / 360; $pixelsPerLonRadian_ = $TILE_SIZE / (2 * pi()); $lng = $x / $pixelsPerLonDegree_; $latRadians = $y / -$pixelsPerLonRadian_; $lat = radiansToDegrees(2 * atan(exp($latRadians)) - pi() / 2); return array("X" => $lng, "Y" => $lat); }
/** * Calculates the geodetic distance between two points using the * Vincenty inverse formula for ellipsoids. * * @see http://en.wikipedia.org/wiki/Vincenty%27s_formulae * @see http://www.movable-type.co.uk/scripts/latlong-vincenty.html * @param mixed $from * @param mixed $to * @return Distance * @throws \RuntimeException */ public function distanceVincenty($from, $to) { $from = LatLng::normalize($from); $to = LatLng::normalize($to); $lat1 = $from->getLatitude(); $lng1 = $from->getLongitude(); $lat2 = $to->getLatitude(); $lng2 = $to->getLongitude(); $a = $this->ellipsoid->getSemiMajorAxis(); $b = $this->ellipsoid->getSemiMinorAxis(); $f = $this->ellipsoid->getFlattening(); $L = deg2rad($lng2 - $lng1); $U1 = atan((1 - $f) * tan(deg2rad($lat1))); $U2 = atan((1 - $f) * tan(deg2rad($lat2))); $sinU1 = sin($U1); $cosU1 = cos($U1); $sinU2 = sin($U2); $cosU2 = cos($U2); $lambda = $L; $iterLimit = 100; do { $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 new Distance(0); // co-incident points } $cosSigma = $sinU1 * $sinU2 + $cosU1 * $cosU2 * $cosLambda; $sigma = atan2($sinSigma, $cosSigma); $sinAlpha = $cosU1 * $cosU2 * $sinLambda / $sinSigma; $cosSqAlpha = 1 - $sinAlpha * $sinAlpha; if (0 != $cosSqAlpha) { $cos2SigmaM = $cosSigma - 2 * $sinU1 * $sinU2 / $cosSqAlpha; } else { $cos2SigmaM = 0.0; // Equatorial line } $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))); } while (abs($lambda - $lambdaP) > 1.0E-12 && --$iterLimit > 0); if ($iterLimit == 0) { throw new \RuntimeException('Vincenty 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); return new Distance($s); }
/** * @param Coordinate $point1 * @param Coordinate $point2 * * @throws NotMatchingEllipsoidException * @throws NotConvergingException * * @return float */ public function getDistance(Coordinate $point1, Coordinate $point2) { if ($point1->getEllipsoid() != $point2->getEllipsoid()) { throw new NotMatchingEllipsoidException("The ellipsoids for both coordinates must match"); } $lat1 = deg2rad($point1->getLat()); $lat2 = deg2rad($point2->getLat()); $lng1 = deg2rad($point1->getLng()); $lng2 = deg2rad($point2->getLng()); $a = $point1->getEllipsoid()->getA(); $b = $point1->getEllipsoid()->getB(); $f = 1 / $point1->getEllipsoid()->getF(); $L = $lng2 - $lng1; $U1 = atan((1 - $f) * tan($lat1)); $U2 = atan((1 - $f) * tan($lat2)); $iterationLimit = 100; $lambda = $L; $sinU1 = sin($U1); $sinU2 = sin($U2); $cosU1 = cos($U1); $cosU2 = cos($U2); do { $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.0; } $cosSigma = $sinU1 * $sinU2 + $cosU1 * $cosU2 * $cosLambda; $sigma = atan2($sinSigma, $cosSigma); $sinAlpha = $cosU1 * $cosU2 * $sinLambda / $sinSigma; $cosSqAlpha = 1 - $sinAlpha * $sinAlpha; if ($cosSqAlpha == 0) { $cos2SigmaM = 0; } else { $cos2SigmaM = $cosSigma - 2 * $sinU1 * $sinU2 / $cosSqAlpha; } $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))); } while (abs($lambda - $lambdaP) > 1.0E-12 && --$iterationLimit > 0); if ($iterationLimit == 0) { throw new NotConvergingException(); } $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); return round($s, 3); }
/** * 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; }
function wgs2u1992($lat, $lon) { //double Brad , Lrad, Lorad ,k, C, firad, Xmer, Ymer, Xgk, Ygk; // stale $E = 0.0818191910428; $Pi = 3.141592653589793; $Pi_2 = 1.570796327; //3.141592653589793238462643 / 2 // Pi / 2 $Pi_4 = 0.7853981634; // 3.141592653589793238462643 / 4 // Pi / 4 $Pi__180 = 0.01745329252; // 3.141592653589793238462643 / 180 $Ro = 6367449.14577; $a2 = 0.0008377318247344; $a4 = 7.608527788826E-7; $a6 = 1.197638019173E-9; $a8 = 2.44337624251E-12; // uklad UTM //#define mo 0.9996 //wspo#udnik skali na po#udniku #rodkowym //#define Lo (double)((((int)(lon/6)) * 6) + 3) // po#udnik #rodkowy // zone = (int)(lon+180/6)+1 //#define FE 500000 //False Easting //#define FN 0 //False Northing // uklad 1992 $mo = 0.9993; //wspo#udnik #rodkowy $Lo = 19.0; $FE = 500000; //False Easting $FN = -5300000; //False Northing $Brad = $lat * $Pi / 180; //Pi / 180; $Lrad = $lon * $Pi / 180; // Pi / 180; $Lorad = $Lo * $Pi / 180; // Pi / 180; //k = ((1 - E * sin(Brad)) / (1 + E * sin(Brad))) ^ (E / 2); // pasc //k = pow(((1 - E * sin(Brad)) / (1 + E * sin(Brad))) , (E / 2)); // c $k = exp($E / 2 * log((1 - $E * sin($Brad)) / (1 + $E * sin($Brad)))); $C = $k * tan($Brad / 2 + $Pi_4); $firad = 2 * atan($C) - $Pi_2; $Xmer = atan(sin($firad) / (cos($firad) * cos($Lrad - $Lorad))); $Ymer = 0.5 * log((1 + cos($firad) * sin($Lrad - $Lorad)) / (1 - cos($firad) * sin($Lrad - $Lorad))); $Xgk = $Ro * ($Xmer + $a2 * sin(2 * $Xmer) * cosh(2 * $Ymer) + $a4 * sin(4 * $Xmer) * cosh(4 * $Ymer) + $a6 * sin(6 * $Xmer) * cosh(6 * $Ymer) + $a8 * sin(8 * $Xmer) * cosh(8 * $Ymer)); $Ygk = $Ro * ($Ymer + $a2 * cos(2 * $Xmer) * sinh(2 * $Ymer) + $a4 * cos(4 * $Xmer) * sinh(4 * $Ymer) + $a6 * cos(6 * $Xmer) * sinh(6 * $Ymer) + $a8 * cos(8 * $Xmer) * sinh(8 * $Ymer)); $X = $mo * $Xgk + $FN; $Y = $mo * $Ygk + $FE; return array($X, $Y); }