关于经纬度算法

  public Angle se(Angle latA, Angle lonA, TKsoft.Earth.Angle latB, Angle lonB)
        {
            //知道 两点经纬度,求角度的方法
            double cosLatB = Math.Cos(latB.Radians);
            Angle tcA = TKsoft.Earth.Angle.FromRadians(Math.Atan2(
                Math.Sin(lonA.Radians - lonB.Radians) * cosLatB,
                Math.Cos(latA.Radians) * Math.Sin(latB.Radians) -
                Math.Sin(latA.Radians) * cosLatB *
                Math.Cos(lonA.Radians - lonB.Radians)));
            if (tcA.Radians < 0)
                tcA.Radians = tcA.Radians + Math.PI * 2;
            tcA.Radians = Math.PI * 2 - tcA.Radians;
            return tcA;
        }

以上代码因项目问题,angle是一个类,各位以此代码 做为参考应该能猜出个大概来(Angle 前缀引用 被 我了)

 /**
         *根据一点、角点(正北0度,顺生针增大)、距离(米)计算另一点
        */
        public static System.Drawing.PointF CalPoint(double x, double y, double angel, double distance)
        {
            //
            System.Drawing.PointF endPoint = new System.Drawing.PointF();
            //角度换算成正东0度,逆时针增大
            angel = -angel - 360+90;
            //米换算成经纬度
            var dis = distance / 1000 / 111.7;
            //角点换成弧度
            angel = angel * Math.PI / 180;
            //计算y坐标
            endPoint.Y = (float)(Math.Sin(angel) * dis + y);
            //计算x坐标
            endPoint.X = (float)(Math.Cos(angel) * dis + x);
            return endPoint;
        }

 

    /// <summary>
        /// 计算两个经纬度之间的经纬度差
        /// </summary>
        /// <param name="pt1"></param>
        /// <param name="pt2"></param>
        /// <returns></returns>
        public static double Distance(IPoint pt1, IPoint pt2)
        {
            return Distance(pt1.X, pt1.Y, pt2.X, pt2.Y);
        }
        /// <summary>
        /// 计算两个坐标点之间的距离
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="tx"></param>
        /// <param name="ty"></param>
        /// <returns></returns>
        public static double Distance(double x, double y, double tx, double ty)
        {
            double a = ty - y;
            double b = tx - x;
            return Math.Sqrt(a * a + b * b);
        }
        /// <summary>
        /// 计算起始点和结束点之间的地理方向
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static double CalcDirection(IPoint start, IPoint end)
        {
            return CalcDirection(start.X, start.Y, end.X, end.Y);
        }


    public static double CalcDirection(double bX, double bY, double eX, double eY)
        {
            double degree = 0;
            double dx = eX - bX;
            double dy = eY - bY;
            if (dx == 0)
            {
                if (bY < eY) degree = 0;
                else degree = 180;
            }
            else
            {
                degree = Math.Atan(dy / dx) * 180 / Math.PI;
                if (degree < 0 && bY < eY) degree = 180 + degree;
                degree = 90 - degree;
                if (bY > eY && bX > eX) degree += 180;
                if (degree == 90 && bX > eX) degree += 180;
            }
            return degree;
        }
    /// <summary>
        /// 获取指定纬度线上纬线圈的半径
        /// </summary>
        /// <param name="lat"></param>
        /// <returns></returns>
        public static double CalcLatRadius(double lat)
        {
            double arc = lat / 180 * Math.PI;
            return Math.Cos(arc) * DrawArgs.EquatorialRadius;
        }
    /// <summary>
        /// 求出指定长度的线段在指定纬度圈上的经度跨度
        /// </summary>
        /// <param name="length">长度(或者距离,单位:米)</param>
        /// <param name="lat">纬度</param>
        /// <returns></returns>
        public static double CalcLonSpan(double length, double lat)
        {
            double c = 2 * Math.PI * CalcLatRadius(lat);
            return length / c * 360;
        }
/// <summary>
        /// 计算指定长度的线段在纬度跨度
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        public static double CalcLatSpan(double length)
        {
            double c = 2 * Math.PI * DrawArgs.EquatorialRadius;
            return length / c * 360;
        }
