/// <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; }
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); }
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"); } }
/// <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); }
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); } }
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; } }
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; }
/// <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); }
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; }
/// <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; }
/// <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); }
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); }