private static void OSGB36ToWGS84()
        {
            var airy1830 = new RefEll(6377563.396, 6356256.909);
            var a        = airy1830.maj;
            var eSquared = airy1830.ecc;
            var phi      = Deg2Rad(lat);
            var lambda   = Deg2Rad(lng);
            var v        = a / (Math.Sqrt(1 - eSquared * SinSquared(phi)));
            var H        = 0; // height
            var x        = (v + H) * Math.Cos(phi) * Math.Cos(lambda);
            var y        = (v + H) * Math.Cos(phi) * Math.Sin(lambda);
            var z        = ((1 - eSquared) * v + H) * Math.Sin(phi);

            var tx = 446.448;
            var ty = -124.157;
            var tz = 542.060;
            var s  = -0.0000204894;
            var rx = Deg2Rad(0.00004172222);
            var ry = Deg2Rad(0.00006861111);
            var rz = Deg2Rad(0.00023391666);

            var xB = tx + (x * (1 + s)) + (-rx * y) + (ry * z);
            var yB = ty + (rz * x) + (y * (1 + s)) + (-rx * z);
            var zB = tz + (-ry * x) + (rx * y) + (z * (1 + s));

            var wgs84 = new RefEll(6378137.000, 6356752.3141);

            a        = wgs84.maj;
            eSquared = wgs84.ecc;

            var lambdaB = Rad2Deg(Math.Atan(yB / xB));
            var p       = Math.Sqrt((xB * xB) + (yB * yB));
            var phiN    = Math.Atan(zB / (p * (1 - eSquared)));

            for (var i = 1; i < 10; i++)
            {
                v = a / (Math.Sqrt(1 - eSquared * SinSquared(phiN)));
                double phiN1 = Math.Atan((zB + (eSquared * v * Math.Sin(phiN))) / p);
                phiN = phiN1;
            }

            var phiB = Rad2Deg(phiN);

            lat = phiB;
            lng = lambdaB;
        }
        public LatitudeLongitude ConvertOrdnanceSurveyToLatitudeLongitude(double easting, double northing)
        {
            RefEll airy1830 = new RefEll(6377563.396, 6356256.909);
            double OSGB_F0  = 0.9996012717;
            double N0       = -100000.0;
            double E0       = 400000.0;
            double phi0     = Deg2Rad(49.0);
            double lambda0  = Deg2Rad(-2.0);
            double a        = airy1830.maj;
            double b        = airy1830.min;
            double eSquared = airy1830.ecc;
            double phi      = 0.0;
            double lambda   = 0.0;
            double E        = easting;
            double N        = northing;
            double n        = (a - b) / (a + b);
            double M        = 0.0;
            double phiPrime = ((N - N0) / (a * OSGB_F0)) + phi0;

            do
            {
                M =
                    (b * OSGB_F0)
                    * (((1 + n + ((5.0 / 4.0) * n * n) + ((5.0 / 4.0) * n * n * n))
                        * (phiPrime - phi0))
                       - (((3 * n) + (3 * n * n) + ((21.0 / 8.0) * n * n * n))
                          * Math.Sin(phiPrime - phi0)
                          * Math.Cos(phiPrime + phi0))
                       + ((((15.0 / 8.0) * n * n) + ((15.0 / 8.0) * n * n * n))
                          * Math.Sin(2.0 * (phiPrime - phi0))
                          * Math.Cos(2.0 * (phiPrime + phi0)))
                       - (((35.0 / 24.0) * n * n * n)
                          * Math.Sin(3.0 * (phiPrime - phi0))
                          * Math.Cos(3.0 * (phiPrime + phi0))));
                phiPrime += (N - N0 - M) / (a * OSGB_F0);
            } while ((N - N0 - M) >= 0.001);
            var v   = a * OSGB_F0 * Math.Pow(1.0 - eSquared * SinSquared(phiPrime), -0.5);
            var rho =
                a
                * OSGB_F0
                * (1.0 - eSquared)
                * Math.Pow(1.0 - eSquared * SinSquared(phiPrime), -1.5);
            var etaSquared = (v / rho) - 1.0;
            var VII        = Math.Tan(phiPrime) / (2 * rho * v);
            var VIII       =
                (Math.Tan(phiPrime) / (24.0 * rho * Math.Pow(v, 3.0)))
                * (5.0
                   + (3.0 * TanSquared(phiPrime))
                   + etaSquared
                   - (9.0 * TanSquared(phiPrime) * etaSquared));
            var IX =
                (Math.Tan(phiPrime) / (720.0 * rho * Math.Pow(v, 5.0)))
                * (61.0
                   + (90.0 * TanSquared(phiPrime))
                   + (45.0 * TanSquared(phiPrime) * TanSquared(phiPrime)));
            var X  = Sec(phiPrime) / v;
            var XI =
                (Sec(phiPrime) / (6.0 * v * v * v))
                * ((v / rho) + (2 * TanSquared(phiPrime)));
            var XII =
                (Sec(phiPrime) / (120.0 * Math.Pow(v, 5.0)))
                * (5.0
                   + (28.0 * TanSquared(phiPrime))
                   + (24.0 * TanSquared(phiPrime) * TanSquared(phiPrime)));
            var XIIA =
                (Sec(phiPrime) / (5040.0 * Math.Pow(v, 7.0)))
                * (61.0
                   + (662.0 * TanSquared(phiPrime))
                   + (1320.0 * TanSquared(phiPrime) * TanSquared(phiPrime))
                   + (720.0
                      * TanSquared(phiPrime)
                      * TanSquared(phiPrime)
                      * TanSquared(phiPrime)));

            phi =
                phiPrime
                - (VII * Math.Pow(E - E0, 2.0))
                + (VIII * Math.Pow(E - E0, 4.0))
                - (IX * Math.Pow(E - E0, 6.0));
            lambda =
                lambda0
                + (X * (E - E0))
                - (XI * Math.Pow(E - E0, 3.0))
                + (XII * Math.Pow(E - E0, 5.0))
                - (XIIA * Math.Pow(E - E0, 7.0));


            lat = Rad2Deg(phi);
            lng = Rad2Deg(lambda);
            // convert to WGS84
            OSGB36ToWGS84();

            return(new LatitudeLongitude(lat, lng));
        }