コード例 #1
0
        /**
         * Convert lat/lon point in WGS84 to OSGB36
         *
         * @param  {LatLon} pWGS84: lat/lon in WGS84 reference frame
         * @return {LatLon} lat/lon point in OSGB36 reference frame
         */
        private LatLong ConvertOSGB36ToWGS84(double northing, double easting)
        {
            LatLong LatLongOSGB36 = OSGB36GridToLatLong(northing, easting);

            return(ConvertEllipsoidOSGB36ToWGS84(LatLongOSGB36));
        }
コード例 #2
0
        /**
         * Convert lat/lon from one ellipsoidal model to another
         *
         * q.v. Ordnance Survey 'A guide to coordinate systems in Great Britain' Section 6
         *      www.ordnancesurvey.co.uk/oswebsite/gps/docs/A_Guide_to_Coordinate_Systems_in_Great_Britain.pdf
         *
         * @private
         * @param {LatLon}   point: lat/lon in source reference frame
         * @param {Number[]} sourceEllipse:    source ellipse parameters
         * @param {Number[]} t:     Helmert transform parameters
         * @param {Number[]} targetEllipse:    target ellipse parameters
         * @return {Coord} lat/lon in target reference frame
         */
        private LatLong ConvertEllipsoidOSGB36ToWGS84(LatLong point)
        {
            var t = TransformFromOSGB36ToWGS84;
            var sourceEllipse = Ellipse[EllipseEnum.Airy1830];
            var targetEllipse = Ellipse[EllipseEnum.WGS84];
            // -- 1: convert polar to Cartesian coordinates (using ellipse 1)

            var lat = ToRadian(point.Lat);
            var lon = ToRadian(point.Long);

            var a = sourceEllipse.A;
            var b = sourceEllipse.B;

            var sinPhi = Math.Sin(lat);
            var cosPhi = Math.Cos(lat);
            var sinLambda = Math.Sin(lon);
            var cosLambda = Math.Cos(lon);
            var h = 24.7; // for the moment

            var eSq = (a * a - b * b) / (a * a);
            var nu = a / Math.Sqrt(1 - eSq * sinPhi * sinPhi);

            var x1 = (nu + h) * cosPhi * cosLambda;
            var y1 = (nu + h) * cosPhi * sinLambda;
            var z1 = ((1 - eSq) * nu + h) * sinPhi;

            // -- 2: apply Helmert transform using appropriate params

            var tx = t.Tx;
            var ty = t.Ty;
            var tz = t.Tz;
            var rx = ToRadian(t.Rx / 3600); // normalise seconds to radians
            var ry = ToRadian(t.Ry / 3600);
            var rz = ToRadian(t.Rz / 3600);
            var s1 = t.S / 1e6 + 1; // normalise ppm to (s+1)

            // apply transform
            var x2 = tx + x1 * s1 - y1 * rz + z1 * ry;
            var y2 = ty + x1 * rz + y1 * s1 - z1 * rx;
            var z2 = tz - x1 * ry + y1 * rx + z1 * s1;

            // -- 3: convert Cartesian to polar coordinates (using ellipse 2)

            a = targetEllipse.A;
            b = targetEllipse.B;
            var precision = 4 / a; // results accurate to around 4 metres

            eSq = (a * a - b * b) / (a * a);
            var p = Math.Sqrt(x2 * x2 + y2 * y2);
            var phi = Math.Atan2(z2, p * (1 - eSq));
            var phiP = 2 * Math.PI;
            while (Math.Abs(phi - phiP) > precision)
            {
                nu = a / Math.Sqrt(1 - eSq * Math.Sin(phi) * Math.Sin(phi));
                phiP = phi;
                phi = Math.Atan2(z2 + eSq * nu * Math.Sin(phi), p);
            }
            var lambda = Math.Atan2(y2, x2);
            h = p / Math.Cos(phi) - nu;

            return new LatLong(ToDegree(phi), ToDegree(lambda), h);
        }
コード例 #3
0
        /**
         * Convert lat/lon from one ellipsoidal model to another
         *
         * q.v. Ordnance Survey 'A guide to coordinate systems in Great Britain' Section 6
         *      www.ordnancesurvey.co.uk/oswebsite/gps/docs/A_Guide_to_Coordinate_Systems_in_Great_Britain.pdf
         *
         * @private
         * @param {LatLon}   point: lat/lon in source reference frame
         * @param {Number[]} sourceEllipse:    source ellipse parameters
         * @param {Number[]} t:     Helmert transform parameters
         * @param {Number[]} targetEllipse:    target ellipse parameters
         * @return {Coord} lat/lon in target reference frame
         */
        private LatLong ConvertEllipsoidOSGB36ToWGS84(LatLong point)
        {
            var t             = TransformFromOSGB36ToWGS84;
            var sourceEllipse = Ellipse[EllipseEnum.Airy1830];
            var targetEllipse = Ellipse[EllipseEnum.WGS84];
            // -- 1: convert polar to Cartesian coordinates (using ellipse 1)

            var lat = ToRadian(point.Lat);
            var lon = ToRadian(point.Long);

            var a = sourceEllipse.A;
            var b = sourceEllipse.B;

            var sinPhi    = Math.Sin(lat);
            var cosPhi    = Math.Cos(lat);
            var sinLambda = Math.Sin(lon);
            var cosLambda = Math.Cos(lon);
            var h         = 24.7; // for the moment

            var eSq = (a * a - b * b) / (a * a);
            var nu  = a / Math.Sqrt(1 - eSq * sinPhi * sinPhi);

            var x1 = (nu + h) * cosPhi * cosLambda;
            var y1 = (nu + h) * cosPhi * sinLambda;
            var z1 = ((1 - eSq) * nu + h) * sinPhi;


            // -- 2: apply Helmert transform using appropriate params

            var tx = t.Tx;
            var ty = t.Ty;
            var tz = t.Tz;
            var rx = ToRadian(t.Rx / 3600); // normalise seconds to radians
            var ry = ToRadian(t.Ry / 3600);
            var rz = ToRadian(t.Rz / 3600);
            var s1 = t.S / 1e6 + 1; // normalise ppm to (s+1)

            // apply transform
            var x2 = tx + x1 * s1 - y1 * rz + z1 * ry;
            var y2 = ty + x1 * rz + y1 * s1 - z1 * rx;
            var z2 = tz - x1 * ry + y1 * rx + z1 * s1;


            // -- 3: convert Cartesian to polar coordinates (using ellipse 2)

            a = targetEllipse.A;
            b = targetEllipse.B;
            var precision = 4 / a; // results accurate to around 4 metres

            eSq = (a * a - b * b) / (a * a);
            var p    = Math.Sqrt(x2 * x2 + y2 * y2);
            var phi  = Math.Atan2(z2, p * (1 - eSq));
            var phiP = 2 * Math.PI;

            while (Math.Abs(phi - phiP) > precision)
            {
                nu   = a / Math.Sqrt(1 - eSq * Math.Sin(phi) * Math.Sin(phi));
                phiP = phi;
                phi  = Math.Atan2(z2 + eSq * nu * Math.Sin(phi), p);
            }
            var lambda = Math.Atan2(y2, x2);

            h = p / Math.Cos(phi) - nu;

            return(new LatLong(ToDegree(phi), ToDegree(lambda), h));
        }