Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 1001 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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();