| 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                            NEW ZEALAND MAP GRID
 | 
        
           |  |  | 11 |   | 
        
           |  |  | 12 |   PURPOSE:	Transforms input longitude and latitude to Easting and
 | 
        
           |  |  | 13 |   Northing for the New Zealand Map Grid projection.  The
 | 
        
           |  |  | 14 |   longitude and latitude must be in radians.  The Easting
 | 
        
           |  |  | 15 |   and Northing values will be returned in meters.
 | 
        
           |  |  | 16 |   | 
        
           |  |  | 17 |   | 
        
           |  |  | 18 |   ALGORITHM REFERENCES
 | 
        
           |  |  | 19 |   | 
        
           |  |  | 20 |   1.  Department of Land and Survey Technical Circular 1973/32
 | 
        
           |  |  | 21 |   http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf
 | 
        
           |  |  | 22 |   | 
        
           |  |  | 23 |   2.  OSG Technical Report 4.1
 | 
        
           |  |  | 24 |   http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf
 | 
        
           |  |  | 25 |   | 
        
           |  |  | 26 |   | 
        
           |  |  | 27 |   IMPLEMENTATION NOTES
 | 
        
           |  |  | 28 |   | 
        
           |  |  | 29 |   The two references use different symbols for the calculated values. This
 | 
        
           |  |  | 30 |   implementation uses the variable names similar to the symbols in reference [1].
 | 
        
           |  |  | 31 |   | 
        
           |  |  | 32 |   The alogrithm uses different units for delta latitude and delta longitude.
 | 
        
           |  |  | 33 |   The delta latitude is assumed to be in units of seconds of arc x 10^-5.
 | 
        
           |  |  | 34 |   The delta longitude is the usual radians. Look out for these conversions.
 | 
        
           |  |  | 35 |   | 
        
           |  |  | 36 |   The algorithm is described using complex arithmetic. There were three
 | 
        
           |  |  | 37 |   options:
 | 
        
           |  |  | 38 |  * find and use a Javascript library for complex arithmetic
 | 
        
           |  |  | 39 |  * write my own complex library
 | 
        
           |  |  | 40 |  * expand the complex arithmetic by hand to simple arithmetic
 | 
        
           |  |  | 41 |   | 
        
           |  |  | 42 |   This implementation has expanded the complex multiplication operations
 | 
        
           |  |  | 43 |   into parallel simple arithmetic operations for the real and imaginary parts.
 | 
        
           |  |  | 44 |   The imaginary part is way over to the right of the display; this probably
 | 
        
           |  |  | 45 |   violates every coding standard in the world, but, to me, it makes it much
 | 
        
           |  |  | 46 |   more obvious what is going on.
 | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 |   The following complex operations are used:
 | 
        
           |  |  | 49 |   - addition
 | 
        
           |  |  | 50 |   - multiplication
 | 
        
           |  |  | 51 |   - division
 | 
        
           |  |  | 52 |   - complex number raised to integer power
 | 
        
           |  |  | 53 |   - summation
 | 
        
           |  |  | 54 |   | 
        
           |  |  | 55 |   A summary of complex arithmetic operations:
 | 
        
           |  |  | 56 |   (from http://en.wikipedia.org/wiki/Complex_arithmetic)
 | 
        
           |  |  | 57 |   addition:       (a + bi) + (c + di) = (a + c) + (b + d)i
 | 
        
           |  |  | 58 |   subtraction:    (a + bi) - (c + di) = (a - c) + (b - d)i
 | 
        
           |  |  | 59 |   multiplication: (a + bi) x (c + di) = (ac - bd) + (bc + ad)i
 | 
        
           |  |  | 60 |   division:       (a + bi) / (c + di) = [(ac + bd)/(cc + dd)] + [(bc - ad)/(cc + dd)]i
 | 
        
           |  |  | 61 |   | 
        
           |  |  | 62 |   The algorithm needs to calculate summations of simple and complex numbers. This is
 | 
        
           |  |  | 63 |   implemented using a for-loop, pre-loading the summed value to zero.
 | 
        
           |  |  | 64 |   | 
        
           |  |  | 65 |   The algorithm needs to calculate theta^2, theta^3, etc while doing a summation.
 | 
        
           |  |  | 66 |   There are three possible implementations:
 | 
        
           |  |  | 67 |   - use pow in the summation loop - except for complex numbers
 | 
        
           |  |  | 68 |   - precalculate the values before running the loop
 | 
        
           |  |  | 69 |   - calculate theta^n = theta^(n-1) * theta during the loop
 | 
        
           |  |  | 70 |   This implementation uses the third option for both real and complex arithmetic.
 | 
        
           |  |  | 71 |   | 
        
           |  |  | 72 |   For example
 | 
        
           |  |  | 73 |   psi_n = 1;
 | 
        
           |  |  | 74 |   sum = 0;
 | 
        
           |  |  | 75 |   for (n = 1; n <=6; n++) {
 | 
        
           |  |  | 76 |   psi_n1 = psi_n * psi;       // calculate psi^(n+1)
 | 
        
           |  |  | 77 |   psi_n = psi_n1;
 | 
        
           |  |  | 78 |   sum = sum + A[n] * psi_n;
 | 
        
           |  |  | 79 |   }
 | 
        
           |  |  | 80 |   | 
        
           |  |  | 81 |   | 
        
           |  |  | 82 |   TEST VECTORS
 | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 |   NZMG E, N:         2487100.638      6751049.719     metres
 | 
        
           |  |  | 85 |   NZGD49 long, lat:      172.739194       -34.444066  degrees
 | 
        
           |  |  | 86 |   | 
        
           |  |  | 87 |   NZMG E, N:         2486533.395      6077263.661     metres
 | 
        
           |  |  | 88 |   NZGD49 long, lat:      172.723106       -40.512409  degrees
 | 
        
           |  |  | 89 |   | 
        
           |  |  | 90 |   NZMG E, N:         2216746.425      5388508.765     metres
 | 
        
           |  |  | 91 |   NZGD49 long, lat:      169.172062       -46.651295  degrees
 | 
        
           |  |  | 92 |   | 
        
           |  |  | 93 |   Note that these test vectors convert from NZMG metres to lat/long referenced
 | 
        
           |  |  | 94 |   to NZGD49, not the more usual WGS84. The difference is about 70m N/S and about
 | 
        
           |  |  | 95 |   10m E/W.
 | 
        
           |  |  | 96 |   | 
        
           |  |  | 97 |   These test vectors are provided in reference [1]. Many more test
 | 
        
           |  |  | 98 |   vectors are available in
 | 
        
           |  |  | 99 |   http://www.linz.govt.nz/docs/topography/topographicdata/placenamesdatabase/nznamesmar08.zip
 | 
        
           |  |  | 100 |   which is a catalog of names on the 260-series maps.
 | 
        
           |  |  | 101 |   | 
        
           |  |  | 102 |   | 
        
           |  |  | 103 |   EPSG CODES
 | 
        
           |  |  | 104 |   | 
        
           |  |  | 105 |   NZMG     EPSG:27200
 | 
        
           |  |  | 106 |   NZGD49   EPSG:4272
 | 
        
           |  |  | 107 |   | 
        
           |  |  | 108 |   http://spatialreference.org/ defines these as
 | 
        
           |  |  | 109 |   Proj4php.defs["EPSG:4272"] = "+proj=longlat +ellps=intl +datum=nzgd49 +no_defs ";
 | 
        
           |  |  | 110 |   Proj4php.defs["EPSG:27200"] = "+proj=nzmg +lat_0=-41 +lon_0=173 +x_0=2510000 +y_0=6023150 +ellps=intl +datum=nzgd49 +units=m +no_defs ";
 | 
        
           |  |  | 111 |   | 
        
           |  |  | 112 |   | 
        
           |  |  | 113 |   LICENSE
 | 
        
           |  |  | 114 |   Copyright: Stephen Irons 2008
 | 
        
           |  |  | 115 |   Released under terms of the LGPL as per: http://www.gnu.org/copyleft/lesser.html
 | 
        
           |  |  | 116 |   | 
        
           |  |  | 117 |  * ***************************************************************************** */
 | 
        
           |  |  | 118 |   | 
        
           |  |  | 119 | /**
 | 
        
           |  |  | 120 |   Initialize New Zealand Map Grip projection
 | 
        
           |  |  | 121 |  */
 | 
        
           |  |  | 122 | class Proj4phpProjNzmg {
 | 
        
           |  |  | 123 |   | 
        
           |  |  | 124 |     /**
 | 
        
           |  |  | 125 |      * iterations: Number of iterations to refine inverse transform.
 | 
        
           |  |  | 126 |      *     0 -> km accuracy
 | 
        
           |  |  | 127 |      *     1 -> m accuracy -- suitable for most mapping applications
 | 
        
           |  |  | 128 |      *     2 -> mm accuracy
 | 
        
           |  |  | 129 |      */
 | 
        
           |  |  | 130 |     protected $iterations = 1;
 | 
        
           |  |  | 131 |   | 
        
           |  |  | 132 |     /**
 | 
        
           |  |  | 133 |      *
 | 
        
           |  |  | 134 |      */
 | 
        
           |  |  | 135 |     public function init() {
 | 
        
           |  |  | 136 |         $this->A = array( );
 | 
        
           |  |  | 137 |         $this->A[1] = +0.6399175073;
 | 
        
           |  |  | 138 |         $this->A[2] = -0.1358797613;
 | 
        
           |  |  | 139 |         $this->A[3] = +0.063294409;
 | 
        
           |  |  | 140 |         $this->A[4] = -0.02526853;
 | 
        
           |  |  | 141 |         $this->A[5] = +0.0117879;
 | 
        
           |  |  | 142 |         $this->A[6] = -0.0055161;
 | 
        
           |  |  | 143 |         $this->A[7] = +0.0026906;
 | 
        
           |  |  | 144 |         $this->A[8] = -0.001333;
 | 
        
           |  |  | 145 |         $this->A[9] = +0.00067;
 | 
        
           |  |  | 146 |         $this->A[10] = -0.00034;
 | 
        
           |  |  | 147 |   | 
        
           |  |  | 148 |         $this->B_re = array( );
 | 
        
           |  |  | 149 |         $this->B_im = array( );
 | 
        
           |  |  | 150 |         $this->B_re[1] = +0.7557853228;
 | 
        
           |  |  | 151 |         $this->B_im[1] = 0.0;
 | 
        
           |  |  | 152 |         $this->B_re[2] = +0.249204646;
 | 
        
           |  |  | 153 |         $this->B_im[2] = +0.003371507;
 | 
        
           |  |  | 154 |         $this->B_re[3] = -0.001541739;
 | 
        
           |  |  | 155 |         $this->B_im[3] = +0.041058560;
 | 
        
           |  |  | 156 |         $this->B_re[4] = -0.10162907;
 | 
        
           |  |  | 157 |         $this->B_im[4] = +0.01727609;
 | 
        
           |  |  | 158 |         $this->B_re[5] = -0.26623489;
 | 
        
           |  |  | 159 |         $this->B_im[5] = -0.36249218;
 | 
        
           |  |  | 160 |         $this->B_re[6] = -0.6870983;
 | 
        
           |  |  | 161 |         $this->B_im[6] = -1.1651967;
 | 
        
           |  |  | 162 |   | 
        
           |  |  | 163 |         $this->C_re = array( );
 | 
        
           |  |  | 164 |         $this->C_im = array( );
 | 
        
           |  |  | 165 |         $this->C_re[1] = +1.3231270439;
 | 
        
           |  |  | 166 |         $this->C_im[1] = 0.0;
 | 
        
           |  |  | 167 |         $this->C_re[2] = -0.577245789;
 | 
        
           |  |  | 168 |         $this->C_im[2] = -0.007809598;
 | 
        
           |  |  | 169 |         $this->C_re[3] = +0.508307513;
 | 
        
           |  |  | 170 |         $this->C_im[3] = -0.112208952;
 | 
        
           |  |  | 171 |         $this->C_re[4] = -0.15094762;
 | 
        
           |  |  | 172 |         $this->C_im[4] = +0.18200602;
 | 
        
           |  |  | 173 |         $this->C_re[5] = +1.01418179;
 | 
        
           |  |  | 174 |         $this->C_im[5] = +1.64497696;
 | 
        
           |  |  | 175 |         $this->C_re[6] = +1.9660549;
 | 
        
           |  |  | 176 |         $this->C_im[6] = +2.5127645;
 | 
        
           |  |  | 177 |   | 
        
           |  |  | 178 |         $this->D = array( );
 | 
        
           |  |  | 179 |         $this->D[1] = +1.5627014243;
 | 
        
           |  |  | 180 |         $this->D[2] = +0.5185406398;
 | 
        
           |  |  | 181 |         $this->D[3] = -0.03333098;
 | 
        
           |  |  | 182 |         $this->D[4] = -0.1052906;
 | 
        
           |  |  | 183 |         $this->D[5] = -0.0368594;
 | 
        
           |  |  | 184 |         $this->D[6] = +0.007317;
 | 
        
           |  |  | 185 |         $this->D[7] = +0.01220;
 | 
        
           |  |  | 186 |         $this->D[8] = +0.00394;
 | 
        
           |  |  | 187 |         $this->D[9] = -0.0013;
 | 
        
           |  |  | 188 |     }
 | 
        
           |  |  | 189 |   | 
        
           |  |  | 190 |     /**
 | 
        
           |  |  | 191 |       New Zealand Map Grid Forward  - long/lat to x/y
 | 
        
           |  |  | 192 |       long/lat in radians
 | 
        
           |  |  | 193 |      */
 | 
        
           |  |  | 194 |     public function forward( $p ) {
 | 
        
           |  |  | 195 |   | 
        
           |  |  | 196 |         $lon = $p->x;
 | 
        
           |  |  | 197 |         $lat = $p->y;
 | 
        
           |  |  | 198 |   | 
        
           |  |  | 199 |         $delta_lat = $lat - $this->lat0;
 | 
        
           |  |  | 200 |         $delta_lon = $lon - $this->long0;
 | 
        
           |  |  | 201 |   | 
        
           |  |  | 202 |         // 1. Calculate d_phi and d_psi    ...                          // and d_lambda
 | 
        
           |  |  | 203 |         // For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians.
 | 
        
           |  |  | 204 |         $d_phi = $delta_lat / Proj4php::$common->SEC_TO_RAD * 1E-5;
 | 
        
           |  |  | 205 |         $d_lambda = $delta_lon;
 | 
        
           |  |  | 206 |         $d_phi_n = 1;  // d_phi^0
 | 
        
           |  |  | 207 |   | 
        
           |  |  | 208 |         $d_psi = 0;
 | 
        
           |  |  | 209 |         for( $n = 1; $n <= 10; $n++ ) {
 | 
        
           |  |  | 210 |             $d_phi_n = $d_phi_n * $d_phi;
 | 
        
           |  |  | 211 |             $d_psi = $d_psi + $this->A[$n] * $d_phi_n;
 | 
        
           |  |  | 212 |         }
 | 
        
           |  |  | 213 |   | 
        
           |  |  | 214 |         // 2. Calculate theta
 | 
        
           |  |  | 215 |         $th_re = $d_psi;
 | 
        
           |  |  | 216 |         $th_im = $d_lambda;
 | 
        
           |  |  | 217 |   | 
        
           |  |  | 218 |         // 3. Calculate z
 | 
        
           |  |  | 219 |         $th_n_re = 1;
 | 
        
           |  |  | 220 |         $th_n_im = 0;  // theta^0
 | 
        
           |  |  | 221 |         #$th_n_re1;
 | 
        
           |  |  | 222 |         #$th_n_im1;
 | 
        
           |  |  | 223 |   | 
        
           |  |  | 224 |         $z_re = 0;
 | 
        
           |  |  | 225 |         $z_im = 0;
 | 
        
           |  |  | 226 |         for( $n = 1; $n <= 6; $n++ ) {
 | 
        
           |  |  | 227 |             $th_n_re1 = $th_n_re * $th_re - $th_n_im * $th_im;
 | 
        
           |  |  | 228 |             $th_n_im1 = $th_n_im * $th_re + $th_n_re * $th_im;
 | 
        
           |  |  | 229 |             $th_n_re = $th_n_re1;
 | 
        
           |  |  | 230 |             $th_n_im = $th_n_im1;
 | 
        
           |  |  | 231 |             $z_re = $z_re + $this->B_re[$n] * $th_n_re - $this->B_im[$n] * $th_n_im;
 | 
        
           |  |  | 232 |             $z_im = $z_im + $this->B_im[$n] * $th_n_re + $this->B_re[$n] * $th_n_im;
 | 
        
           |  |  | 233 |         }
 | 
        
           |  |  | 234 |   | 
        
           |  |  | 235 |         // 4. Calculate easting and northing
 | 
        
           |  |  | 236 |         $p->x = ($z_im * $this->a) + $this->x0;
 | 
        
           |  |  | 237 |         $p->y = ($z_re * $this->a) + $this->y0;
 | 
        
           |  |  | 238 |   | 
        
           |  |  | 239 |         return $p;
 | 
        
           |  |  | 240 |     }
 | 
        
           |  |  | 241 |   | 
        
           |  |  | 242 |     /**
 | 
        
           |  |  | 243 |       New Zealand Map Grid Inverse  -  x/y to long/lat
 | 
        
           |  |  | 244 |      */
 | 
        
           |  |  | 245 |     public function inverse( $p ) {
 | 
        
           |  |  | 246 |   | 
        
           |  |  | 247 |         $x = $p->x;
 | 
        
           |  |  | 248 |         $y = $p->y;
 | 
        
           |  |  | 249 |   | 
        
           |  |  | 250 |         $delta_x = $x - $this->x0;
 | 
        
           |  |  | 251 |         $delta_y = $y - $this->y0;
 | 
        
           |  |  | 252 |   | 
        
           |  |  | 253 |         // 1. Calculate z
 | 
        
           |  |  | 254 |         $z_re = $delta_y / $this->a;
 | 
        
           |  |  | 255 |         $z_im = $delta_x / $this->a;
 | 
        
           |  |  | 256 |   | 
        
           |  |  | 257 |         // 2a. Calculate theta - first approximation gives km accuracy
 | 
        
           |  |  | 258 |         $z_n_re = 1;
 | 
        
           |  |  | 259 |         $z_n_im = 0;  // z^0
 | 
        
           |  |  | 260 |         $z_n_re1;
 | 
        
           |  |  | 261 |         $z_n_im1;
 | 
        
           |  |  | 262 |   | 
        
           |  |  | 263 |         $th_re = 0;
 | 
        
           |  |  | 264 |         $th_im = 0;
 | 
        
           |  |  | 265 |         for( $n = 1; $n <= 6; $n++ ) {
 | 
        
           |  |  | 266 |             $z_n_re1 = $z_n_re * $z_re - $z_n_im * $z_im;
 | 
        
           |  |  | 267 |             $z_n_im1 = $z_n_im * $z_re + $z_n_re * $z_im;
 | 
        
           |  |  | 268 |             $z_n_re = $z_n_re1;
 | 
        
           |  |  | 269 |             $z_n_im = $z_n_im1;
 | 
        
           |  |  | 270 |             $th_re = $th_re + $this->C_re[$n] * $z_n_re - $this->C_im[$n] * $z_n_im;
 | 
        
           |  |  | 271 |             $th_im = $th_im + $this->C_im[$n] * $z_n_re + $this->C_re[$n] * $z_n_im;
 | 
        
           |  |  | 272 |         }
 | 
        
           |  |  | 273 |   | 
        
           |  |  | 274 |         // 2b. Iterate to refine the accuracy of the calculation
 | 
        
           |  |  | 275 |         //        0 iterations gives km accuracy
 | 
        
           |  |  | 276 |         //        1 iteration gives m accuracy -- good enough for most mapping applications
 | 
        
           |  |  | 277 |         //        2 iterations bives mm accuracy
 | 
        
           |  |  | 278 |         for( $i = 0; $i < $this->iterations; $i++ ) {
 | 
        
           |  |  | 279 |             $th_n_re = $th_re;
 | 
        
           |  |  | 280 |             $th_n_im = $th_im;
 | 
        
           |  |  | 281 |             $th_n_re1;
 | 
        
           |  |  | 282 |             $th_n_im1;
 | 
        
           |  |  | 283 |   | 
        
           |  |  | 284 |             $num_re = $z_re;
 | 
        
           |  |  | 285 |             $num_im = $z_im;
 | 
        
           |  |  | 286 |             for( $n = 2; $n <= 6; $n++ ) {
 | 
        
           |  |  | 287 |                 $th_n_re1 = $th_n_re * th_re - $th_n_im * $th_im;
 | 
        
           |  |  | 288 |                 $th_n_im1 = $th_n_im * $th_re + $th_n_re * $th_im;
 | 
        
           |  |  | 289 |                 $th_n_re = $th_n_re1;
 | 
        
           |  |  | 290 |                 $th_n_im = $th_n_im1;
 | 
        
           |  |  | 291 |                 $num_re = $num_re + ($n - 1) * ($this->B_re[$n] * $th_n_re - $this->B_im[$n] * $th_n_im);
 | 
        
           |  |  | 292 |                 $num_im = $num_im + (n - 1) * ($this->B_im[$n] * $th_n_re + $this->B_re[$n] * $th_n_im);
 | 
        
           |  |  | 293 |             }
 | 
        
           |  |  | 294 |   | 
        
           |  |  | 295 |             $th_n_re = 1;
 | 
        
           |  |  | 296 |             $th_n_im = 0;
 | 
        
           |  |  | 297 |             $den_re = $this->B_re[1];
 | 
        
           |  |  | 298 |             $den_im = $this->B_im[1];
 | 
        
           |  |  | 299 |             for( $n = 2; $n <= 6; $n++ ) {
 | 
        
           |  |  | 300 |                 $th_n_re1 = $th_n_re * $th_re - $th_n_im * $th_im;
 | 
        
           |  |  | 301 |                 $th_n_im1 = $th_n_im * $th_re + $th_n_re * $th_im;
 | 
        
           |  |  | 302 |                 $th_n_re = $th_n_re1;
 | 
        
           |  |  | 303 |                 $th_n_im = $th_n_im1;
 | 
        
           |  |  | 304 |                 $den_re = $den_re + $n * ($this->B_re[$n] * $th_n_re - $this->B_im[$n] * $th_n_im);
 | 
        
           |  |  | 305 |                 $den_im = $den_im + $n * ($this->B_im[n] * $th_n_re + $this->B_re[$n] * $th_n_im);
 | 
        
           |  |  | 306 |             }
 | 
        
           |  |  | 307 |   | 
        
           |  |  | 308 |             // Complex division
 | 
        
           |  |  | 309 |             $den2 = $den_re * $den_re + $den_im * $den_im;
 | 
        
           |  |  | 310 |             $th_re = ($num_re * $den_re + $num_im * $den_im) / $den2;
 | 
        
           |  |  | 311 |             $th_im = ($num_im * $den_re - $num_re * $den_im) / $den2;
 | 
        
           |  |  | 312 |         }
 | 
        
           |  |  | 313 |   | 
        
           |  |  | 314 |         // 3. Calculate d_phi              ...                                    // and d_lambda
 | 
        
           |  |  | 315 |         $d_psi = $th_re;
 | 
        
           |  |  | 316 |         $d_lambda = $th_im;
 | 
        
           |  |  | 317 |         $d_psi_n = 1;  // d_psi^0
 | 
        
           |  |  | 318 |   | 
        
           |  |  | 319 |         $d_phi = 0;
 | 
        
           |  |  | 320 |         for( $n = 1; $n <= 9; $n++ ) {
 | 
        
           |  |  | 321 |             $d_psi_n = $d_psi_n * $d_psi;
 | 
        
           |  |  | 322 |             $d_phi = $d_phi + $this->D[$n] * $d_psi_n;
 | 
        
           |  |  | 323 |         }
 | 
        
           |  |  | 324 |   | 
        
           |  |  | 325 |         // 4. Calculate latitude and longitude
 | 
        
           |  |  | 326 |         // d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians.
 | 
        
           |  |  | 327 |         $lat = $this->lat0 + ($d_phi * Proj4php::$common->SEC_TO_RAD * 1E5);
 | 
        
           |  |  | 328 |         $lon = $this->long0 + $d_lambda;
 | 
        
           |  |  | 329 |   | 
        
           |  |  | 330 |         $p->x = $lon;
 | 
        
           |  |  | 331 |         $p->y = $lat;
 | 
        
           |  |  | 332 |   | 
        
           |  |  | 333 |         return $p;
 | 
        
           |  |  | 334 |     }
 | 
        
           |  |  | 335 |   | 
        
           |  |  | 336 | }
 | 
        
           |  |  | 337 |   | 
        
           |  |  | 338 | Proj4php::$proj['nzmg'] = new Proj4phpProjNzmg();
 |