Пример #1
0
        /// <summary>
        /// Calling this method will convert from the passed value to the OSGB36 convertor
        /// </summary>
        /// <param name="pHorizontal">The point on the horizontal axis (easting or latitude)</param>
        /// <param name="pVertical">The point on the vertical axis (northing or longtitude)</param>
        /// <param name="pHeight">The height to be converted</param>
        /// <returns>The location as a OSGB36 coordinate</returns>
        private ICoordinate InternalCalculate(double pHorizontal, double pVertical, double pHeight)
        {
            double lat = mCoordinateSupport.DegreeesToRadians(pVertical);
            double lon = mCoordinateSupport.DegreeesToRadians(pHorizontal);
            double ht  = pHeight;

            double a = OSGB35Constants.a;

            a *= OSGB35Constants.f0;
            double b = OSGB35Constants.b;

            b *= OSGB35Constants.f0;

            double n   = (a - b) / (a + b);
            double e2  = ((a * a) - (b * b)) / (a * a);
            double nu  = (a / Math.Pow(1 - e2 * Math.Pow(Math.Sin(lat), 2.0), 0.5));
            double rho = ((a * (1 - e2)) / Math.Pow(1 - e2 * Math.Pow(Math.Sin(lat), 2.0), 1.5));
            double n2  = (nu / rho) - 1;

            double dLat = lat - OSGB35Constants.lat0;      // difference in latitude
            double sLat = lat + OSGB35Constants.lat0;      // sum of latitude

            double M = MeridianArc.ComputeMeridanArc(dLat, sLat, n, b);

            double P = lon - OSGB35Constants.lon0;          // difference in longitude

            // The following are taken from [1] pp10-11
            double I    = M + OSGB35Constants.n0;
            double II   = (nu / 2) * Math.Sin(lat) * Math.Cos(lat);
            double III  = (nu / 24) * Math.Sin(lat) * Math.Pow(Math.Cos(lat), 3.0) * (5 - Math.Pow(Math.Tan(lat), 2.0) + (9 * n2));
            double IIIA = (nu / 720) * Math.Sin(lat) * Math.Pow(Math.Cos(lat), 5.0) *
                          (61 - (58 * Math.Pow(Math.Tan(lat), 2.0)) + Math.Pow(Math.Tan(lat), 4.0));
            double IV = nu * Math.Cos(lat);
            double V  = (nu / 6) * Math.Pow(Math.Cos(lat), 3.0) * ((nu / rho) - Math.Pow(Math.Tan(lat), 2.0));
            double VI = (nu / 120) * Math.Pow(Math.Cos(lat), 5.0) * (5 - (18 * Math.Pow(Math.Tan(lat), 2.0)) +
                                                                     Math.Pow(Math.Tan(lat), 4.0) + (14 * n2) - (58 * Math.Pow(Math.Tan(lat), 2.0) * n2));

            double y = I + (Math.Pow(P, 2.0) * II) + (Math.Pow(P, 4.0) * III) + (Math.Pow(P, 6.0) * IIIA);
            double x = OSGB35Constants.e0 + (P * IV) + (Math.Pow(P, 3.0) * V) + (Math.Pow(P, 5.0) * VI);

            Shift s = (Shift)mShifts.CalculateShift(x, y);

            double lLat    = x + s.Easting;
            double lLon    = y + s.Northing;
            double lHeight = pHeight - s.Height;

            EastingNorthing x1 = new EastingNorthing(lLat, lLon, lHeight);

            return(x1);
        }
