/// <summary> /// 任意方向上的曲率半径 /// </summary> /// <param name="refEll">参考椭球</param> /// <param name="B">纬度</param> /// <param name="A">方位角</param> /// <returns>该方向的曲率半径</returns> public static double AnyDiretionRadius(ReferenceEllipsoid refEll, Angle B, Angle A) { double N = UnitaryCircleRadius(refEll, B.Seconds); double cosB = Math.Cos(B.Radian); double cosA = Math.Cos(A.Radian); return(N / (1 + refEll.seconde2 * cosB * cosB * cosA * cosA)); }
/// <summary> /// 计算某一纬度处平均曲率半径R /// </summary> /// <param name="refEll">椭球参数</param> /// <param name="b">纬度,以秒为单位</param> /// <returns>纬度为B的平均曲率半径</returns> public static double AverageCircleRadius(ReferenceEllipsoid refEll, double b) { double res = 0; double m = MeridianCircleRadius(refEll, b); double n = UnitaryCircleRadius(refEll, b); res = Math.Sqrt(m * n); return(res); }
/// <summary> /// 地面观测长度归算至椭球面 /// </summary> /// <param name="refEll">椭球参数</param> /// <param name="h1">测站点大地高</param> /// <param name="h2">照准点大地高</param> /// <param name="d">已知斜距</param> /// <param name="b">测站点大地纬度</param> /// <param name="a">测距边大地方位角</param> /// <returns>椭球面大地线长</returns> public static double EllipsoidDistanceCorrection(ReferenceEllipsoid refEll, double h1, double h2, double d, Angle b, Angle a) { double ra = AnyDiretionRadius(refEll, b, a); double hm = (h1 + h2) / 2.0; double dd = Math.Sqrt(d * d - (h2 - h1) * (h2 * h1)); double sin2B = Math.Sin(2 * b.Radian); double cosA = Math.Cos(a.Radian); return(dd * ra / (ra + hm) + d * d * d / (24 * ra * ra) + 1.25E-16 * hm * d * d * sin2B * cosA); }
/// <summary> /// 计算某一纬度处卯酉圈曲率半径N /// </summary> /// <param name="refEllipsoid">椭球参数</param> /// <param name="b">纬度,以秒为单位</param> /// <returns>纬度为B的卯酉圈曲率半径</returns> public static double UnitaryCircleRadius(ReferenceEllipsoid refEll, double b) { double res = 0; b = b / Angle.Rou; double sinB = Math.Sin(b); res = refEll.a * Math.Pow(1 - refEll.firste2 * sinB * sinB, -0.5); return(res); }
/// <summary> /// 由子午线弧长计算该点的纬度 /// </summary> /// <param name="refEll">椭球参数</param> /// <param name="gB">弧长,以米为单位</param> /// <returns>纬度,以秒为单位</returns> public static double LengthOfMeridianAntiCaculate(ReferenceEllipsoid refEll, double gx) { double res = 0; double b0 = gx * Math.Sqrt(1 - refEll.firste2) / refEll.a; double b1 = 0; do { double x1 = LengthOfMeridian(refEll, b0 * Angle.Rou); double deltax = gx - x1; double deltabeta = deltax / MeridianCircleRadius(refEll, b0 * Angle.Rou); double deltab = deltabeta - 1.5 * refEll.firste2 * ((1 + refEll.firste2 * Math.Sin(b0) * Math.Sin(b0)) * Math.Sin(2 * b0) * deltabeta * deltabeta / 2.0 + Math.Cos(2 * b0) * deltabeta * deltabeta * deltabeta / 3.0); b1 = b0 + deltab; double temp = b0; b0 = b1; b1 = temp; } while (Math.Abs(b0 - b1) > 0.000000000001); res = b0 * Angle.Rou; return(res); }
/// <summary> /// 计算从赤道开始到任意纬度B的平行圈之间的弧长 /// </summary> /// <param name="refEll">椭球参数</param> /// <param name="B">纬度,以秒为单位</param> /// <returns>弧长,以米为单位</returns> public static double LengthOfMeridian(ReferenceEllipsoid refEll, double gB) { double res = 0; if (gB < 0) { gB = -gB; } gB = gB / Angle.Rou; double sinB = Math.Sin(gB); double cosB = Math.Cos(gB); double A1 = 1 + (3 / 4.0) * refEll.firste2 + (45 / 64.0) * Math.Pow(refEll.firste2, 2.0) + (175 / 256.0) * Math.Pow(refEll.firste2, 3.0) + (11025 / 16384.0) * Math.Pow(refEll.firste2, 4.0) + (43659 / 65536.0) * Math.Pow(refEll.firste2, 5.0) + (693693 / 1048576.0) * Math.Pow(refEll.firste2, 6.0); double B1 = (3 / 8.0) * refEll.firste2 + (15 / 32.0) * Math.Pow(refEll.firste2, 2.0) + (525 / 1024.0) * Math.Pow(refEll.firste2, 3.0) + (2205 / 4096.0) * Math.Pow(refEll.firste2, 4.0) + (72765 / 131072.0) * Math.Pow(refEll.firste2, 5.0) + (297297 / 524288.0) * Math.Pow(refEll.firste2, 6.0); double C1 = (15 / 256.0) * Math.Pow(refEll.firste2, 2.0) + (105 / 1024.0) * Math.Pow(refEll.firste2, 3.0) + (2205 / 16384.0) * Math.Pow(refEll.firste2, 4.0) + (10395 / 65536.0) * Math.Pow(refEll.firste2, 5.0) + (1486486 / 8388608.0) * Math.Pow(refEll.firste2, 6.0); double D1 = (35 / 3072.0) * Math.Pow(refEll.firste2, 3.0) + (105 / 4096.0) * Math.Pow(refEll.firste2, 4.0) + (10395 / 262144.0) * Math.Pow(refEll.firste2, 5.0) + (55055 / 1048576.0) * Math.Pow(refEll.firste2, 6.0); double E1 = (315 / 131072.0) * Math.Pow(refEll.firste2, 4.0) + (3465 / 524288.0) * Math.Pow(refEll.firste2, 5.0) + (99099 / 8388608.0) * Math.Pow(refEll.firste2, 6.0); double F1 = (693 / 1310720.0) * Math.Pow(refEll.firste2, 5.0) + (9009 / 524288.0) * Math.Pow(refEll.firste2, 6.0); double G1 = (1001 / 8388608.0) * Math.Pow(refEll.firste2, 6.0); res = refEll.a * (1 - refEll.firste2) * (A1 * gB - B1 * Math.Sin(2 * gB) + C1 * Math.Sin(4 * gB) - D1 * Math.Sin(6 * gB) + E1 * Math.Sin(8 * gB) - F1 * Math.Sin(10 * gB) + G1 * Math.Sin(12 * gB)); return(res); }
public GeodeticPoint(ReferenceEllipsoid refEll, GeoCoordinateType geoType, params string[] data) { re = refEll; GeoXYZ gXYZ = new GeoXYZ(0, 0, 0); GeoBLH gBLH = new GeoBLH(0, 0, 0); GeoxyH gxyH = new GeoxyH(0, 0, 0); switch (geoType) { case GeoCoordinateType.XYZ: if (data.Length != 3) { break; } else { gXYZ = new GeoXYZ(data[0], data[1], data[2]); gBLH = ConvertXYZToBLH(gXYZ); gxyH = ConvertBLHToxyH(gBLH); } break; case GeoCoordinateType.BLH: if (data.Length == 2) { gBLH = new GeoBLH(data[0], data[1]); gXYZ = ConvertBLHToXYZ(gBLH); gxyH = ConvertBLHToxyH(gBLH); } else if (data.Length == 3) { gBLH = new GeoBLH(data[0], data[1], data[2]); gXYZ = ConvertBLHToXYZ(gBLH); gxyH = ConvertBLHToxyH(gBLH); } else { break; } break; default: if (data.Length == 2) { gxyH = new GeoxyH(data[0], data[1]); gBLH = ConvertxyHToBLH(gxyH); gXYZ = ConvertBLHToXYZ(gBLH); } else if (data.Length == 3) { gxyH = new GeoxyH(data[0], data[1], data[3]); gBLH = ConvertxyHToBLH(gxyH); gXYZ = ConvertBLHToXYZ(gBLH); } else { break; } break; } gX = gXYZ.gX; gY = gXYZ.gY; gZ = gXYZ.gZ; gB = gBLH.gB; gL = gBLH.gL; gH = gBLH.gH; gx = gxyH.gx; gy = gxyH.gy; }