Exemplo n.º 1
0
        /// <summary>
        /// 计算归化纬度
        /// </summary>
        /// <param name="B1">大地纬度</param>
        /// <param name="sinu1">归化纬度sin</param>
        /// <param name="cosu1">归化纬度cos</param>
        private void CalReducedLat(double B1, ref double sinu1, ref double cosu1)
        {
            double e1 = Ell.e1;
            double W1 = GeoPro.GetW(e1, B1);

            sinu1 = Math.Sqrt(1 - e1 * e1) / W1 * Math.Sin(B1);
            cosu1 = Math.Cos(B1) / W1;
        }
Exemplo n.º 2
0
        public static StringBuilder GetReport(Ellipsoid ellipsoid, List <GeodesicInfo> data, int type)
        {
            StringBuilder sb = new StringBuilder();
            string        line;

            line = "**********************************************************************\r\n\r\n";
            sb.Append(line);
            line = "\t\t\t\t大地主题解算报告\r\n\r\n";
            sb.Append(line);
            line = "**********************************************************************\r\n\r\n\r\n";
            sb.Append(line);
            line = "------------------------------统计数据---------------------------------\r\n\r\n";
            sb.Append(line);
            line = "\t计算点对总数:".PadRight(20) + data.Count + "\r\n\r\n";
            sb.Append(line);
            line = "\t椭球长半轴:".PadRight(20) + ellipsoid.a + "\r\n\r\n";
            sb.Append(line);
            line = "\t椭球扁率:".PadRight(20) + ellipsoid.f + "\r\n\r\n";
            sb.Append(line);
            if (type == 1)
            {
                line = "\t计算类型:".PadRight(20) + "大地主题正算\t\r\n\r\n";
            }
            else
            {
                line = "\t计算类型:".PadRight(20) + "大地主题反算\t\r\n\r";
            }
            sb.Append(line);
            line = "\n\n";
            sb.Append(line);


            line = "------------------------------计算结果--------------------------------------\r\n\r\n";
            sb.Append(line);
            line = "\t点名\t纬度(B)\t\t经度 (L)\t\t大地方位角(A)\t\t大地线(S)\r\n\r\n";
            sb.Append(line);
            for (int i = 0; i < data.Count; i++)
            {
                GeodesicInfo info = data[i];
                Pointinfo    p1   = info.P1;
                Pointinfo    p2   = info.P2;
                line = "\n";
                sb.Append(line);
                line = "\t" + p1.Name.PadRight(10) + GeoPro.DMS2String(p1.B).PadRight(15) + GeoPro.DMS2String(p1.L).PadRight(15) + GeoPro.DMS2String(info.A12).PadRight(15) + info.S.ToString("0.000") + "\t\t\r\n\r\n";
                sb.Append(line);
                line = "\t" + p2.Name.PadRight(10) + GeoPro.DMS2String(p2.B).PadRight(15) + GeoPro.DMS2String(p2.L).PadRight(15) + GeoPro.DMS2String(info.A21).PadRight(15) + info.S.ToString("0.000") + "\t\t\r\n\r\n";
                sb.Append(line);
            }



            line = "\n";
            sb.Append(line);
            return(sb);
        }
