/** * Convert this grid reference into a latitude and longitude * * @return */ function toLatLng() { $airy1830 = new RefEll(6377563.396, 6356256.909); $OSGB_F0 = 0.9996012717; $N0 = -100000.0; $E0 = 400000.0; $phi0 = deg2rad(49.0); $lambda0 = deg2rad(-2.0); $a = $airy1830->maj; $b = $airy1830->min; $eSquared = $airy1830->ecc; $phi = 0.0; $lambda = 0.0; $E = $this->easting; $N = $this->northing; $n = ($a - $b) / ($a + $b); $M = 0.0; $phiPrime = ($N - $N0) / ($a * $OSGB_F0) + $phi0; do { $M = $b * $OSGB_F0 * ((1 + $n + 5.0 / 4.0 * $n * $n + 5.0 / 4.0 * $n * $n * $n) * ($phiPrime - $phi0) - (3 * $n + 3 * $n * $n + 21.0 / 8.0 * $n * $n * $n) * sin($phiPrime - $phi0) * cos($phiPrime + $phi0) + (15.0 / 8.0 * $n * $n + 15.0 / 8.0 * $n * $n * $n) * sin(2.0 * ($phiPrime - $phi0)) * cos(2.0 * ($phiPrime + $phi0)) - 35.0 / 24.0 * $n * $n * $n * sin(3.0 * ($phiPrime - $phi0)) * cos(3.0 * ($phiPrime + $phi0))); $phiPrime += ($N - $N0 - $M) / ($a * $OSGB_F0); } while ($N - $N0 - $M >= 0.001); $v = $a * $OSGB_F0 * pow(1.0 - $eSquared * sinSquared($phiPrime), -0.5); $rho = $a * $OSGB_F0 * (1.0 - $eSquared) * pow(1.0 - $eSquared * sinSquared($phiPrime), -1.5); $etaSquared = $v / $rho - 1.0; $VII = tan($phiPrime) / (2 * $rho * $v); $VIII = tan($phiPrime) / (24.0 * $rho * pow($v, 3.0)) * (5.0 + 3.0 * tanSquared($phiPrime) + $etaSquared - 9.0 * tanSquared($phiPrime) * $etaSquared); $IX = tan($phiPrime) / (720.0 * $rho * pow($v, 5.0)) * (61.0 + 90.0 * tanSquared($phiPrime) + 45.0 * tanSquared($phiPrime) * tanSquared($phiPrime)); $X = sec($phiPrime) / $v; $XI = sec($phiPrime) / (6.0 * $v * $v * $v) * ($v / $rho + 2 * tanSquared($phiPrime)); $XII = sec($phiPrime) / (120.0 * pow($v, 5.0)) * (5.0 + 28.0 * tanSquared($phiPrime) + 24.0 * tanSquared($phiPrime) * tanSquared($phiPrime)); $XIIA = sec($phiPrime) / (5040.0 * pow($v, 7.0)) * (61.0 + 662.0 * tanSquared($phiPrime) + 1320.0 * tanSquared($phiPrime) * tanSquared($phiPrime) + 720.0 * tanSquared($phiPrime) * tanSquared($phiPrime) * tanSquared($phiPrime)); $phi = $phiPrime - $VII * pow($E - $E0, 2.0) + $VIII * pow($E - $E0, 4.0) - $IX * pow($E - $E0, 6.0); $lambda = $lambda0 + $X * ($E - $E0) - $XI * pow($E - $E0, 3.0) + $XII * pow($E - $E0, 5.0) - $XIIA * pow($E - $E0, 7.0); return new LatLng(rad2deg($phi), rad2deg($lambda)); }
/** * Convert this LatLng object from OSGB36 datum to WGS84 datum. */ function OSGB36ToWGS84() { $airy1830 = new RefEll(6377563.396, 6356256.909); $a = $airy1830->maj; $b = $airy1830->min; $eSquared = $airy1830->ecc; $phi = deg2rad($this->lat); $lambda = deg2rad($this->lng); $v = $a / sqrt(1 - $eSquared * coordHelpers::sinSquared($phi)); $H = 0; // height $x = ($v + $H) * cos($phi) * cos($lambda); $y = ($v + $H) * cos($phi) * sin($lambda); $z = ((1 - $eSquared) * $v + $H) * sin($phi); $tx = 446.448; $ty = -124.157; $tz = 542.0599999999999; $s = -2.04894E-5; $rx = deg2rad(4.172222E-5); $ry = deg2rad(6.861111000000001E-5); $rz = deg2rad(0.00023391666); $xB = $tx + $x * (1 + $s) + -$rx * $y + $ry * $z; $yB = $ty + $rz * $x + $y * (1 + $s) + -$rx * $z; $zB = $tz + -$ry * $x + $rx * $y + $z * (1 + $s); $wgs84 = new RefEll(6378137.0, 6356752.3141); $a = $wgs84->maj; $b = $wgs84->min; $eSquared = $wgs84->ecc; $lambdaB = rad2deg(atan($yB / $xB)); $p = sqrt($xB * $xB + $yB * $yB); $phiN = atan($zB / ($p * (1 - $eSquared))); for ($i = 1; $i < 10; $i++) { $v = $a / sqrt(1 - $eSquared * sinSquared($phiN)); $phiN1 = atan(($zB + $eSquared * $v * sin($phiN)) / $p); $phiN = $phiN1; } $phiB = rad2deg($phiN); $this->lat = $phiB; $this->lng = $lambdaB; }