/// <summary>
        /// 计算num的pwo次幂
        /// </summary>
        /// <param name="num"></param>
        /// <param name="pow"></param>
        /// <returns></returns>
        public static double Pow(double num, int pow)
        {
            double result = Convert.ToDouble(num);
            for (int i = 1; i < pow; i++)
            {
                result *= num;
            }
            return result;
        }
   //定义角度转化为弧度的函数
        public double angle_radian(double[] angle)                                       //角度转化为弧度函数
        {
            double radian;
            radian = (angle[0] + angle[1] / 60 + angle[2] / 3600) / 180 * PI;
            return radian;
        }

        //定义弧度转化为角度的函数
        public double[] radian_angle(double radian)                                      //弧度转化为角度函数
        {
            double degree, minute, second;
            double[] angle = { 0, 0, 0 };
            degree = System.Math.Truncate(radian /PI * 180);
            minute = System.Math.Truncate((radian / PI * 180 - degree) * 60);
            second = System.Math.Abs(((radian / PI * 180 - degree) * 60 - minute) * 60);
            minute = System.Math.Abs(minute);
            angle[0] = degree;
            angle[1] = minute;
            angle[2] = second;
            return angle;
        }
 public static double E = 0.081813334,PI = Math.PI;              //定义常变量
         public static double B1, L1, A1, B2, L2, A2, S;                 //定义主变量
         public static double A,B,C,α,β;                              //定义正算变量
         public static double a1, a2, b1, b2;                           //定义反算变量


//大地主题正算
   //大地主题正算
        private void button1_Click(object sender, EventArgs e)
        { 
             double[] Bre1={0,0,0},Lat1={0,0,0},Ang1={0,0,0}, Bre2={0,0,0},Lat2={0,0,0},Ang2={0,0,0};
             double W1, sinu1, sinu2, cosu1, sinA0, cotσ1, sin2σ1, cos2σ1,couAo, sin2σ1plusσ0, cos2σ1plusσ0, σ, σ0, λ, δ;

             Bre1[0] = Convert.ToDouble(textBox1.Text); Bre1[1] = Convert.ToDouble(textBox2.Text);Bre1[2] = Convert.ToDouble(textBox3.Text);
             Lat1[0] = Convert.ToDouble(textBox4.Text); Lat1[1] = Convert.ToDouble(textBox5.Text);Lat1[2] = Convert.ToDouble(textBox6.Text);
             Ang1[0] = Convert.ToDouble(textBox7.Text); Ang1[1] = Convert.ToDouble(textBox8.Text); Ang1[2] = Convert.ToDouble(textBox9.Text);
             S= Convert.ToDouble(textBox10.Text);
             B1= angle_radian(Bre1);L1= angle_radian(Lat1);A1= angle_radian(Ang1);

            //计算起点规划纬度
             W1 = Math.Sqrt(1.0 - Math.Pow(E *Math.Sin(B1), 2));
             sinu1 = (Math.Sin(B1) * Math.Sqrt(1 - E * E)) / W1;
             cosu1 = Math.Cos(B1) / W1;

            //计算辅助函数值
             sinA0 = cosu1 * Math.Sin(A1);
             cotσ1 = cosu1 * Math.Cos(A1) / sinu1;
             sin2σ1 = cotσ1 * 2 / (cotσ1 * cotσ1 + 1);
             cos2σ1 = (cotσ1 * cotσ1 - 1) / (cotσ1 * cotσ1 + 1);

            //计算必要系数值
             couAo = Math.Sqrt(1 - sinA0 * sinA0);
             A = 6356863.020 + (10708.949 - 13.474 * couAo * couAo) * couAo * couAo;
             B = (5354.469 - 8.978 * couAo * couAo) * couAo * couAo;
             C = (2.238 * couAo * couAo) * couAo * couAo + 0.006;
             α = (33523299 - (28189 - 70 * couAo * couAo) * couAo * couAo) * Math.Pow(10, -10);
             β= (14093.5 - 48.5 * couAo * couAo) * couAo * couAo * System.Math.Pow(10, -10);

             //计算球面长度
             σ0 = (S - (B + C * cos2σ1) * sin2σ1) / A;
             sin2σ1plusσ0 = sin2σ1 * Math.Cos(2 * σ0) + cos2σ1 * Math.Sin(2 * σ0);
             cos2σ1plusσ0 = cos2σ1 * Math.Cos(2 * σ0) - sin2σ1 * Math.Sin(2 * σ0);
             σ = σ0 + (B + 5 * C * cos2σ1plusσ0) * sin2σ1plusσ0 / A;

             //计算经度差改正数
             δ = (α * σ + β * (sin2σ1plusσ0 - sin2σ1)) * sinA0;

            //计算终点大地坐标及坐标方位角
            sinu2 = sinu1 * Math.Cos(σ) + cosu1 * Math.Cos(A1) * Math.Sin(σ);
            B2 = Math.Atan(sinu2 / (Math.Sqrt(1 - E * E) * Math.Sqrt(1 - sinu2 * sinu2)));
            λ = Math.Atan(Math.Sin(A1) * Math.Sin(σ) / (cosu1 * Math.Cos(σ) - sinu1 * Math.Sin(σ) * Math.Cos(A1)));

            if (Math.Sin(A1) > 0)
            {
                if (Math.Tan(λ) > 0)
                {
                    λ = Math.Abs(λ);
                }
                else
                {
                    λ = PI - Math.Abs(λ);
                }
            }
            else
            {
                if (Math.Tan(λ) < 0)
                {
                    λ = -Math.Abs(λ);
                }
                else
                {
                    λ = Math.Abs(λ) - PI;
                }
            }
            L2 = L1 + λ - δ;
            A2 =Math.Atan(cosu1 * Math.Sin(A1) / (cosu1 * Math.Cos(σ) *Math.Cos(A1) - sinu1 *Math.Sin(σ)));
            if (Math.Sin(A1) < 0)
            {
                if (Math.Tan(A2) > 0)
                {
                    A2 = Math.Abs(A2);
                }
                else
                {
                    A2 = PI - Math.Abs(A2);
                }
            }
            else
            {
                if (Math.Tan(A2) > 0)
                {
                    A2 = PI + Math.Abs(A2);
                }
                else
                {
                    A2 = 2 * PI - Math.Abs(A2);
                }
            }
            //将弧度制角化为角度制角                                                                                              
            Bre2 = radian_angle(B2);
            Lat2 = radian_angle(L2);
            Ang2 = radian_angle(A2);


            //通过语句在程序界面显示最后结果
            textBox11.Text = Convert.ToString(Bre2[0]); textBox12.Text = Convert.ToString(Bre2[1]); textBox13.Text = Convert.ToString(Bre2[2]);
            textBox14.Text = Convert.ToString(Lat2[0]); textBox15.Text = Convert.ToString(Lat2[1]); textBox16.Text = Convert.ToString(Lat2[2]);
            textBox17.Text = Convert.ToString(Ang2[0]); textBox18.Text = Convert.ToString(Ang2[1]); textBox19.Text = Convert.ToString(Ang2[2]);

        
        }

