static HelmertTransform()
        {
            WGS84toAiry1830 = new HelmertTransform(-446.448, 124.157, -542.060,
                                                   -0.1502, -0.2470, -0.8421,
                                                   20.4894);

            Airy1830toWGS84 = new HelmertTransform(446.448, -124.157, 542.060,
                                                   0.1502, 0.2470, 0.8421,
                                                   -20.4894);
        }
        private LatLng ChangeDatum(Ellipsoid currentEllipsoid, HelmertTransform transform, Ellipsoid targetEllipsoid)
        {
            // This is deliberately ugly C#. It's ported from javascript at http://www.jstott.me.uk/jscoord/ (v1.1.1)
            // The less I touch it, the less chance there is of breaking it.

            var a        = currentEllipsoid.a;
            var b        = currentEllipsoid.b;
            var eSquared = currentEllipsoid.eSquared;
            var phi      = DegreesToRadians(_latitude);
            var lambda   = DegreesToRadians(_longitude);

            var v = a / (Math.Sqrt(1 - eSquared * SinSquared(phi)));
            var H = 0.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 = transform._tx;
            var ty = transform._ty;
            var tz = transform._tz;
            var s  = transform._s;
            var rx = transform._rx;
            var ry = transform._ry;
            var rz = transform._rz;

            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));

            a        = targetEllipsoid.a;
            b        = targetEllipsoid.b;
            eSquared = targetEllipsoid.eSquared;

            var lambdaB = RadiansToDegrees(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)));
                var phiN1 = Math.Atan((zB + (eSquared * v * Math.Sin(phiN))) / p);
                phiN = phiN1;
            }

            var phiB = RadiansToDegrees(phiN);

            LatLng result = new LatLng(phiB, lambdaB);

            return(result);
        }