| 1001 | delphine | 1 | <?php
 | 
        
           |  |  | 2 | /**
 | 
        
           |  |  | 3 |  * Author : Julien Moquet
 | 
        
           |  |  | 4 |  *
 | 
        
           |  |  | 5 |  * Inspired by Proj4php from Mike Adair madairATdmsolutions.ca
 | 
        
           |  |  | 6 |  *                      and Richard Greenwood rich@greenwoodma$p->com
 | 
        
           |  |  | 7 |  * License: LGPL as per: http://www.gnu.org/copyleft/lesser.html
 | 
        
           |  |  | 8 |  */
 | 
        
           |  |  | 9 | /*******************************************************************************
 | 
        
           |  |  | 10 |   NAME                            MOLLWEIDE
 | 
        
           |  |  | 11 |   | 
        
           |  |  | 12 |   PURPOSE:	Transforms input longitude and latitude to Easting and
 | 
        
           |  |  | 13 |   Northing for the MOllweide projection.  The
 | 
        
           |  |  | 14 |   longitude and latitude must be in radians.  The Easting
 | 
        
           |  |  | 15 |   and Northing values will be returned in meters.
 | 
        
           |  |  | 16 |   | 
        
           |  |  | 17 |   PROGRAMMER              DATE
 | 
        
           |  |  | 18 |   ----------              ----
 | 
        
           |  |  | 19 |   D. Steinwand, EROS      May, 1991;  Updated Sept, 1992; Updated Feb, 1993
 | 
        
           |  |  | 20 |   S. Nelson, EDC		Jun, 2993;	Made corrections in precision and
 | 
        
           |  |  | 21 |   number of iterations.
 | 
        
           |  |  | 22 |   | 
        
           |  |  | 23 |   ALGORITHM REFERENCES
 | 
        
           |  |  | 24 |   | 
        
           |  |  | 25 |   1.  Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
 | 
        
           |  |  | 26 |   U.S. Geological Survey Professional Paper 1453 , United State Government
 | 
        
           |  |  | 27 |   Printing Office, Washington D.C., 1989.
 | 
        
           |  |  | 28 |   | 
        
           |  |  | 29 |   2.  Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
 | 
        
           |  |  | 30 |   Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
 | 
        
           |  |  | 31 |   State Government Printing Office, Washington D.C., 1987.
 | 
        
           |  |  | 32 |  ****************************************************************************** */
 | 
        
           |  |  | 33 |   | 
        
           |  |  | 34 | class Proj4phpProjMoll {
 | 
        
           |  |  | 35 |     /* Initialize the Mollweide projection
 | 
        
           |  |  | 36 |       ------------------------------------ */
 | 
        
           |  |  | 37 |   | 
        
           |  |  | 38 |     public function init() {
 | 
        
           |  |  | 39 |         //no-op
 | 
        
           |  |  | 40 |     }
 | 
        
           |  |  | 41 |   | 
        
           |  |  | 42 |     /* Mollweide forward equations--mapping lat,long to x,y
 | 
        
           |  |  | 43 |       ---------------------------------------------------- */
 | 
        
           |  |  | 44 |     public function forward( $p ) {
 | 
        
           |  |  | 45 |   | 
        
           |  |  | 46 |         /* Forward equations
 | 
        
           |  |  | 47 |           ----------------- */
 | 
        
           |  |  | 48 |         $lon = $p->x;
 | 
        
           |  |  | 49 |         $lat = $p->y;
 | 
        
           |  |  | 50 |   | 
        
           |  |  | 51 |         $delta_lon = Proj4php::$common->adjust_lon( $lon - $this->long0 );
 | 
        
           |  |  | 52 |         $theta = $lat;
 | 
        
           |  |  | 53 |         $con = Proj4php::$common->PI * sin( $lat );
 | 
        
           |  |  | 54 |   | 
        
           |  |  | 55 |         /* Iterate using the Newton-Raphson method to find theta
 | 
        
           |  |  | 56 |           ----------------------------------------------------- */
 | 
        
           |  |  | 57 |         for( $i = 0; true; ++$i ) {
 | 
        
           |  |  | 58 |             $delta_theta = -($theta + sin( $theta ) - $con) / (1.0 + cos( $theta ));
 | 
        
           |  |  | 59 |             $theta += $delta_theta;
 | 
        
           |  |  | 60 |             if( abs( $delta_theta ) < Proj4php::$common->EPSLN )
 | 
        
           |  |  | 61 |                 break;
 | 
        
           |  |  | 62 |             if( $i >= 50 ) {
 | 
        
           |  |  | 63 |                 Proj4php::reportError( "moll:Fwd:IterationError" );
 | 
        
           |  |  | 64 |                 //return(241);
 | 
        
           |  |  | 65 |             }
 | 
        
           |  |  | 66 |         }
 | 
        
           |  |  | 67 |         $theta /= 2.0;
 | 
        
           |  |  | 68 |   | 
        
           |  |  | 69 |         /* If the latitude is 90 deg, force the x coordinate to be "0 . false easting"
 | 
        
           |  |  | 70 |           this is done here because of precision problems with "cos(theta)"
 | 
        
           |  |  | 71 |           -------------------------------------------------------------------------- */
 | 
        
           |  |  | 72 |         if( Proj4php::$common->PI / 2 - abs( $lat ) < Proj4php::$common->EPSLN )
 | 
        
           |  |  | 73 |             $delta_lon = 0;
 | 
        
           |  |  | 74 |         $x = 0.900316316158 * $this->a * $delta_lon * cos( $theta ) + $this->x0;
 | 
        
           |  |  | 75 |         $y = 1.4142135623731 * $this->a * sin( $theta ) + $this->y0;
 | 
        
           |  |  | 76 |   | 
        
           |  |  | 77 |         $p->x = $x;
 | 
        
           |  |  | 78 |         $p->y = $y;
 | 
        
           |  |  | 79 |         return $p;
 | 
        
           |  |  | 80 |     }
 | 
        
           |  |  | 81 |   | 
        
           |  |  | 82 |     /**
 | 
        
           |  |  | 83 |      *
 | 
        
           |  |  | 84 |      * @param type $p
 | 
        
           |  |  | 85 |      * @return type
 | 
        
           |  |  | 86 |      */
 | 
        
           |  |  | 87 |     public function inverse( $p ) {
 | 
        
           |  |  | 88 |         #$theta;
 | 
        
           |  |  | 89 |         #$arg;
 | 
        
           |  |  | 90 |   | 
        
           |  |  | 91 |         /* Inverse equations
 | 
        
           |  |  | 92 |           ----------------- */
 | 
        
           |  |  | 93 |         $p->x-= $this->x0;
 | 
        
           |  |  | 94 |         //~ $p->y -= $this->y0;
 | 
        
           |  |  | 95 |         $arg = $p->y / (1.4142135623731 * $this->a);
 | 
        
           |  |  | 96 |   | 
        
           |  |  | 97 |         /* Because of division by zero problems, 'arg' can not be 1.0.  Therefore
 | 
        
           |  |  | 98 |           a number very close to one is used instead.
 | 
        
           |  |  | 99 |           ------------------------------------------------------------------- */
 | 
        
           |  |  | 100 |         if( abs( $arg ) > 0.999999999999 )
 | 
        
           |  |  | 101 |             $arg = 0.999999999999;
 | 
        
           |  |  | 102 |         $theta = asin( $arg );
 | 
        
           |  |  | 103 |         $lon = Proj4php::$common->adjust_lon( $this->long0 + ($p->x / (0.900316316158 * $this->a * cos( $theta ))) );
 | 
        
           |  |  | 104 |         if( $lon < (-Proj4php::$common->PI) )
 | 
        
           |  |  | 105 |             $lon = -Proj4php::$common->PI;
 | 
        
           |  |  | 106 |         if( $lon > Proj4php::$common->PI )
 | 
        
           |  |  | 107 |             $lon = Proj4php::$common->PI;
 | 
        
           |  |  | 108 |         $arg = (2.0 * $theta + sin( 2.0 * $theta )) / Proj4php::$common->PI;
 | 
        
           |  |  | 109 |         if( abs( $arg ) > 1.0 )
 | 
        
           |  |  | 110 |             $arg = 1.0;
 | 
        
           |  |  | 111 |         $lat = asin( $arg );
 | 
        
           |  |  | 112 |         //return(OK);
 | 
        
           |  |  | 113 |   | 
        
           |  |  | 114 |         $p->x = $lon;
 | 
        
           |  |  | 115 |         $p->y = $lat;
 | 
        
           |  |  | 116 |   | 
        
           |  |  | 117 |         return $p;
 | 
        
           |  |  | 118 |     }
 | 
        
           |  |  | 119 | }
 | 
        
           |  |  | 120 |   | 
        
           |  |  | 121 | Proj4php::$proj['moll'] = new Proj4phpProjMoll();
 |