public function forward($p) { /* Forward equations ----------------- */ $lon = $p->x; $lat = $p->y; $delta_lon = Common::adjust_lon($lon - $this->long0); $theta = $lat; $con = Common::PI * sin($lat); /* Iterate using the Newton-Raphson method to find theta ----------------------------------------------------- */ for ($i = 0; true; ++$i) { $delta_theta = -($theta + sin($theta) - $con) / (1.0 + cos($theta)); $theta += $delta_theta; if (abs($delta_theta) < Common::EPSLN) { break; } if ($i >= 50) { Proj4php::reportError("moll:Fwd:IterationError"); //return(241); } } $theta /= 2.0; /* If the latitude is 90 deg, force the x coordinate to be "0 . false easting" this is done here because of precision problems with "cos(theta)" -------------------------------------------------------------------------- */ if (Common::PI / 2 - abs($lat) < Common::EPSLN) { $delta_lon = 0; } $x = 0.900316316158 * $this->a * $delta_lon * cos($theta) + $this->x0; $y = 1.4142135623731 * $this->a * sin($theta) + $this->y0; $p->x = $x; $p->y = $y; return $p; }
public function inverse($p) { $p->x -= $this->x0; $p->y -= $this->y0; $lat = $p->y / $this->a; if (abs($lat) > Common::HALF_PI) { Proj4php::reportError("equi:Inv:DataError"); } $lon = Common::adjust_lon($this->long0 + $p->x / ($this->a * cos($this->lat0))); $p->x = $lon; $p->y = $lat; }
/** * @return void */ public function init() { // Initialise dependant projection first. parent::init(); if (!$this->rc) { Proj4php::reportError("sterea:init:E_ERROR_0"); return; } $this->sinc0 = sin($this->phic0); $this->cosc0 = cos($this->phic0); $this->R2 = 2.0 * $this->rc; if (!$this->title) { $this->title = "Oblique Stereographic Alternative"; } }
/** * @param type $p * @return null */ public function inverse($p) { $DEL_TOL = 1.0E-14; $lon = $p->x / $this->C; $lat = $p->y; $num = pow(tan(0.5 * $lat + Common::FORTPI) / $this->K, 1.0 / $this->C); for ($i = Common::MAX_ITER; $i > 0; --$i) { $lat = 2.0 * atan($num * Common::srat($this->e * sin($p->y), -0.5 * $this->e)) - Common::HALF_PI; if (abs($lat - $p->y) < $DEL_TOL) { break; } $p->y = $lat; } // convergence failed if (!$i) { Proj4php::reportError("gauss:inverse:convergence failed"); return null; } $p->x = $lon; $p->y = $lat; return $p; }
/** * * @param type $p * @return type */ public function inverse($p) { $p->x -= $this->x0; $p->y -= $this->y0; $rh = sqrt($p->x * $p->x + $p->y * $p->y); if ($rh > 2.0 * Common::HALF_PI * $this->a) { Proj4php::reportError("aeqdInvDataError"); return; } $z = $rh / $this->a; $sinz = sin($z); $cosz = cos($z); $lon = $this->long0; #$lat; if (abs($rh) <= Common::EPSLN) { $lat = $this->lat0; } else { $lat = Common::asinz($cosz * $this->sin_p12 + $p->y * $sinz * $this->cos_p12 / $rh); $con = abs($this->lat0) - Common::HALF_PI; if (abs($con) <= Common::EPSLN) { if ($this->lat0 >= 0.0) { $lon = Common::adjust_lon($this->long0 + atan2($p->x, -$p->y)); } else { $lon = Common::adjust_lon($this->long0 - atan2(-$p->x, $p->y)); } } else { $con = $cosz - $this->sin_p12 * sin($lat); if (abs($con) < Common::EPSLN && abs($p->x) < Common::EPSLN) { //no-op, just keep the lon value as is } else { #$temp = atan2( ($p->x * $sinz * $this->cos_p12 ), ($con * $rh ) ); // $temp is unused !?! $lon = Common::adjust_lon($this->long0 + atan2($p->x * $sinz * $this->cos_p12, $con * $rh)); } } } $p->x = $lon; $p->y = $lat; return $p; }
function phi4z($eccent, $e0, $e1, $e2, $e3, $a, $b, &$c, $phi) { /* $sinphi; $sin2ph; $tanph; $ml; $mlp; $con1; $con2; $con3; $dphi; $i; */ $phi = $a; for ($i = 1; $i <= 15; $i++) { $sinphi = sin($phi); $tanphi = tan($phi); $c = $tanphi * sqrt(1.0 - $eccent * $sinphi * $sinphi); $sin2ph = sin(2.0 * $phi); /* ml = e0 * *phi - e1 * sin2ph + e2 * sin (4.0 * *phi); mlp = e0 - 2.0 * e1 * cos (2.0 * *phi) + 4.0 * e2 * cos (4.0 * *phi); */ $ml = $e0 * $phi - $e1 * $sin2ph + $e2 * sin(4.0 * $phi) - $e3 * sin(6.0 * $phi); $mlp = $e0 - 2.0 * $e1 * cos(2.0 * $phi) + 4.0 * $e2 * cos(4.0 * $phi) - 6.0 * $e3 * cos(6.0 * $phi); $con1 = 2.0 * $ml + $c * ($ml * $ml + $b) - 2.0 * $a * ($c * $ml + 1.0); $con2 = $eccent * $sin2ph * ($ml * $ml + $b - 2.0 * $a * $ml) / (2.0 * $c); $con3 = 2.0 * ($a - $ml) * ($c * $mlp - 2.0 / $sin2ph) - 2.0 * $mlp; $dphi = $con1 / ($con2 + $con3); $phi += $dphi; if (abs($dphi) <= 1.0E-10) { return $phi; } } Proj4php::reportError("phi4z: No convergence"); return null; }
public function forward($p) { /* $sinphi; $cosphi; // sin and cos value $dlon; // delta longitude value $coslon; // cos of longitude $ksp; // scale factor $g; */ $lon = $p->x; $lat = $p->y; /* Forward equations ----------------- */ $dlon = Common::adjust_lon($lon - $this->long0); $sinphi = sin($lat); $cosphi = cos($lat); $coslon = cos($dlon); $g = $this->sin_p14 * $sinphi + $this->cos_p14 * $cosphi * $coslon; $ksp = 1.0; if (g > 0 || abs(g) <= Common::EPSLN) { $x = $this->x0 + $this->a * $ksp * $cosphi * sin($dlon) / $g; $y = $this->y0 + $this->a * $ksp * ($this->cos_p14 * $sinphi - $this->sin_p14 * $cosphi * $coslon) / $g; } else { Proj4php::reportError("orthoFwdPointError"); // Point is in the opposing hemisphere and is unprojectable // We still need to return a reasonable point, so we project // to infinity, on a bearing // equivalent to the northern hemisphere equivalent // This is a reasonable approximation for short shapes and lines that // straddle the horizon. $x = $this->x0 + $this->infinity_dist * $cosphi * sin($dlon); $y = $this->y0 + $this->infinity_dist * ($this->cos_p14 * $sinphi - $this->sin_p14 * $cosphi * $coslon); } $p->x = $x; $p->y = $y; return $p; }
public function inverse($p) { $x = $p->x - $this->x0; $y = $p->y - $this->y0; if ($this->sphere) { $lat = Common::HALF_PI - 2.0 * atan(exp(-$y / $this->a * $this->k0)); } else { $ts = exp(-$y / ($this->a * $this->k0)); $lat = Common::phi2z($this->e, $ts); if ($lat == -9999) { Proj4php::reportError("merc:inverse: lat = -9999"); return null; } } $lon = Common::adjust_lon($this->long0 + $x / ($this->a * $this->k0)); $p->x = $lon; $p->y = $lat; return $p; }
/** * * @param type $p * @return type */ public function inverse($p) { /* $rh; // height above ellipsoid $z; // angle $sinz; $cosz; // sin of z and cos of z $temp; $con; $lon; $lat; */ /* Inverse equations ----------------- */ $p->x -= $this->x0; $p->y -= $this->y0; $rh = sqrt($p->x * $p->x + $p->y * $p->y); if ($rh > $this->a + 1.0E-7) { Proj4php::reportError("orthoInvDataError"); } $z = Common::asinz($rh / $this->a); $sinz = sin($z); $cosz = cos($z); $lon = $this->long0; if (abs($rh) <= Common::EPSLN) { $lat = $this->lat0; } $lat = Common::asinz($cosz * $this->sin_p14 + $p->y * $sinz * $this->cos_p14 / $rh); $con = abs($this->lat0) - Common::HALF_PI; if (abs(con) <= Common::EPSLN) { if ($this->lat0 >= 0) { $lon = Common::adjust_lon($this->long0 + atan2($p->x, -$p->y)); } else { $lon = Common::adjust_lon($this->long0 - atan2(-$p->x, $p->y)); } } $con = $cosz - $this->sin_p14 * sin($lat); $p->x = $lon; $p->y = $lat; return $p; }
/** * source coordinate system definition. * destination coordinate system definition. * point to transform in geodetic coordinates (long, lat, height). */ public function datum_transform(Datum $source, Datum $dest, Point $point) { // Short cut if the datums are identical. if ($source->compare_datums($dest)) { // In this case, zero is sucess, // whereas cs_compare_datums returns 1 to indicate TRUE // confusing, should fix this. return $point; } // Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest if ($source->datum_type == Common::PJD_NODATUM || $dest->datum_type == Common::PJD_NODATUM) { return $point; } // If this datum requires grid shifts, then apply it to geodetic coordinates. if ($source->datum_type == Common::PJD_GRIDSHIFT) { Proj4php::reportError("Grid shift transformations are not implemented yet.\r\n"); throw new Exception("ERROR: Grid shift transformations are not implemented yet."); } if ($dest->datum_type == Common::PJD_GRIDSHIFT) { Proj4php::reportError("Grid shift transformations are not implemented yet.\r\n"); throw new Exception("ERROR: Grid shift transformations are not implemented yet."); } // Do we need to go through geocentric coordinates? if ($source->es != $dest->es || $source->a != $dest->a || $source->datum_type == Common::PJD_3PARAM || $source->datum_type == Common::PJD_7PARAM || $dest->datum_type == Common::PJD_3PARAM || $dest->datum_type == Common::PJD_7PARAM) { // Convert to geocentric coordinates. $source->geodetic_to_geocentric($point); // CHECK_RETURN; // Convert between datums if ($source->datum_type == Common::PJD_3PARAM || $source->datum_type == Common::PJD_7PARAM) { $source->geocentric_to_wgs84($point); // CHECK_RETURN; } if ($dest->datum_type == Common::PJD_3PARAM || $dest->datum_type == Common::PJD_7PARAM) { $dest->geocentric_from_wgs84($point); // CHECK_RETURN; } // Convert back to geodetic coordinates $dest->geocentric_to_geodetic($point); // CHECK_RETURN; } // Apply grid shift to destination if required if ($dest->datum_type == Common::PJD_GRIDSHIFT) { Proj4php::reportError("Grid shift transformations are not implemented yet.\r\n"); throw new Exception("ERROR: Grid shift transformations are not implemented yet."); // pj_apply_gridshift(pj_param(dest.params,"snadgrids").s, 1, point); // CHECK_RETURN; } return $point; }
public function forward($p) { /* $theta; // angle $sin_phi; $cos_phi; // sin and cos value $b; // temporary values $c; $t; $tq; // temporary values $con; $n; $ml; // cone constant, small m $q; $us; $vl; $ul; $vs; $s; $dlon; $ts1; */ $lon = $p->x; $lat = $p->y; /* Forward equations ----------------- */ $sin_phi = sin($lat); $dlon = Common::adjust_lon($lon - $this->longc); $vl = sin($this->bl * $dlon); if (abs(abs($lat) - Common::HALF_PI) > Common::EPSLN) { $ts1 = Common::tsfnz($this->e, $lat, $sin_phi); $q = $this->el / pow($ts1, $this->bl); $s = 0.5 * ($q - 1.0 / $q); $t = 0.5 * ($q + 1.0 / $q); $ul = ($s * $this->singam - $vl * $this->cosgam) / $t; $con = cos($this->bl * $dlon); if (abs(con) < 1.0E-7) { $us = $this->al * $this->bl * $dlon; } else { $us = $this->al * atan(($s * $this->cosgam + $vl * $this->singam) / $con) / $this->bl; if ($con < 0) { $us = $us + Common::PI * $this->al / $this->bl; } } } else { if ($lat >= 0) { $ul = $this->singam; } else { $ul = -$this->singam; } $us = $this->al * $lat / $this->bl; } if (abs(abs($ul) - 1.0) <= Common::EPSLN) { //alert("Point projects into infinity","omer-for"); Proj4php::reportError("omercFwdInfinity"); //return(205); } $vs = 0.5 * $this->al * log((1.0 - $ul) / (1.0 + $ul)) / $this->bl; $us = $us - $this->u; $p->x = $this->x0 + $vs * $this->cosaz + $us * $this->sinaz; $p->y = $this->y0 + $us * $this->cosaz - $vs * $this->sinaz; return $p; }
public function inverse($p) { $p->x -= $this->x0; $p->y -= $this->y0; $x = $p->x / $this->a; $y = $p->y / $this->a; if ($this->sphere) { $cosz = 0.0; #$rh; $sinz = 0.0; $rh = sqrt($x * $x + $y * $y); $phi = $rh * 0.5; if ($phi > 1.0) { Proj4php::reportError("laea:Inv:DataError"); return null; } $phi = 2.0 * asin($phi); if ($this->mode == $this->OBLIQ || $this->mode == $this->EQUIT) { $sinz = sin($phi); $cosz = cos($phi); } switch ($this->mode) { case $this->EQUIT: $phi = abs($rh) <= Common::EPSLN ? 0.0 : asin($y * $sinz / $rh); $x *= $sinz; $y = $cosz * $rh; break; case $this->OBLIQ: $phi = abs($rh) <= Common::EPSLN ? $this->phi0 : asin($cosz * $this->sinph0 + $y * $sinz * $this->cosph0 / $rh); $x *= $sinz * $this->cosph0; $y = ($cosz - sin($phi) * $this->sinph0) * $rh; break; case $this->N_POLE: $y = -$y; $phi = Common::HALF_PI - $phi; break; case $this->S_POLE: $phi -= Common::HALF_PI; break; } $lam = $y == 0.0 && ($this->mode == $this->EQUIT || $this->mode == $this->OBLIQ) ? 0.0 : atan2($x, $y); } else { /* $cCe; $sCe; $q; $rho; */ $ab = 0.0; switch ($this->mode) { case $this->EQUIT: case $this->OBLIQ: $x /= $this->dd; $y *= $this->dd; $rho = sqrt($x * $x + $y * $y); if ($rho < Common::EPSLN) { $p->x = 0.0; $p->y = $this->phi0; return $p; } $sCe = 2.0 * asin(0.5 * $rho / $this->rq); $cCe = cos($sCe); $x *= $sCe = sin($sCe); if ($this->mode == $this->OBLIQ) { $ab = $cCe * $this->sinb1 + $y * $sCe * $this->cosb1 / $rho; $q = $this->qp * $ab; $y = $rho * $this->cosb1 * $cCe - $y * $this->sinb1 * $sCe; } else { $ab = $y * $sCe / $rho; $q = $this->qp * $ab; $y = $rho * $cCe; } break; case $this->N_POLE: $y = -$y; case $this->S_POLE: $q = $x * $x + $y * $y; if (!$q) { $p->x = 0.0; $p->y = $this->phi0; return $p; } /* q = $this->qp - q; */ $ab = 1.0 - $q / $this->qp; if ($this->mode == $this->S_POLE) { $ab = -$ab; } break; } $lam = atan2($x, $y); $phi = $this->authlat(asin($ab), $this->apa); } /* $Rh = sqrt($p->x *$p->x +$p->y * $p->y); $temp = Rh / (2.0 * $this->a); if (temp > 1) { Proj4php::reportError("laea:Inv:DataError"); return null; } $z = 2.0 * Common::asinz(temp); $sin_z=sin(z); $cos_z=cos(z); $lon =$this->long0; if (abs(Rh) > Common::EPSLN) { $lat = Common::asinz($this->sin_lat_o * cos_z +$this-> cos_lat_o * sin_z *$p->y / Rh); $temp =abs($this->lat0) - Common::HALF_PI; if (abs(temp) > Common::EPSLN) { temp = cos_z -$this->sin_lat_o * sin(lat); if(temp!=0.0) lon=Common::adjust_lon($this->long0+atan2($p->x*sin_z*$this->cos_lat_o,temp*Rh)); } else if ($this->lat0 < 0.0) { lon = Common::adjust_lon($this->long0 - atan2(-$p->x,$p->y)); } else { lon = Common::adjust_lon($this->long0 + atan2($p->x, -$p->y)); } } else { lat = $this->lat0; } */ //return(OK); $p->x = Common::adjust_lon($this->long0 + $lam); $p->y = $phi; return $p; }
/** Transverse Mercator Inverse - x/y to long/lat */ public function inverse($p) { #$phi; /* temporary angles */ #$delta_phi; /* difference between longitudes */ $max_iter = 6; /* maximun number of iterations */ if (isset($this->sphere) && $this->sphere === true) { /* 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 = Common::asinz($con); if ($temp < 0) { $lat = -$lat; } if ($g == 0 && $h == 0) { $lon = $this->long0; } else { $lon = Common::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) <= Common::EPSLN) { break; } if ($i >= $max_iter) { Proj4php::reportError("tmerc:inverse: Latitude failed to converge"); return 95; } } // for() if (abs($phi) < Common::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 = Common::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 = Common::HALF_PI * Common::sign($y); $lon = $this->long0; } } $p->x = $lon; $p->y = $lat; return $p; }
public function forward(Point $p) { list($lon, $lat) = $p->toArray(); // convert to radians if ($lat <= 90.0 && $lat >= -90.0 && $lon <= 180.0 && $lon >= -180.0) { //lon = lon * Common::D2R; //lat = lat * Common::D2R; } else { Proj4php::reportError('lcc:forward: llInputOutOfRange: ' . $lon . ' : ' . $lat); return; } $con = abs(abs($lat) - Common::HALF_PI); if ($con > Common::EPSLN) { $ts = Common::tsfnz($this->e, $lat, sin($lat)); $rh1 = $this->a * $this->f0 * pow($ts, $this->ns); } else { $con = $lat * $this->ns; if ($con <= 0) { Proj4php::reportError('lcc:forward: No Projection'); return; } $rh1 = 0; } $theta = $this->ns * Common::adjust_lon($lon - $this->long0); $p->x = $this->k0 * ($rh1 * sin($theta)) + $this->x0; $p->y = $this->k0 * ($this->rh - $rh1 * cos($theta)) + $this->y0; return $p; }
/** * Function: defsFailed * Report an error in loading the proj file. Initialization of the Proj * object has failed and the readyToUse flag will never be set. * */ public function loadProjCodeFailure($projName) { Proj4php::reportError("failed to find projection file for: " . $projName); //TBD initialize with identity transforms so proj will still work? }
/** * Stereographic forward equations--mapping lat,long to x,y * * @param type $p * @return type */ public function forward($p) { $lon = $p->x; $lon = Common::adjust_lon($lon - $this->long0); $lat = $p->y; if ($this->sphere) { /* $sinphi; $cosphi; $coslam; $sinlam; */ $sinphi = sin($lat); $cosphi = cos($lat); $coslam = cos($lon); $sinlam = sin($lon); switch ($this->mode) { case $this->EQUIT: $y = 1.0 + $cosphi * $coslam; if (y <= Common::EPSLN) { Proj4php::reportError("stere:forward:Equit"); } $y = $this->akm1 / $y; $x = $y * $cosphi * $sinlam; $y *= $sinphi; break; case $this->OBLIQ: $y = 1.0 + $this->sinph0 * $sinphi + $this->cosph0 * $cosphi * $coslam; if ($y <= Common::EPSLN) { Proj4php::reportError("stere:forward:Obliq"); } $y = $this->akm1 / $y; $x = $y * $cosphi * $sinlam; $y *= $this->cosph0 * $sinphi - $this->sinph0 * $cosphi * $coslam; break; case $this->N_POLE: $coslam = -$coslam; $lat = -$lat; //Note no break here so it conitnues through S_POLE //Note no break here so it conitnues through S_POLE case $this->S_POLE: if (abs($lat - Common::HALF_PI) < $this->TOL) { Proj4php::reportError("stere:forward:S_POLE"); } $y = $this->akm1 * tan(Common::FORTPI + 0.5 * $lat); $x = $sinlam * $y; $y *= $coslam; break; } } else { $coslam = cos($lon); $sinlam = sin($lon); $sinphi = sin($lat); if ($this->mode == $this->OBLIQ || $this->mode == $this->EQUIT) { $Xt = 2.0 * atan($this->ssfn_($lat, $sinphi, $this->e)); $sinX = sin($Xt - Common::HALF_PI); $cosX = cos($Xt); } switch ($this->mode) { case $this->OBLIQ: $A = $this->akm1 / ($this->cosX1 * (1.0 + $this->sinX1 * $sinX + $this->cosX1 * $cosX * $coslam)); $y = $A * ($this->cosX1 * $sinX - $this->sinX1 * $cosX * $coslam); $x = $A * $cosX; break; case $this->EQUIT: $A = 2.0 * $this->akm1 / (1.0 + $cosX * $coslam); $y = $A * $sinX; $x = $A * $cosX; break; case $this->S_POLE: $lat = -$lat; $coslam = -$coslam; $sinphi = -$sinphi; case $this->N_POLE: $x = $this->akm1 * Common::tsfnz($this->e, $lat, $sinphi); $y = -$x * $coslam; break; } $x = $x * $sinlam; } $p->x = $x * $this->a + $this->x0; $p->y = $y * $this->a + $this->y0; return $p; }
/** * * @param type $p * @return type */ 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)) - Common::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) { Proj4php::reportError("omercFwdInfinity"); return; } //S = log(tan(PI / 4.0 + phy / 2.0)); $S = 1.0 / $this->alpha * (log(tan(Common::PI / 4.0 + $b / 2.0)) - $this->K) + $this->e * log(tan(Common::PI / 4.0 + asin($this->e * sin($phy)) / 2.0)); $prevPhy = $phy; $phy = 2.0 * atan(exp($S)) - Common::PI / 2.0; } $p->x = $lambda; $p->y = $phy; return $p; }
/** * Function to compute phi1, the latitude for the inverse of the Albers Conical Equal-Area projection. * * @param type $eccent * @param type $qs * @return $phi or null on Convergence error */ public function phi1z($eccent, $qs) { $phi = Common::asinz(0.5 * $qs); if ($eccent < Common::EPSLN) { return $phi; } $eccnts = $eccent * $eccent; for ($i = 1; $i <= 25; ++$i) { $sinphi = sin($phi); $cosphi = cos($phi); $con = $eccent * $sinphi; $com = 1.0 - $con * $con; $dphi = 0.5 * $com * $com / $cosphi * ($qs / (1.0 - $eccnts) - $sinphi / $com + 0.5 / $eccent * log((1.0 - $con) / (1.0 + $con))); $phi = $phi + $dphi; if (abs($dphi) <= 1.0E-7) { return $phi; } } Proj4php::reportError("aea:phi1z:Convergence error"); return null; }
/** * Function: parseWKT * Parses a WKT string to get initialization parameters. */ public function parseWKT($wkt) { $wktSections = self::ParseWKTIntoSections($wkt); if (empty($wktSections)) { return; } $wktObject = $wktSections[0]; $wktName = $wktSections[1]; $wktArray = $wktSections[2]; // Do something based on the type of the wktObject being parsed. // Add in variations in the spelling as required. switch ($wktObject) { case 'LOCAL_CS': $this->projName = 'identity'; $this->localCS = true; $this->srsCode = $wktName; break; case 'GEOGCS': $this->projName = 'longlat'; $this->geocsCode = $wktName; if (!$this->srsCode) { $this->srsCode = $wktName; } break; case 'PROJCS': $this->srsCode = $wktName; break; case 'GEOCCS': break; case 'PROJECTION': if (key_exists($wktName, Proj4php::$wktProjections)) { $this->projName = Proj4php::$wktProjections[$wktName]; } else { Proj4php::reportError('Undefined Projection: ' . $wktName); } break; case 'DATUM': $this->datumName = $wktName; if (key_exists($wktName, Proj4php::$wktDatums)) { $this->datumCode = Proj4php::$wktDatums[$wktName]; } break; case 'LOCAL_DATUM': $this->datumCode = 'none'; break; case 'SPHEROID': if (key_exists($wktName, Proj4php::$wktEllipsoids)) { $this->ellps = Proj4php::$wktEllipsoids[$wktName]; } else { $this->ellps = $wktName; $this->a = floatval(array_shift($wktArray)); $this->rf = floatval(array_shift($wktArray)); } break; case 'PRIMEM': // to radians? $this->from_greenwich = floatval(array_shift($wktArray)) * Common::D2R; break; case 'UNIT': $this->units = $wktName; $this->parseWKTToMeter($wktName, $wktArray); $this->parseWKTToRads($wktName, $wktArray); break; case 'PARAMETER': $name = strtolower($wktName); $value = floatval(array_shift($wktArray)); // there may be many variations on the wktName values, add in case // statements as required switch ($name) { case 'false_easting': $this->x0 = $value; if (isset($this->to_meter)) { $this->x0 = $this->to_meter * $this->x0; } break; case 'false_northing': $this->y0 = $value; if (isset($this->to_meter)) { $this->y0 = $this->to_meter * $this->y0; } break; case 'scale_factor': $this->k0 = $value; break; case 'central_meridian': case 'longitude_of_center': // SR-ORG:10 $this->longc = $value * $this->to_rads; case 'longitude_of_origin': // SR-ORG:118 $this->long0 = $value * $this->to_rads; break; case 'latitude_of_origin': case 'latitude_of_center': // SR-ORG:10 $this->lat0 = $value * $this->to_rads; if ($this->projName == 'merc' || $this->projName == 'eqc') { $this->lat_ts = $value * $this->to_rads; //EPSG:3752 (merc), EPSG:3786 (eqc), SR-ORG:7710" (stere) //this cannot be set here in: SR-ORG:6647 (stere) } break; case 'standard_parallel_1': $this->lat1 = $value * $this->to_rads; $this->lat_ts = $value * $this->to_rads; //SR-ORG:22 break; case 'standard_parallel_2': $this->lat2 = $value * $this->to_rads; break; case 'rectified_grid_angle': if (!isset($this->alpha)) { //I'm not sure if this should be set here. //EPSG:3167 defineds azimuth and rectified_grid_angle. both are similar (azimuth is closer) //SR-ORG:7172 defines both, and both are 90. $this->alpha = $value * $this->to_rads; } break; case 'azimuth': $this->alpha = $value * $this->to_rads; //EPSG:2057 break; case 'more_here': break; default: break; } break; case 'TOWGS84': $this->datum_params = $wktArray; break; //DGR 2010-11-12: AXIS //DGR 2010-11-12: AXIS case 'AXIS': $name = strtolower($wktName); $value = array_shift($wktArray); switch ($value) { case 'EAST': $value = 'e'; break; case 'WEST': $value = 'w'; break; case 'NORTH': $value = 'n'; break; case 'SOUTH': $value = 's'; break; case 'UP': $value = 'u'; break; case 'DOWN': $value = 'd'; break; case 'OTHER': default: //throw new Exception("Unknown Axis ".$name." Value: ".$value); $value = ' '; break; // FIXME } if (!$this->axis) { $this->axis = "enu"; } switch ($name) { case 'e(x)': // EPSG:2140 // EPSG:2140 case 'x': $this->axis = $value . substr($this->axis, 1, 2); break; case 'n(y)': case 'y': $this->axis = substr($this->axis, 0, 1) . $value . substr($this->axis, 2, 1); break; case 'z': $this->axis = substr($this->axis, 0, 2) . $value; break; // Here is a list of other axis that exist in wkt definitions. are they useful? // Here is a list of other axis that exist in wkt definitions. are they useful? case 'geodetic latitude': //from SR-ORG:29 //from SR-ORG:29 case 'latitude': case 'lat': case 'geodetic longitude': case 'longitude': case 'long': case 'lon': case 'e': case 'n': //SR-ORG:4705 //SR-ORG:4705 case 'gravity-related height': case 'geocentric y': //SR-ORG:7910 //SR-ORG:7910 case 'east': case 'north': //SR-ORG:4705 //SR-ORG:4705 case 'ellipsoidal height': //EPSG:3823 //EPSG:3823 case 'easting': case 'northing': case 'southing': //SR-ORG:8262 break; default: throw new Exception("Unknown Axis Name: " . $name); //for testing break; } case 'EXTENSION': $name = strtolower($wktName); $value = array_shift($wktArray); switch ($name) { case 'proj4': // WKT can define a proj4 definition. for example SR-ORG:6 $this->defData = $value; break; default: break; } break; case 'MORE_HERE': break; default: break; } foreach ($wktArray as $wktArrayContent) { $this->parseWKT($wktArrayContent); } }
/** * calculate lat/lon from xy * * @param Point $p * @return Point $p */ public function inverse($p) { /* Transformation */ /* revert y, x */ $tmp = $p->x; $p->x = $p->y; $p->y = $tmp; if ($this->czech) { $p->y *= -1.0; $p->x *= -1.0; } $ro = sqrt($p->x * $p->x + $p->y * $p->y); $eps = atan2($p->y, $p->x); $d = $eps / sin($this->s0); $s = 2.0 * (atan(pow($this->ro0 / $ro, 1.0 / $this->n) * tan($this->s0 / 2.0 + $this->s45)) - $this->s45); $u = asin(cos($this->ad) * sin($s) - sin($this->ad) * cos($s) * cos($d)); $deltav = asin(cos($s) * sin($d) / cos($u)); $p->x = $this->long0 - $deltav / $this->alfa; /* ITERATION FOR $lat */ $fi1 = $u; $ok = 0; $iter = 0; do { $p->y = 2.0 * (atan(pow($this->k, -1.0 / $this->alfa) * pow(tan($u / 2.0 + $this->s45), 1.0 / $this->alfa) * pow((1.0 + $this->e * sin($fi1)) / (1.0 - $this->e * sin($fi1)), $this->e / 2.0)) - $this->s45); if (abs($fi1 - $p->y) < 1.0E-10) { $ok = 1; } $fi1 = $p->y; $iter += 1; } while ($ok == 0 && $iter < 15); if ($iter >= 15) { Proj4php::reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations"); //console.log('iter:', iter); return null; } return $p; }
public function phi3z($ml, $e0, $e1, $e2, $e3) { $phi = $ml; for ($i = 0; $i < 15; $i++) { $dphi = ($ml + $e1 * sin(2.0 * $phi) - $e2 * sin(4.0 * $phi) + $e3 * sin(6.0 * $phi)) / $e0 - $phi; $phi += $dphi; if (abs($dphi) <= 1.0E-10) { return $phi; } } Proj4php::reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations"); return null; }