Пример #2
0
        /// <summary>
        /// Calling this method will convert from the passed value to the LatLon
        /// </summary>
        /// <param name="pHorizontal">The point on the horizontal axis (easting or latitude)</param>
        /// <param name="pVertical">The point on the vertical axis (northing or longtitude)</param>
        /// <param name="pHeight">The height to be converted</param>
        /// <returns>The location as a LatLon coordinate</returns>
        private ICoordinate InternalCalculate(double pHorizontal, double pVertical, double pHeight)
        {
            double eS = 0, nS = 0;
            double ht_dif = 0;
            double E = 0, N = 0;

            Shift s = (Shift)mShifts.CalculateShift(pHorizontal, pVertical);

            eS     = s.Easting;
            nS     = s.Northing;
            ht_dif = Math.Round(s.Height, 3);

            double diff = 0, diffn = 0, NeweS = 0, NewnS = 0;
            int    iterations = 0;

            do
            {
                E = pHorizontal - eS;         // use shifts to calculate OSGRS80 Grid coordinates
                N = pVertical - nS;

                s      = (Shift)mShifts.CalculateShift(pHorizontal, pVertical);
                NeweS  = s.Easting;
                NewnS  = s.Northing;
                ht_dif = s.Height;

                diff  = NeweS - eS;
                diffn = NewnS - nS;

                eS = NeweS;
                nS = NewnS;

                iterations = iterations + 1;
            } while ((iterations < 30) && ((Math.Abs(diff) > 0.00001)) || (Math.Abs(diffn) > 0.00001));

            double a = OSGB35Constants.a;

            a *= OSGB35Constants.f0;
            double b = OSGB35Constants.b;

            b *= OSGB35Constants.f0;


            double n      = (a - b) / (a + b);
            double e2     = ((a * a) - (b * b)) / (a * a);
            double latEst = ((N - OSGB35Constants.n0) / a) + OSGB35Constants.lat0;

            double latNew, dLat, sLat, M;

            iterations = 0;

            do
            {
                dLat = latEst - OSGB35Constants.lat0;      // difference in latitude
                sLat = latEst + OSGB35Constants.lat0;      // sum of latitude

                M      = MeridianArc.ComputeMeridanArc(dLat, sLat, n, b);
                latNew = ((N - OSGB35Constants.n0 - M) / a) + latEst;
                latEst = latNew;
                diff   = N - OSGB35Constants.n0 - M;
            } while ((iterations++ < 30) && (diff > 0.000001));

            double nu  = (a / Math.Pow(1 - e2 * Math.Pow(Math.Sin(latEst), 2.0), 0.5));
            double rho = ((a * (1 - e2)) / Math.Pow(1 - e2 * Math.Pow(Math.Sin(latEst), 2.0), 1.5));
            double n2  = (nu / rho) - 1;

            double VII  = Math.Tan(latEst) / (2 * nu * rho);
            double VIII = (Math.Tan(latEst) / (24 * rho * Math.Pow(nu, 3.0))) * (5 + (3 * Math.Pow(Math.Tan(latEst), 2.0)) +
                                                                                 n2 - (9 * Math.Pow(Math.Tan(latEst), 2.0) * n2));
            double IX = (Math.Tan(latEst) / (720 * rho * Math.Pow(nu, 5.0))) * (61 + (90 * Math.Pow(Math.Tan(latEst), 2.0)) +
                                                                                (45 * Math.Pow(Math.Tan(latEst), 4.0)));
            double X    = 1 / (Math.Cos(latEst) * nu);
            double XI   = (1 / (6 * (Math.Cos(latEst) * Math.Pow(nu, 3.0))) * ((nu / rho) + (2 * Math.Pow(Math.Tan(latEst), 2.0))));
            double XII  = (1 / (120 * (Math.Cos(latEst) * Math.Pow(nu, 5.0))) * (5 + (28 * Math.Pow(Math.Tan(latEst), 2.0)) + (24 * Math.Pow(Math.Tan(latEst), 4.0))));
            double XIIA = (1 / (5040 * (Math.Cos(latEst) * Math.Pow(nu, 7.0))) * (61 + (662 * Math.Pow(Math.Tan(latEst), 2.0)) +
                                                                                  (1320 * Math.Pow(Math.Tan(latEst), 4.0)) + (720 * Math.Pow(Math.Tan(latEst), 6.0))));

            double y  = E - OSGB35Constants.e0;
            double k1 = latEst - (y * y * VII) + (Math.Pow(y, 4.0) * VIII) - (Math.Pow(y, 6.0) * IX);
            double k2 = OSGB35Constants.lon0 + (y * X) - (Math.Pow(y, 3.0) * XI) + (Math.Pow(y, 5.0) * XII) - (Math.Pow(y, 7.0) * XIIA);
            double k3 = pHeight + ht_dif;


            // [TestCase(49.92226393730, -6.29977752014, 100.000, 91492.146, 11318.804, 46.519)]
            double xr1 = mCoordinateSupport.RadiansToDegrees(k1);
            double xr2 = mCoordinateSupport.RadiansToDegrees(k2);

            return(new LatLon(xr1, xr2, k3));
        }