So how the hell do you convert from one coordinate system to another. Well the proper way would be to study and learn all about 3D trig.
The easy way is to read this paper:
National GPS Network information: Annexe C. Converting between grid Eastings and Northings and ellipsoidal latitude and longitudeI've done this and it made my eyes bleed. I've taken the information in it and produced the following C# code:
using System;
namespace tt
{
///
///
///
public class LatLonConversions
{
const double a = 6377563.396;
const double b = 6356256.91;
const double e2 = (a -b)/a;
const double n0 = -100000;
const double e0 = 400000;
const double f0 = 0.999601272;
const double phi0 = 0.855211333;
const double lambda0 = -0.034906585;
const double n = (a-b)/(a+b);
private LatLonConversions()
{ }
public static LatLon ConvertOSToLatLon(double E, double N)
{
double phi = 0;
phi = (N-n0)/(a*f0) + phi0;
double M = b * f0 * ( (1 + n + 5/4*n*n + 5/4*n*n*n)*(phi - phi0) - (3*n + 3*n*n + 21/8*n*n*n) * Math.Sin(phi-phi0) * Math.Cos(phi+phi0) +
(15/8*n*n + 15/8*n*n*n) * Math.Sin(2*(phi-phi0))*Math.Cos(2*(phi+phi0))-35/24*n*n*n*Math.Sin(3*(phi-phi0))*Math.Cos(3*(phi+phi0)));
while (N-n0-M>=0.01)
{
phi = (N-n0-M)/(a*f0)+phi;
M = b * f0 * ( (1 + n + 5/4*n*n + 5/4*n*n*n)*(phi - phi0) - (3*n + 3*n*n + 21/8*n*n*n) * Math.Sin(phi-phi0) * Math.Cos(phi+phi0) +
(15/8*n*n + 15/8*n*n*n) * Math.Sin(2*(phi-phi0))*Math.Cos(2*(phi+phi0))-35/24*n*n*n*Math.Sin(3*(phi-phi0))*Math.Cos(3*(phi+phi0)));
}
double v = a*f0*Math.Pow(1-e2*Math.Sin(phi)*Math.Sin(phi),-0.5);
double p = a*f0*Math.Pow(1-e2*Math.Sin(phi)*Math.Sin(phi),-1.5)*(1-e2);
double n2 = v/p-1;
double vii = Math.Tan(phi)/(2*p*v);
double viii = Math.Tan(phi)/(24*p*v*v*v)*(5+3*Math.Tan(phi)*Math.Tan(phi) + n2 - 9*Math.Tan(phi)*Math.Tan(phi)*n2);
double ix = Math.Tan(phi)/(720*p*Math.Pow(v, 5)) * (61 + 90 * Math.Tan(phi) * Math.Tan(phi) + 45 * Math.Pow(Math.Tan(phi), 4));
double x = (1/Math.Cos(phi))/v;
double xi = (1/Math.Cos(phi))/(6*Math.Pow(v, 3)) * (v/p + 2*Math.Pow(Math.Tan(phi), 2));
double xii = (1/Math.Cos(phi))/(120*Math.Pow(v, 5)) * (5 + 28*Math.Pow(Math.Tan(phi), 2) +24*Math.Pow(Math.Tan(phi), 4));
double xiia = (1/Math.Cos(phi))/(5040*Math.Pow(v, 7)) * (61 + 662*Math.Pow(Math.Tan(phi), 2) +1320*Math.Pow(Math.Tan(phi), 4)+ 720*Math.Pow(Math.Tan(phi), 6));
double e = (E-e0);
double lon = (phi - vii * e*e + viii*e*e*e*e-ix*e*e*e*e*e*e ) * 180 / Math.PI;
double lat = (lambda0 + x*e - xi*e*e*e + xii*e*e*e*e*e - xiia*e*e*e*e*e*e*e) *180 / Math.PI;
return new LatLon(lon, lat);
}
}
public class LatLon
{
public double Latitude;
public double Longitude;
public LatLon()
{
Latitude =0;
Longitude =0;
}
public LatLon(double lat, double lon)
{
Latitude =lat;
Longitude =lon;
}
}
}
You can test an implementation of this code using my
OS2LatLong webservice.