public function inverse($p) { #$con, $phi; /* temporary angles */ #$delta_phi; /* difference between longitudes */ $max_iter = 6; /* maximun number of iterations */ if ($this->sphere) { /* spherical form */ $f = exp($p->x / ($this->a * $this->k0)); $g = 0.5 * ($f - 1 / $f); $temp = $this->lat0 + $p->y / ($this->a * $this->k0); $h = cos($temp); $con = sqrt((1.0 - $h * $h) / (1.0 + $g * $g)); $lat = Sourcemap_Proj::asinz($con); if ($temp < 0) { $lat = -$lat; } if ($g == 0 && $h == 0) { $lon = $this->long0; } else { $lon = Sourcemap_Proj::adjust_lon(atan2($g, $h) + $this->long0); } } else { // ellipsoidal form $x = $p->x - $this->x0; $y = $p->y - $this->y0; $con = ($this->ml0 + $y / $this->k0) / $this->a; $phi = $con; for ($i = 0; true; $i++) { $delta_phi = ($con + $this->e1 * sin(2.0 * $phi) - $this->e2 * sin(4.0 * $phi) + $this->e3 * sin(6.0 * $phi)) / $this->e0 - $phi; $phi += $delta_phi; if (abs($delta_phi) <= Sourcemap_Proj::EPSLN) { break; } if ($i >= $max_iter) { throw new Exception("Latitude failed to converge."); #return(95); } } if (abs($phi) < Sourcemap_Proj::HALF_PI) { // sincos(phi, &sin_phi, &cos_phi); $sin_phi = sin($phi); $cos_phi = cos($phi); $tan_phi = tan($phi); $c = $this->ep2 * pow($cos_phi, 2); $cs = pow($c, 2); $t = pow($tan_phi, 2); $ts = pow($t, 2); $con = 1.0 - $this->es * pow($sin_phi, 2); $n = $this->a / sqrt($con); $r = $n * (1.0 - $this->es) / $con; $d = $x / ($n * $this->k0); $ds = pow($d, 2); $lat = $phi - $n * $tan_phi * $ds / $r * (0.5 - $ds / 24.0 * (5.0 + 3.0 * $t + 10.0 * $c - 4.0 * $cs - 9.0 * $this->ep2 - $ds / 30.0 * (61.0 + 90.0 * $t + 298.0 * $c + 45.0 * $ts - 252.0 * $this->ep2 - 3.0 * $cs))); $lon = Sourcemap_Proj::adjust_lon($this->long0 + $d * (1.0 - $ds / 6.0 * (1.0 + 2.0 * $t + $c - $ds / 20.0 * (5.0 - 2.0 * $c + 28.0 * $t - 3.0 * $cs + 8.0 * $this->ep2 + 24.0 * $ts))) / $cos_phi); } else { $lat = Sourcemap_Proj::HALF_PI * Sourcemap_Proj::sign($y); $lon = $this->long0; } } $p->x = $lon; $p->y = $lat; return $p; }