zoukankan      html  css  js  c++  java
  • 关于经纬度算法

      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;
            }
  • 相关阅读:
    raid0
    GitHub 标星 11000+,阿里开源的微服务组件如何连续 10 年扛住双十一大促?
    写给大家看的“不负责任” K8s 入门文档
    快速迁移 Next.js 应用到函数计算
    轻松搭建基于 Serverless 的 Go 应用(Gin、Beego 举例)
    阿里巴巴副总裁肖力:云原生安全下看企业新边界——身份管理
    从零开始入门 K8s | K8s 安全之访问控制
    深度解读!阿里统一应用管理架构升级的教训与实践
    CNCF 2019 年度报告重磅发布 | 云原生生态周报 Vol. 41
    HTML+CSS技术实现网页滑动门效果
  • 原文地址:https://www.cnblogs.com/chcong/p/4617109.html
Copyright © 2011-2022 走看看