New file |
0,0 → 1,145 |
<?php |
/** |
* Author : Julien Moquet |
* |
* Inspired by Proj4php from Mike Adair madairATdmsolutions.ca |
* and Richard Greenwood rich@greenwoodma$p->com |
* License: LGPL as per: http://www.gnu.org/copyleft/lesser.html |
*/ |
/***************************************************************************** |
NAME GNOMONIC |
|
PURPOSE: Transforms input longitude and latitude to Easting and |
Northing for the Gnomonic Projection. |
Implementation based on the existing sterea and ortho |
implementations. |
|
PROGRAMMER DATE |
---------- ---- |
Richard Marsden November 2009 |
|
ALGORITHM REFERENCES |
|
1. Snyder, John P., "Flattening the Earth - Two Thousand Years of Map |
Projections", University of Chicago Press 1993 |
|
2. Wolfram Mathworld "Gnomonic Projection" |
http://mathworld.wolfram.com/GnomonicProjection.html |
Accessed: 12th November 2009 |
******************************************************************************/ |
|
class Proj4phpProjGnom { |
|
/** |
* Initialize the Gnomonic projection |
* |
* @todo $def not used in context...? |
* @param type $def |
*/ |
public function init( $def ) { |
|
/* Place parameters in static storage for common use |
------------------------------------------------- */ |
$this->sin_p14 = sin( $this->lat0 ); |
$this->cos_p14 = cos( $this->lat0 ); |
|
// Approximation for projecting points to the horizon (infinity) |
$this->infinity_dist = 1000 * $this->a; |
$this->rc = 1; |
} |
|
/* Gnomonic forward equations--mapping lat,long to x,y |
--------------------------------------------------- */ |
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 = Proj4php::$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 ) <= Proj4php::$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; |
} |
|
/** |
* |
* @param type $p |
* @return type |
*/ |
public function inverse( $p ) { |
|
/* |
$rh; // Rho |
$z; // angle |
$sinc; |
$cosc; |
$c; |
$lon; |
$lat; |
*/ |
|
/* Inverse equations |
----------------- */ |
$p->x = ($p->x - $this->x0) / $this->a; |
$p->y = ($p->y - $this->y0) / $this->a; |
|
$p->x /= $this->k0; |
$p->y /= $this->k0; |
|
if( ($rh = sqrt( $p->x * $p->x + $p->y * $p->y ) ) ) { |
$c = atan2( $rh, $this->rc ); |
$sinc = sin( $c ); |
$cosc = cos( $c ); |
|
$lat = Proj4php::$common->asinz( $cosc * $this->sin_p14 + ($p->y * $sinc * $this->cos_p14) / $rh ); |
$lon = atan2( $p->x * sinc, rh * $this->cos_p14 * $cosc - $p->y * $this->sin_p14 * $sinc ); |
$lon = Proj4php::$common->adjust_lon( $this->long0 + $lon ); |
} else { |
$lat = $this->phic0; |
$lon = 0.0; |
} |
|
$p->x = $lon; |
$p->y = $lat; |
|
return $p; |
} |
} |
|
Proj4php::$proj['gnom'] = new Proj4phpProjGnom(); |