//大地主题 反算

  private void button2_Click(object sender, EventArgs e)
        {
             double B1, L1, A1, B2, L2, A2, S;
             double[] Bre1 = { 0, 0, 0 }, Lat1 = { 0, 0, 0 }, Ang1 = { 0, 0, 0 }, Bre2 = { 0, 0, 0 }, Lat2 = { 0, 0, 0 }, Ang2 = { 0, 0, 0 };
             double W1, W2, sinu1, sinu2, cosu1, cosu2, sinA0,cosA0,  sinσ, cosσ, σ,  λ, L, δ, δ1,p, q, x, y, β1,B11,C11;

             Bre1[0] = Convert.ToDouble(textBox25.Text); Bre1[1] = Convert.ToDouble(textBox24.Text); Bre1[2] = Convert.ToDouble(textBox23.Text);
             Lat1[0] = Convert.ToDouble(textBox20.Text); Lat1[1] = Convert.ToDouble(textBox21.Text); Lat1[2] = Convert.ToDouble(textBox22.Text);
             Bre2[0] = Convert.ToDouble(textBox26.Text); Bre2[1] = Convert.ToDouble(textBox27.Text); Bre2[2] = Convert.ToDouble(textBox28.Text);
             Lat2[0] = Convert.ToDouble(textBox29.Text); Lat2[1] = Convert.ToDouble(textBox30.Text); Lat2[2] = Convert.ToDouble(textBox31.Text);
             B1 = angle_radian(Bre1); L1 = angle_radian(Lat1); 
             B2 = angle_radian(Bre2); L2 = angle_radian(Lat2);

             W1 = Math.Sqrt(1 - E * E * Math.Sin(B1) * Math.Sin(B1));
             W2 = Math.Sqrt(1 - E * E * Math.Sin(B2) * Math.Sin(B2));
             sinu1 = (Math.Sin(B1) * Math.Sqrt(1 - E * E)) / W1;
             sinu2 = (Math.Sin(B2) * Math.Sqrt(1 - E * E)) / W2;
             cosu1 = Math.Cos(B1) / W1;
             cosu2 = Math.Cos(B2) / W2;
             L = L2 - L1;
             a1 = sinu1 * sinu2;
             a2 = cosu1 * cosu2;
             b1 = cosu1 * sinu2;
             b2 = sinu1 * cosu2;

             //用逐次趋近法计算大地起点大地方位角、球面长度及经差λ=L+δ:
             δ = 0; λ = 1.0; δ1 = 0;
             do
             {
                 δ = δ1;
                 p = cosu2 * Math.Sin(λ);
                 q = b1 - b2 * Math.Cos(λ);
                 A1 = Math.Atan(p / q);
                 if (p > 0)
                 {
                     if (q > 0)
                     {
                         A1 = Math.Abs(A1);
                     }
                     else
                     {
                         A1 = PI - Math.Abs(A1);
                     }
                 }
                 else
                 {
                     if (p < 0)
                     {
                         A1 =PI + Math.Abs(A1);
                     }
                     else
                     {
                         A1 = 2 * PI - Math.Abs(A1);
                     }
                 }
                 sinσ = p * Math.Sin(A1) + q * Math.Cos(A1);
                 cosσ = a1 + a2 * Math.Cos(λ);
                 σ = Math.Atan(sinσ / cosσ);

                 if (cosσ > 0)   
                      { σ = Math.Abs(σ); } 
                 else
                      { σ = PI - Math.Abs(σ); }

                 sinA0 = cosu1 * Math.Sin(A1);
                 cosA0 = Math.Sqrt(1 - sinA0 * sinA0);
                 x = 2 * a1 - Math.Pow(cosA0, 2) * cosσ;
                α = (33523299 - (28189 - 70 * cosA0 * cosA0) * cosA0 * cosA0) * Math.Pow(10, -10);
                 β1 = (28189 - 94 * cosA0 * cosA0) * Math.Pow(10, -10);
                 δ1 = (α * σ - β1 * x *Math.Sin(σ)) * sinA0;
                 λ = L + δ1;
             } while (Math.Abs(δ - δ1) >= Math.Pow(10, -9));
             δ = δ1;

             //计算某些系数
             A = 6356863.020 + (10708.949 - 13.474 * cosA0 * cosA0) * cosA0 * cosA0;
             B11 = 10708.938 - 17.956 * cosA0 * cosA0;
             C11 = 4.487;

             //计算大地线长度S
             y = (Math.Pow(cosA0, 4) - 2 * x * x) * cosσ;
             S = A * σ + (B11 * x + C11 * y) * sinσ;

             //计算反方位角A2
             p = cosu1 * System.Math.Sin(λ); q = b1 * System.Math.Cos(λ) - b2;
             A2 = System.Math.Atan(p / q);

             if (p < 0)
             {
                 if (q < 0)
                 {
                     A2 = Math.Abs(A2);
                 }
                 else
                 {
                     A2 =PI - Math.Abs(A2);
                 }
             }
             else
             {
                 if (p > 0)
                 {
                     A2 = PI + Math.Abs(A2);
                 }
                 else
                 {
                     A2 = 2 * PI -Math.Abs(A2);
                 }
             }

             //将弧度制角转化为角度制角
             Ang1 = radian_angle(A1);
             Ang2 = radian_angle(A2);

             textBox33.Text = Convert.ToString(Ang1[0]); textBox34.Text = Convert.ToString(Ang1[1]); textBox35.Text = Convert.ToString(Ang1[2]);
             textBox36.Text = Convert.ToString(Ang2[0]); textBox37.Text = Convert.ToString(Ang2[1]); textBox38.Text = Convert.ToString(Ang2[2]);
             textBox32.Text = Convert.ToString(S);


        }

 

    /// <summary>
        /// 计算两个经纬度之间的球面距离
        /// </summary>
        /// <param Name="p1">p1的经纬度</param>
        /// <param Name="p2">p2的经纬度</param>
        /// <returns>距离(单位是米)</returns>
        public static double Distance(PointF p1, PointF p2)
        {
            double _nRslt;
            double x1 = p1.X * Math.PI / 180.0;
            double y1 = p1.Y * Math.PI / 180.0;
            double x2 = p2.X * Math.PI / 180.0;
            double y2 = p2.Y * Math.PI / 180.0;
            _nRslt = Math.Sin(y1) * Math.Sin(y2) + Math.Cos(y1) * Math.Cos(y2) * Math.Cos(Math.Abs(x2 - x1));
            if (_nRslt < 1)
            {
                _nRslt = Math.Atan(-_nRslt / Math.Sqrt(-_nRslt * _nRslt + 1)) + 2.0 * Math.Atan(1);
            }
            else
            {
                _nRslt = 0.0;
            }

            _nRslt = _nRslt * DrawArgs.EquatorialRadius;
            return _nRslt;
        }
posted @ 2015-07-02 20:39  千年问心  阅读(2174)  评论(0编辑  收藏  举报