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