Beispiel #1
0
        /// <summary>
        /// Returns new geodetic coordinate in radians
        /// </summary>
        /// <param name="glat1">Latitude in Radians</param>
        /// <param name="glon1">Longitude in Radians</param>
        /// <param name="faz">Bearing</param>
        /// <param name="s">Distance</param>
        /// <param name="ellipse">Earth Ellipse Values</param>
        /// <returns>double[]</returns>
        public static double[] Direct_Ell(double glat1, double glon1, double faz, double s, double[] ellipse)
        {
            glon1 *= -1;                //REVERSE LONG FOR CALC 2.1.1.1
            double EPS = 0.00000000005; //Used to determine if starting at pole.
            double r, tu, sf, cf, b, cu, su, sa, c2a, x, c, d, y, sy = 0, cy = 0, cz = 0, e = 0;
            double glat2, glon2, f;

            //Determine if near pole
            if ((Math.Abs(Math.Cos(glat1)) < EPS) && !(Math.Abs(Math.Sin(faz)) < EPS))
            {
                Debug.WriteLine("Warning: Location is at earth's pole. Only N-S courses are meaningful at this location.");
            }


            double a = ellipse[0]; //Equitorial Radius

            f  = 1 / ellipse[1];   //Flattening
            r  = 1 - f;
            tu = r * Math.Tan(glat1);
            sf = Math.Sin(faz);
            cf = Math.Cos(faz);
            if (cf == 0)
            {
                b = 0.0;
            }
            else
            {
                b = 2.0 * Math.Atan2(tu, cf);
            }
            cu  = 1.0 / Math.Sqrt(1 + tu * tu);
            su  = tu * cu;
            sa  = cu * sf;
            c2a = 1 - sa * sa;
            x   = 1.0 + Math.Sqrt(1.0 + c2a * (1.0 / (r * r) - 1.0));
            x   = (x - 2.0) / x;
            c   = 1.0 - x;
            c   = (x * x / 4.0 + 1.0) / c;
            d   = (0.375 * x * x - 1.0) * x;
            tu  = s / (r * a * c);
            y   = tu;
            c   = y + 1;
            while (Math.Abs(y - c) > EPS)
            {
                sy = Math.Sin(y);
                cy = Math.Cos(y);
                cz = Math.Cos(b + y);
                e  = 2.0 * cz * cz - 1.0;
                c  = y;
                x  = e * cy;
                y  = e + e - 1.0;
                y  = (((sy * sy * 4.0 - 3.0) * y * cz * d / 6.0 + x) *
                      d / 4.0 - cz) * sy * d + tu;
            }

            b = cu * cy * cf - su * sy;
            c = r * Math.Sqrt(sa * sa + b * b);
            d = su * cy + cu * sy * cf;

            glat2 = ModM.ModLat(Math.Atan2(d, c));
            c     = cu * cy - su * sy * cf;
            x     = Math.Atan2(sy * sf, c);
            c     = ((-3.0 * c2a + 4.0) * f + 4.0) * c2a * f / 16.0;
            d     = ((e * cy * c + cz) * sy * c + y) * sa;
            glon2 = ModM.ModLon(glon1 + x - (1.0 - c) * d * f);  //Adjust for IDL
            //baz = ModM.ModCrs(Math.Atan2(sa, b) + Math.PI);
            return(new double[] { glat2, glon2 });
        }