예제 #1
0
 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;
 }