public override double[] MetersToDegrees(double[] p)
{
double con,phi; /* temporary angles */
double delta_phi; /* difference between longitudes */
long i; /* counter variable */
double sin_phi, cos_phi, tan_phi; /* sin cos and tangent values */
double c, cs, t, ts, n, r, d, ds; /* temporary variables */
long max_iter = 6; /* maximun number of iterations */
double x = p[0] * _metersPerUnit - false_easting;
double y = p[1] * _metersPerUnit - false_northing;
con = (ml0 + y / scale_factor) / this._semiMajor;
phi = con;
for (i=0;;i++)
{
delta_phi = ((con + e1 * Math.Sin(2.0*phi) - e2 * Math.Sin(4.0*phi) + e3 * Math.Sin(6.0*phi))
/ e0) - phi;
phi += delta_phi;
if (Math.Abs(delta_phi) <= EPSLN) break;
if (i >= max_iter)
throw new ArgumentException("Latitude failed to converge");
}
if (Math.Abs(phi) < HALF_PI)
{
sincos(phi, out sin_phi, out cos_phi);
tan_phi = Math.Tan(phi);
c = esp * Math.Pow(cos_phi, 2);
cs = Math.Pow(c, 2);
t = Math.Pow(tan_phi, 2);
ts = Math.Pow(t, 2);
con = 1.0 - es * Math.Pow(sin_phi, 2);
n = this._semiMajor / Math.Sqrt(con);
r = n * (1.0 - es) / con;
d = x / (n * scale_factor);
ds = Math.Pow(d, 2);
double lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24.0 * (5.0 + 3.0 * t +
10.0 * c - 4.0 * cs - 9.0 * esp - ds / 30.0 * (61.0 + 90.0 * t +
298.0 * c + 45.0 * ts - 252.0 * esp - 3.0 * cs)));
double lon = adjust_lon(central_meridian + (d * (1.0 - ds / 6.0 * (1.0 + 2.0 * t +
c - ds / 20.0 * (5.0 - 2.0 * c + 28.0 * t - 3.0 * cs + 8.0 * esp +
24.0 * ts))) / cos_phi));
if (p.Length < 3)
return new double[] { Radians2Degrees(lon), Radians2Degrees(lat) };
else
return new double[] { Radians2Degrees(lon), Radians2Degrees(lat), p[2] };
}
else
{
if (p.Length < 3)
return new double[] { Radians2Degrees(HALF_PI * sign(y)), Radians2Degrees(central_meridian) };
else
return new double[] { Radians2Degrees(HALF_PI * sign(y)), Radians2Degrees(central_meridian), p[2] };
}
}