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
/**
4
  NOTES: According to EPSG the full Krovak projection method should have
5
  the following parameters.  Within PROJ.4 the azimuth, and pseudo
6
  standard parallel are hardcoded in the algorithm and can't be
7
  altered from outside.  The others all have defaults to match the
8
  common usage with Krovak projection.
9
 
10
  lat_0 = latitude of centre of the projection
11
 
12
  lon_0 = longitude of centre of the projection
13
 
14
 * * = azimuth (true) of the centre line passing through the centre of the projection
15
 
16
 * * = latitude of pseudo standard parallel
17
 
18
  k  = scale factor on the pseudo standard parallel
19
 
20
  x_0 = False Easting of the centre of the projection at the apex of the cone
21
 
22
  y_0 = False Northing of the centre of the projection at the apex of the cone
23
 
24
**/
25
class Proj4phpProjKrovak {
26
 
27
    /**
28
     *
29
     */
30
    public function init() {
31
        /* we want Bessel as fixed ellipsoid */
32
        $this->a = 6377397.155;
33
        $this->es = 0.006674372230614;
34
        $this->e = sqrt( $this->es );
35
        /* if latitude of projection center is not set, use 49d30'N */
36
        if( !$this->lat0 ) {
37
            $this->lat0 = 0.863937979737193;
38
        }
39
        if( !$this->long0 ) {
40
            $this->long0 = 0.7417649320975901 - 0.308341501185665;
41
        }
42
        /* if scale not set default to 0.9999 */
43
        if( !$this->k0 ) {
44
            $this->k0 = 0.9999;
45
        }
46
        $this->s45 = 0.785398163397448;    /* 45° */
47
        $this->s90 = 2 * $this->s45;
48
        $this->fi0 = $this->lat0;    /* Latitude of projection centre 49° 30' */
49
        /*  Ellipsoid Bessel 1841 a = 6377397.155m 1/f = 299.1528128,
50
          e2=0.006674372230614;
51
         */
52
        $this->e2 = $this->es;       /* 0.006674372230614; */
53
        $this->e = sqrt( $this->e2 );
54
        $this->alfa = sqrt( 1. + ($this->e2 * pow( cos( $this->fi0 ), 4 )) / (1. - $this->e2) );
55
        $this->uq = 1.04216856380474;      /* DU(2, 59, 42, 42.69689) */
56
        $this->u0 = asin( sin( $this->fi0 ) / $this->alfa );
57
        $this->g = pow( (1. + $this->e * sin( $this->fi0 )) / (1. - $this->e * sin( $this->fi0 )), $this->alfa * $this->e / 2. );
58
        $this->k = tan( $this->u0 / 2. + $this->s45 ) / pow( tan( $this->fi0 / 2. + $this->s45 ), $this->alfa ) * $this->g;
59
        $this->k1 = $this->k0;
60
        $this->n0 = $this->a * sqrt( 1. - $this->e2 ) / (1. - $this->e2 * pow( sin( $this->fi0 ), 2 ));
61
        $this->s0 = 1.37008346281555;       /* Latitude of pseudo standard parallel 78° 30'00" N */
62
        $this->n = sin( $this->s0 );
63
        $this->ro0 = $this->k1 * $this->n0 / tan( $this->s0 );
64
        $this->ad = $this->s90 - $this->uq;
65
    }
66
 
67
    /**
68
     * ellipsoid
69
     * calculate xy from lat/lon
70
     * Constants, identical to inverse transform function
71
     *
72
     * @param type $p
73
     * @return type
74
     */
75
    public function forward( $p ) {
76
 
77
        $lon = $p->x;
78
        $lat = $p->y;
79
        $delta_lon = Proj4php::$common->adjust_lon( $lon - $this->long0 ); // Delta longitude
80
 
81
        /* Transformation */
82
        $gfi = pow( ((1. + $this->e * sin( $lat )) / (1. - $this->e * sin( $lat )) ), ($this->alfa * $this->e / 2. ) );
83
        $u = 2. * (atan( $this->k * pow( tan( $lat / 2. + $this->s45 ), $this->alfa ) / $gfi ) - $this->s45);
84
        $deltav = - $delta_lon * $this->alfa;
85
        $s = asin( cos( $this->ad ) * sin( $u ) + sin( $this->ad ) * cos( $u ) * cos( $deltav ) );
86
        $d = asin( cos( $u ) * sin( $deltav ) / cos( $s ) );
87
        $eps = $this->n * $d;
88
        $ro = $this->ro0 * pow( tan( $this->s0 / 2. + $this->s45 ), $this->n ) / pow( tan( $s / 2. + $this->s45 ), $this->n );
89
        /* x and y are reverted! */
90
        //$p->y = ro * cos(eps) / a;
91
        //$p->x = ro * sin(eps) / a;
92
        $p->y = $ro * cos( $eps ) / 1.0;
93
        $p->x = $ro * sin( $eps ) / 1.0;
94
 
95
        if( $this->czech ) {
96
            $p->y *= -1.0;
97
            $p->x *= -1.0;
98
        }
99
 
100
        return $p;
101
    }
102
 
103
    /**
104
     * calculate lat/lon from xy
105
     *
106
     * @param Point $p
107
     * @return Point $p
108
     */
109
    public function inverse( $p ) {
110
 
111
        /* Transformation */
112
        /* revert y, x */
113
        $tmp = $p->x;
114
        $p->x = $p->y;
115
        $p->y = $tmp;
116
 
117
        if( $this->czech ) {
118
            $p->y *= -1.0;
119
            $p->x *= -1.0;
120
        }
121
 
122
        $ro = sqrt( $p->x * $p->x + $p->y * $p->y );
123
        $eps = atan2( $p->y, $p->x );
124
        $d = $eps / sin( $this->s0 );
125
        $s = 2. * (atan( pow( $this->ro0 / $ro, 1. / $this->n ) * tan( $this->s0 / 2. + $this->s45 ) ) - $this->s45);
126
        $u = asin( cos( $this->ad ) * sin( s ) - sin( $this->ad ) * cos( s ) * cos( d ) );
127
        $deltav = asin( cos( $s ) * sin( $d ) / cos( $u ) );
128
        $p->x = $this->long0 - $deltav / $this->alfa;
129
 
130
        /* ITERATION FOR $lat */
131
        $fi1 = $u;
132
        $ok = 0;
133
        $iter = 0;
134
        do {
135
            $p->y = 2. * ( atan( pow( $this->k, -1. / $this->alfa ) *
136
                                pow( tan( $u / 2. + $this->s45 ), 1. / $this->alfa ) *
137
                                pow( (1. + $this->e * sin( $fi1 )) / (1. - $this->e * sin( $fi1 )), $this->e / 2. )
138
                      ) - $this->s45);
139
            if( abs( $fi1 - $p->y ) < 0.0000000001 )
140
                $ok = 1;
141
            $fi1 = $p->y;
142
            $iter += 1;
143
        } while( $ok == 0 && $iter < 15 );
144
 
145
        if( $iter >= 15 ) {
146
            Proj4php::reportError( "PHI3Z-CONV:Latitude failed to converge after 15 iterations" );
147
            //console.log('iter:', iter);
148
            return null;
149
        }
150
 
151
        return $p;
152
    }
153
 
154
}
155
 
156
Proj4php::$proj['krovak'] = new Proj4phpProjKrovak();