Exemplo n.º 3
0
        private void UpdateNegTable()
        {
            DataRow dr;

            for (int i = 0; i < NegData.Count; i++)
            {
                GeodesicInfo data = NegData[i];
                dr       = NegDataTable.Rows[i];
                dr["A1"] = GeoPro.DMS2String(data.A12);
                dr["A2"] = GeoPro.DMS2String(data.A21);
                dr["S"]  = data.S.ToString("0.000");
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// 计算A,B,C等参数
        /// </summary>
        /// <param name="sinA0">sinA0</param>
        /// <param name="ABC">ABC数组</param>
        /// <param name="alpha">alpha</param>
        /// <param name="beta">beta</param>
        private void CalABC_AlphaBeta(double sinA0, double[] ABC, ref double alpha, ref double beta, ref double gama)
        {
            double cos2_A0 = 1 - sinA0 * sinA0;
            double k_2 = 0;
            double e2 = Ell.e2, b = Ell.b;
            double e1 = Ell.e1;

            k_2 = GeoPro.Getk_2(e2, cos2_A0);
            GeoPro.GetABC(b, k_2, ABC);
            alpha = GeoPro.GetAlpha(e1, cos2_A0);
            beta  = GeoPro.GetBeta(e1, cos2_A0);
            gama  = GeoPro.GetGama(e1, cos2_A0);
        }
Exemplo n.º 5
0
        private void UpdatePosTable()
        {
            DataRow dr;

            for (int i = 0; i < PosData.Count; i++)
            {
                GeodesicInfo data = PosData[i];

                dr = PosDataTable.Rows[i];
                Pointinfo p2 = data.P2;
                dr["终点"] = p2.Name;
                dr["B2"] = GeoPro.DMS2String(p2.B);
                dr["L2"] = GeoPro.DMS2String(p2.L);
                dr["A2"] = GeoPro.DMS2String(data.A21);
            }
        }
Exemplo n.º 6
0
        private void NegData2Table()
        {
            NegDataTable = new DataTable();
            NegDataTable.Columns.Add("起点", System.Type.GetType("System.String"));
            NegDataTable.Columns.Add("B1", System.Type.GetType("System.String"));
            NegDataTable.Columns.Add("L1", System.Type.GetType("System.String"));
            NegDataTable.Columns.Add("终点", System.Type.GetType("System.String"));
            NegDataTable.Columns.Add("B2", System.Type.GetType("System.String"));
            NegDataTable.Columns.Add("L2", System.Type.GetType("System.String"));
            NegDataTable.Columns.Add("A1", System.Type.GetType("System.String"));
            NegDataTable.Columns.Add("A2", System.Type.GetType("System.String"));
            NegDataTable.Columns.Add("S", System.Type.GetType("System.String"));

            DataRow dr;

            for (int i = 0; i < NegData.Count; i++)
            {
                GeodesicInfo data = NegData[i];
                Pointinfo    p1   = data.P1;
                Pointinfo    p2   = data.P2;
                dr = NegDataTable.NewRow();

                dr["起点"] = p1.Name;
                dr["B1"] = GeoPro.DMS2String(p1.B);
                dr["L1"] = GeoPro.DMS2String(p1.L);
                dr["终点"] = p2.Name;
                dr["B2"] = GeoPro.DMS2String(p2.B);
                dr["L2"] = GeoPro.DMS2String(p2.L);


                NegDataTable.Rows.Add(dr);
            }

            EllipsoidA.Text  = "椭球长半轴(a):" + MyEllipsoid.a;
            Ellipsoidf_.Text = "椭球扁率(f):" + MyEllipsoid.f;

            dataGridViewNeg.DataSource = NegDataTable;
            for (int i = 0; i < dataGridViewNeg.ColumnCount; i++)
            {
                dataGridViewNeg.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
            }
        }
Exemplo n.º 7
0
        private void PosData2Table()
        {
            PosDataTable = new DataTable();
            PosDataTable.Columns.Add("起点", System.Type.GetType("System.String"));
            PosDataTable.Columns.Add("B1", System.Type.GetType("System.String"));
            PosDataTable.Columns.Add("L1", System.Type.GetType("System.String"));
            PosDataTable.Columns.Add("A1", System.Type.GetType("System.String"));
            PosDataTable.Columns.Add("S", System.Type.GetType("System.String"));
            PosDataTable.Columns.Add("终点", System.Type.GetType("System.String"));
            PosDataTable.Columns.Add("B2", System.Type.GetType("System.String"));
            PosDataTable.Columns.Add("L2", System.Type.GetType("System.String"));
            PosDataTable.Columns.Add("A2", System.Type.GetType("System.String"));

            DataRow dr;

            for (int i = 0; i < PosData.Count; i++)
            {
                GeodesicInfo data = PosData[i];
                Pointinfo    p1   = data.P1;
                dr = PosDataTable.NewRow();

                dr["起点"] = p1.Name;
                dr["B1"] = GeoPro.DMS2String(p1.B);
                dr["L1"] = GeoPro.DMS2String(p1.L);
                dr["A1"] = GeoPro.DMS2String(data.A12);
                dr["S"]  = data.S.ToString("0.000");


                PosDataTable.Rows.Add(dr);
            }

            dataGridViewPos.DataSource = PosDataTable;
            for (int i = 0; i < dataGridViewPos.ColumnCount; i++)
            {
                dataGridViewPos.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
            }

            EllipsoidA.Text  = "椭球长半轴(a):" + MyEllipsoid.a;
            Ellipsoidf_.Text = "椭球扁率(f):" + MyEllipsoid.f;
        }
Exemplo n.º 8
0
        /// <summary>
        /// 趋近法算角度
        /// </summary>
        /// <param name="dL">初始经度差</param>
        /// <param name="cosu2">cosu2</param>
        /// <param name="cosu1">cosu1</param>
        /// <param name="ab">ab参数数组</param>
        /// <param name="lamda">lamda经度差估计值</param>
        /// <param name="A1">A1坐标方位角</param>
        /// <param name="del">del</param>
        /// <param name="cos2_A0">cos2_A0</param>
        /// <param name="x">x</param>
        private void CalA1_Lamda(double dL, double u2, double u1, double [] ab, ref double lamda, ref double A1,
                                 ref double del, ref double cos2_A0)
        {
            double deltat = 0, delta = 0;
            double cos_del = 0, sin_del = 0;
            double e1 = Ell.e1;
            double alpha = 0, beta = 0, gama = 0;
            double sinA0;
            double p = 0;
            double q = 0;

            lamda = dL;
            do
            {
                deltat = delta;
                p      = Math.Cos(u2) * Math.Sin(lamda);
                q      = ab[2] - ab[3] * Math.Cos(lamda);
                A1     = Math.Abs(Math.Atan(p / q));
                A1     = GeoPro.InvJudgeA1A2(p, q, A1);

                sin_del = p * Math.Sin(A1) + q * Math.Cos(A1);
                cos_del = ab[0] + ab[1] * Math.Cos(lamda);
                del     = Math.Atan(sin_del / cos_del);
                del     = GeoPro.InvJudgedel(del, cos_del);

                sinA0 = Math.Cos(u1) * Math.Sin(A1);
                double del1 = Math.Atan(Math.Tan(u1) / Math.Cos(A1));
                cos2_A0 = 1 - sinA0 * sinA0;

                alpha = GeoPro.GetAlpha(e1, cos2_A0);
                beta  = GeoPro.GetBeta(e1, cos2_A0);
                gama  = GeoPro.GetGama(e1, cos2_A0);

                delta = (alpha * del + (beta) * Math.Cos(2 * del1 + del) * Math.Sin(del)
                         + gama * Math.Sin(2 * del) * Math.Cos(4 * del1 + 2 * del)) * sinA0;
                lamda = dL + delta;
            } while (Math.Abs(delta - deltat) * 206265 > 0.00001);
        }
Exemplo n.º 9
0
        public void Invertest(GeodesicInfo geodesic)
        {
            //数据格式转换
            double B1 = GeoPro.DMS2RAD(geodesic.P1.B);
            double L1 = GeoPro.DMS2RAD(geodesic.P1.L);
            double B2 = GeoPro.DMS2RAD(geodesic.P2.B);
            double L2 = GeoPro.DMS2RAD(geodesic.P2.L);
            double A12 = 0, A21 = 0, S = 0;
            //椭球参数
            double eps, e2, a, b;

            eps = Ell.e2 * Ell.e2; e2 = Ell.e1 * Ell.e1;
            a   = Ell.a; b = Ell.b;
            double u1     = Math.Atan(Math.Sqrt(1 - e2) * Math.Tan(B1));
            double u2     = Math.Atan(Math.Sqrt(1 - e2) * Math.Tan(B2));
            double DL     = L2 - L1;
            double sa1    = Math.Sin(u1) * Math.Sin(u2);
            double sa2    = Math.Cos(u1) * Math.Cos(u2);
            double cb1    = Math.Cos(u1) * Math.Sin(u2);
            double cb2    = Math.Sin(u1) * Math.Cos(u2);
            double lambda = DL;

            // '-------特殊情况点位判断----------------
            if (u1 == 0 && u2 == 0)
            {
                if (lambda > 0)
                {
                    S   = a * lambda;
                    A12 = Math.PI / 2;
                    A21 = Math.PI * 3 / 2;
                }
                else
                {
                    S   = a * lambda;
                    A21 = Math.PI / 2;
                    A12 = Math.PI * 3 / 2;
                }
            }
            else
            {
                double Dlambda = 0;
                double sinA0 = 0; double sigma = 0; double sigma1 = 0;
                do
                {
                    double lambda0 = lambda;
                    double p       = Math.Cos(u2) * Math.Sin(lambda0);
                    double q       = cb1 - cb2 * Math.Cos(lambda0);
                    A12 = Math.Abs(Math.Atan(p / q));
                    if (p > 0 && q > 0)
                    {
                        A12 = A12;
                    }
                    if (p > 0 && q < 0)
                    {
                        A12 = Math.PI - A12;
                    }
                    if (p < 0 && q < 0)
                    {
                        A12 = Math.PI + A12;
                    }
                    if (p < 0 && q > 0)
                    {
                        A12 = 2 * Math.PI - A12;
                    }

                    double Ssigma = p * Math.Sin(A12) + q * Math.Cos(A12);
                    double csigma = sa1 + sa2 * Math.Cos(lambda0);
                    sigma = Math.Abs(Math.Atan(Ssigma / csigma));
                    if (csigma > 0)
                    {
                        sigma = sigma;
                    }
                    if (csigma < 0)
                    {
                        sigma = Math.PI - sigma;
                    }
                    sinA0  = Math.Cos(u1) * Math.Sin(A12);
                    sigma1 = Math.Atan(Math.Tan(u1) / Math.Cos(A12));

                    double cosA0  = Math.Sqrt(1 - sinA0 * sinA0);
                    double e4     = e2 * e2;
                    double e6     = e4 * e2;
                    double xk2    = e2 * cosA0 * cosA0;
                    double xk4    = xk2 * xk2;
                    double xk6    = xk4 * xk2;
                    double alpha1 = (e2 / 2 + e4 / 8 + e6 / 16) - e2 * (1 + e2) * xk2 / 16 + 3 * xk4 * e2 / 128;
                    double beta1  = e2 * (1 + e2) * xk2 / 16 - e2 * xk4 / 32;
                    double gamma1 = e2 * xk4 / 256;
                    double xxy    = alpha1 * sigma + beta1 * Math.Sin(sigma) * Math.Cos(2 * sigma1 + sigma);
                    xxy     = xxy + gamma1 * Math.Sin(2 * sigma) * Math.Cos(4 * sigma1 + 2 * sigma);
                    lambda  = DL + sinA0 * xxy;
                    Dlambda = Math.Abs(lambda - lambda0) * 206265;
                } while (Dlambda > 0.000001);
                double cosA00 = Math.Sqrt(1 - sinA0 * sinA0);
                double xk20   = eps * cosA00 * cosA00;
                double xk40   = xk20 * xk20;
                double xk60   = xk20 * xk40;
                double alpha  = (1 - xk20 / 4 + 7 * xk40 / 64 - 15 * xk60 / 256) / b;
                double beta   = xk20 / 4 - xk40 / 8 + 37 * xk60 / 512;
                double gamma  = xk40 / 128 - xk60 / 128;
                double xs12   = gamma * Math.Sin(2 * sigma) * Math.Cos(4 * sigma1 + 2 * sigma);
                S = (sigma - beta * Math.Sin(sigma) * Math.Cos(2 * sigma1 + sigma) - xs12) / alpha;

                double sinA2 = Math.Cos(u1) * Math.Sin(A12);
                double cosA2 = Math.Cos(u1) * Math.Cos(sigma) * Math.Cos(A12) - Math.Sin(u1) * Math.Sin(sigma);
                double tanA2 = sinA2 / cosA2;
                A21 = Math.Abs(Math.Atan(sinA2 / cosA2));
                double sinA1 = Math.Sin(A12);
                if (sinA2 > 0 && cosA2 > 0)
                {
                    A21 = A21;
                }
                if (sinA2 > 0 && cosA2 < 0)
                {
                    A21 = Math.PI - A21;
                }
                if (sinA2 < 0 && cosA2 < 0)
                {
                    A21 = Math.PI + A21;
                }
                if (sinA2 < 0 && cosA2 > 0)
                {
                    A21 = 2 * Math.PI - A21;
                }
            }

            geodesic.A12 = GeoPro.RAD2DMS(A12);
            geodesic.A21 = GeoPro.RAD2DMS(A21);
            geodesic.S   = S;
        }
Exemplo n.º 10
0
        /// <summary>
        /// 单组数据反算
        /// </summary>
        /// <param name="geodesic">单组大地线数据</param>
        public void InverseSolution(GeodesicInfo geodesic)
        {
            //数据格式转换
            double B1 = GeoPro.DMS2RAD(geodesic.P1.B);
            double L1 = GeoPro.DMS2RAD(geodesic.P1.L);
            double B2 = GeoPro.DMS2RAD(geodesic.P2.B);
            double L2 = GeoPro.DMS2RAD(geodesic.P2.L);
            double A12 = 0, A21 = 0, S = 0;
            //椭球参数
            double e1, e2, b, c, a;

            e1 = Ell.e1; e2 = Ell.e2;
            b  = Ell.b; c = Ell.c; a = Ell.a;
            //辅助计算

            double u1 = Math.Atan(Math.Sqrt(1 - e1 * e1) * Math.Tan(B1));
            double u2 = Math.Atan(Math.Sqrt(1 - e1 * e1) * Math.Tan(B2));
            double dL = L2 - L1;

            double[] ab = CalPara(u1, u2);
            if (u1 == 0 && u2 == 0)
            {
                if (dL > 0)
                {
                    S   = a * dL;
                    A12 = Math.PI / 2;
                    A21 = Math.PI * 3 / 2;
                }
                else
                {
                    S   = a * dL;
                    A21 = Math.PI / 2;
                    A12 = Math.PI * 3 / 2;
                }
            }
            else
            {
                //逐次趋近法同时计算起点大地方位角,球面长度及经度差lamda
                double del     = 0;
                double lamda   = 0;
                double cos2_A0 = 0;

                CalA1_Lamda(dL, u2, u1, ab, ref lamda, ref A12, ref del, ref cos2_A0);

                //计算S
                double[] ABC = new double[3];
                double   k_2 = GeoPro.Getk_2(e2, cos2_A0);
                GeoPro.GetABC(b, k_2, ABC);

                double del1 = Math.Atan(Math.Tan(u1) / Math.Cos(A12));
                double xs12 = ABC[2] * Math.Sin(2 * del) * Math.Cos(4 * del1 + 2 * del);

                S = (del - ABC[1] * Math.Sin(del) * Math.Cos(2 * del1 + del) - xs12) / ABC[0];
                //计算A2
                A21 = Math.Atan(Math.Cos(u1) * Math.Sin(lamda) / (ab[2] * Math.Cos(lamda) - ab[3]));
                A21 = GeoPro.InvJudgeA1A2(Math.Cos(u1) * Math.Sin(lamda), (ab[2] * Math.Cos(lamda) - ab[3]), A21);
                //
                if (A12 >= Math.PI)
                {
                    A21 = A21 - Math.PI;
                }
                if (A12 < Math.PI)
                {
                    A21 = A21 + Math.PI;
                }
            }

            //
            geodesic.A12 = GeoPro.RAD2DMS(A12);
            geodesic.A21 = GeoPro.RAD2DMS(A21);
            geodesic.S   = S;
        }
Exemplo n.º 11
0
        /// <summary>
        /// 单组数据正算
        /// </summary>
        /// <param name="geodesic">单组大地线数据</param>
        public void DirectSolution(GeodesicInfo geodesic)
        {
            //数据格式转换
            double B1  = GeoPro.DMS2RAD(geodesic.P1.B);
            double L1  = GeoPro.DMS2RAD(geodesic.P1.L);
            double A12 = GeoPro.DMS2RAD(geodesic.A12);
            double S   = geodesic.S;
            //椭球参数
            double e1, e2, b, c;

            e1 = Ell.e1; e2 = Ell.e2;
            b  = Ell.b; c = Ell.c;
            //计算归化纬度
            double sinu1 = 0, cosu1 = 0;

            CalReducedLat(B1, ref sinu1, ref cosu1);

            //计算辅助函数,解球面三角
            double sinA0      = cosu1 * Math.Sin(A12);
            double cot_delta1 = cosu1 * Math.Cos(A12) / sinu1;
            double delta1     = Math.Atan(1.0 / cot_delta1);

            //计算ABC及α和β
            double[] ABC   = new double[3];
            double   alpha = 0;
            double   beta  = 0;
            double   gama  = 0;

            CalABC_AlphaBeta(sinA0, ABC, ref alpha, ref beta, ref gama);

            //计算球面长度
            double delta = ABC[0] * S;

            CalGeodesicLength(delta1, ABC, S, ref delta);

            //计算经差改正数
            double lamda_L = sinA0 * (alpha * delta + beta * Math.Sin(delta) * Math.Cos(2 * delta1 + delta)
                                      + gama * Math.Sin(2 * delta) * Math.Cos(4 * delta1 + 2 * delta));

            //计算终点大地坐标及大地方位角
            double sinu2 = sinu1 * Math.Cos(delta) + cosu1 * Math.Cos(A12) * Math.Sin(delta);
            double B2    = Math.Atan(1 / Math.Sqrt(1 - e1 * e1) * sinu2 / Math.Sqrt(1 - sinu2 * sinu2));

            double lamba = Math.Atan(Math.Sin(delta) * Math.Sin(A12) / (cosu1 * Math.Cos(delta) - sinu1 * Math.Sin(delta)
                                                                        * Math.Cos(A12)));

            lamba = GeoPro.DirJudgelamba(Math.Sin(A12), lamba);

            double L2 = L1 + lamba - lamda_L;

            double A21 = Math.Atan(cosu1 * Math.Sin(A12) / (cosu1 * Math.Cos(delta)
                                                            * Math.Cos(A12) - sinu1 * Math.Sin(delta)));

            A21 = GeoPro.DirJudgeA2(Math.Sin(A12), A21);

            if (A21 > 2 * Math.PI)
            {
                A21 -= 2 * Math.PI;
            }
            if (A21 < 0)
            {
                A21 += 2 * Math.PI;
            }

            //角度转换
            if (A12 >= Math.PI && A21 >= Math.PI)
            {
                A21 = A21 - Math.PI;
            }
            if (A12 < Math.PI && A21 < Math.PI)
            {
                A21 = A21 + Math.PI;
            }
            //
            //  geodesic.P2 = new Pointinfo();



            geodesic.P2.B = GeoPro.RAD2DMS(B2);
            geodesic.P2.L = GeoPro.RAD2DMS(L2);
            geodesic.A21  = GeoPro.RAD2DMS(A21);
        }
Exemplo n.º 12
0
        private void Dirtest(GeodesicInfo geodesic)
        {
            //数据格式转换
            double B1  = GeoPro.DMS2RAD(geodesic.P1.B);
            double L1  = GeoPro.DMS2RAD(geodesic.P1.L);
            double A12 = GeoPro.DMS2RAD(geodesic.A12);
            double S   = geodesic.S;
            //椭球参数
            double eps, e2, b, c, a;

            eps = Ell.e2 * Ell.e2; e2 = Ell.e1 * Ell.e1;
            b   = Ell.b; c = Ell.c; a = Ell.a;
            double u1     = Math.Atan(Math.Sqrt(1 - e2) * Math.Tan(B1));
            double sinA0  = Math.Cos(u1) * Math.Sin(A12);
            double cosA0  = Math.Sqrt(1 - sinA0 * sinA0);
            double sigma1 = Math.Atan(Math.Tan(u1) / Math.Cos(A12));
            double xk2    = eps * cosA0 * cosA0;
            double xk4    = xk2 * xk2;
            double xk6    = xk4 * xk2;
            double alpha  = (1 - xk2 / 4 + 7 * xk4 / 64 - 15 * xk6 / 256) / b;
            double beta   = xk2 / 4 - xk4 / 8 + 37 * xk6 / 512;
            double gamma  = xk4 / 128 - xk6 / 128;

            double sigma  = alpha * S;
            double Dsigma = 0;

            do
            {
                double sigma0 = sigma;
                sigma  = alpha * S + beta * Math.Sin(sigma0) * Math.Cos(2 * sigma1 + sigma0);
                sigma  = sigma + gamma * Math.Sin(2 * sigma0) * Math.Cos(4 * sigma1 + 2 * sigma0);
                Dsigma = Math.Abs(sigma - sigma0) * 206265;
            } while (Dsigma > 0.0001);
            double sinA2 = Math.Cos(u1) * Math.Sin(A12);
            double cosA2 = Math.Cos(u1) * Math.Cos(sigma) * Math.Cos(A12) - Math.Sin(u1) * Math.Sin(sigma);
            double tanA2 = sinA2 / cosA2; double A2 = Math.Abs(Math.Atan(sinA2 / cosA2));
            double sinA1 = Math.Sin(A12);

            if (sinA1 < 0 && tanA2 > 0)
            {
                A2 = A2;
            }
            if (sinA1 < 0 && tanA2 < 0)
            {
                A2 = Math.PI - A2;
            }
            if (sinA1 > 0 && tanA2 > 0)
            {
                A2 = Math.PI + A2;
            }
            if (sinA1 > 0 && tanA2 < 0)
            {
                A2 = 2 * Math.PI - A2;
            }

            double sinU2 = Math.Sin(u1) * Math.Cos(sigma) + Math.Cos(u1) * Math.Cos(A12) * Math.Sin(sigma);
            double B2    = Math.Atan(sinU2 / Math.Sqrt(1 - e2) / Math.Sqrt(1 - sinU2 * sinU2));

            double sinl = Math.Sin(A12) * Math.Sin(sigma);
            double cosl = Math.Cos(u1) * Math.Cos(sigma) - Math.Sin(u1) * Math.Sin(sigma) * Math.Cos(A12);
            double tanlambda = sinl / cosl; double lambda = Math.Abs(Math.Atan(sinl / cosl));

            if (tanlambda > 0 && sinA1 > 0)
            {
                lambda = lambda;
            }
            if (tanlambda < 0 && sinA1 > 0)
            {
                lambda = Math.PI - lambda;
            }
            if (tanlambda < 0 && sinA1 < 0)
            {
                lambda = -lambda;
            }
            if (tanlambda > 0 && sinA1 < 0)
            {
                lambda = lambda - Math.PI;
            }

            double e4 = e2 * e2;
            double e6 = e4 * e2;

            xk2 = e2 * cosA0 * cosA0;
            xk4 = xk2 * xk2;
            xk6 = xk4 * xk2;
            double alpha1 = (e2 / 2 + e4 / 8 + e6 / 16) - e2 * (1 + e2) * xk2 / 16 + 3 * xk4 * e2 / 128;
            double beta1  = e2 * (1 + e2) * xk2 / 16 - e2 * xk4 / 32;
            double gamma1 = e2 * xk4 / 256;
            double l0     = alpha1 * sigma + beta1 * Math.Sin(sigma) * Math.Cos(2 * sigma1 + sigma);

            l0 = l0 + gamma1 * Math.Sin(2 * sigma) * Math.Cos(4 * sigma1 + 2 * sigma);
            double ll = lambda - sinA0 * l0;
            double L2 = L1 + ll;



            geodesic.P2   = new Pointinfo();
            geodesic.P2.B = GeoPro.RAD2DMS(B2);
            geodesic.P2.L = GeoPro.RAD2DMS(L2);
            geodesic.A21  = GeoPro.RAD2DMS(A2);
        }