/// <summary> /// 平面坐标转经纬坐标 /// 1.若平面坐标point的Y为6位,需指定center中央子午线经度 /// </summary> /// <param name="point">平面坐标</param> /// <param name="center">中央子午线经度,若为null,Y为8位带带号数字,否则Y应为6位数字</param> /// <param name="bandtype"></param> /// <param name="coordinate"></param> /// <returns>X纬,Y经</returns> public static Point Plane2Geo(Point point, double?center = null, EBandType bandtype = EBandType.度带, ECoordinate coordinate = ECoordinate.北京54) { double t_f; double Eta_f; double B_f; double N_f; double M_f; double B0; double K0, K2, K4, K6; double dh; double y = point.Y; double x = point.X; if (center == null) { dh = (int)(y / 1000000); //带号 y = (y % 1000000) - 500000; } else { dh = 0; y = y - 500000; } double a, b, e1, e2; //椭球参数 getpara(coordinate, out a, out b); e1 = Math.Sqrt(a * a - b * b) / a; e2 = Math.Sqrt(a * a - b * b) / b; double A0; A0 = 1.0 + 3.0 / 4 * e1 * e1 + 45.0 / 64 * Math.Pow(e1, 4) + 350.0 / 512 * Math.Pow(e1, 6) + 11025.0 / 16384 * Math.Pow(e1, 8); B0 = x / (a * (1 - e1 * e1) * A0); K0 = 1.0 / 2 * (3.0 / 4 * e1 * e1 + 45.0 / 64 * Math.Pow(e1, 4) + 350.0 / 512 * Math.Pow(e1, 6) + 11025.0 / 16384 * Math.Pow(e1, 8)); K2 = -1.0 / 3 * (63.0 / 64 * Math.Pow(e1, 4) + 1108.0 / 512 * Math.Pow(e1, 6) + 58239.0 / 16384 * Math.Pow(e1, 8)); K4 = 1.0 / 3 * (604.0 / 512 * Math.Pow(e1, 6) + 68484.0 / 16384 * Math.Pow(e1, 8)); K6 = -1.0 / 3 * (26328.0 / 16384 * Math.Pow(e1, 8)); B_f = B0 + Math.Sin(2 * B0) * (K0 + Math.Sin(B0) * Math.Sin(B0) * (K4 + K6 * Math.Sin(B0) * Math.Sin(B0))); t_f = Math.Tan(B_f); Eta_f = e2 * Math.Cos(B_f); N_f = a / Math.Sqrt(1 - e1 * e1 * Math.Sin(B_f) * Math.Sin(B_f)); M_f = N_f / (1 + e2 * e2 * Math.Cos(B_f) * Math.Cos(B_f)); double B; B = B_f - t_f / (2 * M_f * N_f) * y * y + t_f / (24 * M_f * Math.Pow(N_f, 3)) * (5 + 3 * t_f * t_f + Eta_f * Eta_f - 9 * Eta_f * Eta_f * t_f * t_f) * Math.Pow(y, 4) - t_f / (720 * M_f * Math.Pow(N_f, 5)) * (61 + 90 * t_f * t_f + 45 * Math.Pow(t_f, 4)) * Math.Pow(y, 6); double l; l = 1.0 / (N_f * Math.Cos(B_f)) * y - 1.0 / (6 * Math.Pow(N_f, 3) * Math.Cos(B_f)) * (1 + 2 * t_f * t_f + Eta_f * Eta_f) * Math.Pow(y, 3) + 1.0 / (120 * Math.Pow(N_f, 5) * Math.Cos(B_f)) * (5 + 28 * t_f * t_f + 24 * Math.Pow(t_f, 4) + 6 * Eta_f * Eta_f + 8 * Eta_f * Eta_f * t_f * t_f) * Math.Pow(y, 5); //将B转化为度分秒的形式 double dDegB; dDegB = B * 180 / Math.PI; double dDegL; dDegL = l * 180 / Math.PI; if (center == null) { if (bandtype == EBandType.度带) { center = dh * 3; } else if (bandtype == EBandType.六度带) { center = dh * 6 - 3; } } return(new Point(dDegB, dDegL + (double)center)); }
/// <summary> /// 经纬转平面坐标 /// 1.若参数center为null,则按三或六度带自动确定中央子午线经度,返回结果的Y为8位,前两位为带号 /// 2.若参数center指定中央子午线经度,返回结果Y为6位 /// </summary> /// <param name="geopoint">经纬度坐标,x纬y经</param> /// <param name="center">中央子午度经度</param> /// <param name="bandtype"></param> /// <param name="coordinate"></param> /// <returns>若center=null, Y为8位,前两位为带号, 否则为6位</returns> public static Point geo2Plane(Point geopoint, double?center = null, EBandType bandtype = EBandType.度带, ECoordinate coordinate = ECoordinate.北京54) { double N; double t; double Eta; double X; double A0, A2, A4, A6, A8; double RadB; double Rou; Rou = 180 * 3600 / Math.PI; double longitude = geopoint.Y; //.Longitude; double latitude = geopoint.X; //.Latitude; double a, b, e1, e2; //椭球参数 getpara(coordinate, out a, out b); e1 = Math.Sqrt(a * a - b * b) / a; e2 = Math.Sqrt(a * a - b * b) / b; double l; double L0; int n; if (center != null) //指定中央经线 { L0 = (int)center; n = 0; } else { if (bandtype == EBandType.度带) { n = (int)((longitude + 1.5) / 3); L0 = 3 * n; } else { n = (int)(longitude / 6) + 1; L0 = 6 * n - 3; } } //L0 = 111; double L; L = longitude; l = (L - L0) * 3600; RadB = (latitude) * Math.PI / 180; N = a / Math.Sqrt(1 - e1 * e1 * Math.Sin(RadB) * Math.Sin(RadB)); t = Math.Tan(RadB); Eta = e2 * Math.Cos(RadB); A0 = 1.0 + 3.0 / 4 * e1 * e1 + 45.0 / 64 * Math.Pow(e1, 4) + 350.0 / 512 * Math.Pow(e1, 6) + 11025.0 / 16384 * Math.Pow(e1, 8); A2 = -1.0 / 2 * (3.0 / 4 * e1 * e1 + 60.0 / 64 * Math.Pow(e1, 4) + 525.0 / 512 * Math.Pow(e1, 6) + 17640.0 / 16384 * Math.Pow(e1, 8)); A4 = 1.0 / 4 * (15.0 / 64 * Math.Pow(e1, 4) + 210.0 / 512 * Math.Pow(e1, 6) + 8820.0 / 16384 * Math.Pow(e1, 8)); A6 = -1.0 / 6 * (35.0 / 512 * Math.Pow(e1, 6) + 2520.0 / 16384 * Math.Pow(e1, 8)); A8 = 1.0 / 8 * (315.0 / 16384 * Math.Pow(e1, 8)); X = a * (1 - e1 * e1) * (A0 * RadB + A2 * Math.Sin(2 * RadB) + A4 * Math.Sin(4 * RadB) + A6 * Math.Sin(6 * RadB) + A8 * Math.Sin(8 * RadB)); //计算平面横轴 double plane_X = X + N / (2 * Rou * Rou) * Math.Sin(RadB) * Math.Cos(RadB) * l * l + N / (24 * Math.Pow(Rou, 4)) * Math.Sin(RadB) * Math.Pow(Math.Cos(RadB), 3) * (5 - t * t + 9 * Eta * Eta + 4 * Math.Pow(Eta, 4)) * Math.Pow(l, 4) + N / (720 * Math.Pow(Rou, 6)) * Math.Sin(RadB) * Math.Pow(Math.Cos(RadB), 5) * (61 - 58 * t * t + Math.Pow(t, 4)) * Math.Pow(l, 6); //计算平面纵轴 double plane_Y = N / Rou * Math.Cos(RadB) * l + N / (6 * Math.Pow(Rou, 3)) * Math.Pow(Math.Cos(RadB), 3) * (1 - t * t + Eta * Eta) * Math.Pow(l, 3) + N / (120 * Math.Pow(Rou, 5)) * Math.Pow(Math.Cos(RadB), 5) * (5 - 18 * t * t + Math.Pow(t, 4) + 14 * Eta * Eta - 58 * Eta * Eta * t * t) * Math.Pow(l, 5); double py; if (center == null) { py = double.Parse(n.ToString() + (plane_Y + 500000).ToString()); } else { py = plane_Y + 500000; } return(new Point(plane_X, py)); }