//反算 public override void GetBLFromXY(decimal x, decimal y, ref decimal B, ref decimal L) { //this.GetBLFromXY(x, y, ref B, ref L, 0, EnumProjectionDatum.Xian80, this.Strip, this.L0, this.IsBigNumber); //去掉大数和东移500公里 decimal y1 = y - 500000.0M; if (this.IsBigNumber == true) { y1 = y1 - (this.L0 / (int)this.Strip) * 1000000M; } //计算临时参数 decimal E = K0 * x; decimal CosE = Maths.Cos(E); decimal SinE = Maths.Sin(E); decimal SinE3 = SinE * SinE * SinE; decimal SinE5 = SinE3 * SinE * SinE; decimal SinE7 = SinE5 * SinE * SinE; //求底点纬度 decimal Bf = E + CosE * (K1 * SinE - K2 * SinE3 + K3 * SinE5 - K4 * SinE7); //计算临时参数 decimal CosBf = Maths.Cos(Bf); decimal CosBf2 = CosBf * CosBf; decimal t = Maths.Tan(Bf); decimal η2 = e12 * CosBf2; decimal C = a * a / b; decimal V = Maths.Sqrt(1 + η2); decimal N = C / V; decimal V2 = V * V; decimal t2 = t * t; decimal t4 = t2 * t2; decimal y1_N = y1 / N; decimal y1_N2 = y1_N * y1_N; decimal y1_N3 = y1_N2 * y1_N; decimal y1_N4 = y1_N3 * y1_N; decimal y1_N5 = y1_N4 * y1_N; decimal y1_N6 = y1_N5 * y1_N; decimal V2t = V * V * t; //计算经纬度值B,L B = Bf - (V2t * y1_N2) / 2 + ((5 + 3 * t2 + η2 - 9 * η2 * t2) * V2t * y1_N4 * 1.0M) / 24 - ((61 + 90 * t2 + 45 * t4) * V2t * y1_N6 * 1.0M) / 720; L = y1_N * 1.0M / CosBf - (1 + 2 * t2 + η2) * (1.0M / CosBf) * y1_N3 / 6 + (5 + 28 * t2 + 24 * t2 + 6 * η2 + 8 * η2 * t2) * (1.0M / CosBf) * y1_N5 * 1.0M / 120; AngleUnit_D dUnit = new AngleUnit_D(this.L0); L = L + dUnit.getArcDValue(); //弧度 //弧度->度 AngleUnit_ArcD acUnit = new AngleUnit_ArcD(B); dUnit = new AngleUnit_D(acUnit); B = (decimal)dUnit.getAngle(); acUnit = new AngleUnit_ArcD(L); dUnit = new AngleUnit_D(acUnit); L = (decimal)dUnit.getAngle(); }
/// <summary> /// 计算IGeometry的椭球面的 理论面积 /// </summary> /// <param name="geo">输入的分幅图的几何对象IGeometry(矩形状)</param> /// <returns>(单位:平方米)</returns> public override decimal Compute(IGeometry geo) { decimal P = 0.0M; //(1)最大最小角计算出WGS84大地经纬度坐标(四个点) 经差/纬差 decimal xmin = Maths.Todecimal(geo.Envelope.XMin); decimal ymin = Maths.Todecimal(geo.Envelope.YMin); decimal xmax = Maths.Todecimal(geo.Envelope.XMax); decimal ymax = Maths.Todecimal(geo.Envelope.YMax); //(2)转为经纬度坐标 decimal Bmin = 0.0M;//ToWGS84(xmin,ymin) decimal Lmin = 0.0M; decimal BMax = 0.0M;//ToWGS84(xmax,ymax) decimal Lmax = 0.0M; //double dL = Lmax - Lmin; //经差△L //double dB = BMax - Bmin; //纬差(B2-B1) //比例尺 5千 IMapScale scale = new MapScale_5000(); decimal dL = scale.L2_L1; //(单位:弧度) decimal dB = scale.B2_B1; //(单位:弧度) //default=西安椭球体参数 decimal b = this.EllipseParameter.b; decimal a = this.EllipseParameter.a; decimal A = this.EllipseParameter.A; decimal B = this.EllipseParameter.B; decimal C = this.EllipseParameter.C; decimal D = this.EllipseParameter.D; decimal E = this.EllipseParameter.E; decimal Bm = (Bmin + BMax) / 2; decimal CosBm = Maths.Cos(Bm); decimal Cos3Bm = Maths.Cos(3 * Bm); decimal Cos5Bm = Maths.Cos(5 * Bm); decimal Cos7Bm = Maths.Cos(7 * Bm); decimal Cos9Bm = Maths.Cos(9 * Bm); P = ((4 * PI * b * b * dL) / (360 * 60)) * (A * Maths.Sin(dB * 1 / 2) * CosBm - B * Maths.Sin(dB * 3 / 2) * Cos3Bm + C * Maths.Sin(dB * 5 / 2) * Cos5Bm - D * Maths.Sin(dB * 7 / 2) * Cos7Bm + E * Maths.Sin(dB * 9 / 2) * Cos9Bm); return(P); //(单位:平方米) }
/// <summary> /// 求(B1,L1)-(B2,L2)的任意梯形椭球面积 /// </summary> /// <param name="B1"></param> /// <param name="L1"></param> /// <param name="B2"></param> /// <param name="L2"></param> /// <returns></returns> public decimal Compute(decimal B1, decimal L1, decimal B2, decimal L2) { decimal P = 0; decimal Lany = 60.0M; decimal dL = (L2 + L1) / 2 - Lany; //经差△L decimal dB = B2 - B1; //纬差(B2-B1) dL = dL * PI / 180; //(单位:弧度) dB = dB * PI / 180; //(单位:弧度) //default=西安椭球体参数 decimal b = this.EllipseParameter.b; decimal a = this.EllipseParameter.a; decimal A = this.EllipseParameter.A; decimal B = this.EllipseParameter.B; decimal C = this.EllipseParameter.C; decimal D = this.EllipseParameter.D; decimal E = this.EllipseParameter.E; decimal Bm = (B1 + B2) / 2; Bm = Bm * PI / 180; //(单位:弧度) decimal CosBm = Maths.Cos(Bm); decimal Cos3Bm = Maths.Cos(3 * Bm); decimal Cos5Bm = Maths.Cos(5 * Bm); decimal Cos7Bm = Maths.Cos(7 * Bm); decimal Cos9Bm = Maths.Cos(9 * Bm); //求任意梯形椭球面积 P = (2 * b * b * dL) * (A * Maths.Sin(dB * 1 / 2) * CosBm - B * Maths.Sin(dB * 3 / 2) * Cos3Bm + C * Maths.Sin(dB * 5 / 2) * Cos5Bm - D * Maths.Sin(dB * 7 / 2) * Cos7Bm + E * Maths.Sin(dB * 9 / 2) * Cos9Bm); return(P); }
/// <summary> /// 大地坐标转换为高斯投影坐标 正解公式 /// WGC84->高斯投影 /// Description: ///' 大地坐标转换为高斯投影坐标 ///' Parameters: ///' LX,BX - 输入,经纬度坐标 ///' x,y - 输出,高斯投影坐标(大数) ///' nearright - 输入,L是相邻两带的分界线时的取法,0 - 左带(小),1 - 右带(大) ///' ProjectionType - 输入,1 - 80坐标系,0 - 54坐标系 ///' StripType - 输入,1 - 6度分带,0 - 3度分带 /// 当只有一个已知控制点时,根据平移参数调整东伪偏移、北纬偏移值实现WGS84到北京54的转换 /// 东伪偏移=东伪偏移值=tpMainStrip * 1000000+500000.0 /// 北纬偏移值=0; /// </summary> /// <param name="BX">大地纬度B</param> /// <param name="LX">大地经度L</param> /// <param name="x">高斯投影X</param> /// <param name="y">高斯投影Y</param> /// <param name="nearright">输入,L是相邻两带的分界线时的取法,0 - 左带(小),1 - 右带(大)</param> /// <param name="ProjectionType"> 输入,1 - 80坐标系,0 - 54坐标系</param> /// <param name="StripType"> 输入,1 - 6度分带,0 - 3度分带</param> /// <param name="IsBigNumber">输入, 是大数坐标吗?</param> public void GetXYFromBL(decimal BX, decimal LX, ref decimal x, ref decimal y, long nearright, EnumProjectionDatum ProjectionType, EnumStrip StripType, bool IsBigNumber) { decimal t = 0; decimal B = 0; decimal L = 0; decimal x0 = 0; decimal y2 = 0; decimal E12 = 0; decimal c0 = 0; decimal n1 = 0; decimal m = 0; decimal temp1 = 0, temp2 = 0; decimal LX1 = 0; decimal fc_pi = 3.14159265358979M; //PI值 B = (BX / 180) * fc_pi; //转为弧度值bx*(PI/180) L = (LX / 180) * fc_pi; //转为弧度值lx*(PI/180) //求带内中央子午线经度 LX1 = GetLocalLongitude(LX, nearright, StripType); m = Maths.Cos(B) * fc_pi * LX1 / 180.0M; t = Maths.Tan(B); switch (ProjectionType) { case EnumProjectionDatum.Xian80: //80坐标 c0 = 6399596.65198801M; E12 = 0.0067395018195M; x0 = 111133.0047M * BX - (32009.8575M * Maths.Sin(B) + 133.9978M * (Maths.Pow(Maths.Sin(B), 3)) + 0.6975M * (Maths.Pow(Maths.Sin(B), 5)) + 0.0039M * (Maths.Pow(Maths.Sin(B), 7))) * Maths.Cos(B); break; case EnumProjectionDatum.Bejing54: //54坐标 c0 = 6399698.90178271M; E12 = 0.00673852541468M; x0 = 111134.8611M * BX - (32005.7798M * Maths.Sin(B) + 133.9614M * (Maths.Pow(Maths.Sin(B), 3)) + 0.6972M * (Maths.Pow(Maths.Sin(B), 5)) + 0.0039M * (Maths.Pow(Maths.Sin(B), 7))) * Maths.Cos(B); break; default: //其它暂为空 break; } y2 = E12 * (Maths.Pow(Maths.Cos(B), 2)); n1 = c0 / Maths.Sqrt(1.0M + y2); temp1 = (Maths.Pow(m, 2)) / 2.0M + (5.0M - (Maths.Pow(t, 2)) + 9.0M * y2 + 4 * (Maths.Pow(y2, 2))) * (Maths.Pow(m, 4)) / 24.0M + (61.0M - 58.0M * (Maths.Pow(t, 2)) + (Maths.Pow(t, 4))) * (Maths.Pow(m, 6)) / 720.0M; temp2 = m + (1.0M - (Maths.Pow(t, 2)) + y2) * (Maths.Pow(m, 3)) / 6.0M + (5.0M - 18.0M * (Maths.Pow(t, 2)) + (Maths.Pow(t, 4)) + 14.0M * y2 - 58.0M * y2 * (Maths.Pow(t, 2))) * (Maths.Pow(m, 5)) / 120.0M; x = x0 + n1 * t * temp1; y = n1 * temp2 + 500000.0M; //与中央经线的距离m //500000.0表示平移了500公里距离 目的是把负数坐标转为正数好处理 //主带数值(整数) decimal tpMainStrip = 0; //主带数值 switch (StripType) { case EnumStrip.Strip3: tpMainStrip = (int)Math.Truncate(LX / 3) + 1; break; case EnumStrip.Strip6: tpMainStrip = (int)Math.Truncate(LX / 6) + 1; break; default: //则自动计算 ,默认为3度带 tpMainStrip = (int)Math.Truncate(LX / 3) + 1; break; } //转为大数坐标y=带数*1000000+与中央经线的距离m //东伪偏移值=tpMainStrip * 1000000+500000.0 if (IsBigNumber == true) //转为高斯投影是大数投影吗?即Zone 35带数 (小数投影为CM_105E) { y = y + tpMainStrip * 1000000; } }
/// <summary> /// 计算IGeometry的椭球面的 理论面积 /// </summary> /// <param name="geo">输入的分幅图的几何对象IGeometry(矩形状)</param> /// <returns>(单位:平方米)</returns> public override decimal Compute(IGeometry geo) { decimal P = 0.0M; decimal Lany = 60.0M; decimal ShapeArea = 0; //(1)最大最小角计算出WGS84大地经纬度坐标(四个点) 经差/纬差 decimal xmin = Maths.Todecimal(geo.Envelope.XMin); decimal ymin = Maths.Todecimal(geo.Envelope.YMin); decimal xmax = Maths.Todecimal(geo.Envelope.XMax); decimal ymax = Maths.Todecimal(geo.Envelope.YMax); ShapeArea = Maths.Todecimal((geo as IArea).Area); //double blxs = (geo as IArea).Area / (geo.Envelope as IArea).Area; //(2)转为经纬度坐标 //ToWGS84(xmax,ymax) decimal Bmin = 0, Lmin = 0, Bmax = 0, Lmax = 0; this.gassConv.GetBLFromXY(ymin, xmin, ref Bmin, ref Lmin, 0, this.Datum, this.Strip, this.L0, this.IsBigNumber); //ToWGS84(xmin,ymin) this.gassConv.GetBLFromXY(ymax, xmax, ref Bmax, ref Lmax, 0, this.Datum, this.Strip, this.L0, this.IsBigNumber); //ToWGS84(xmin,ymin) decimal dL = (Lmax + Lmin) / 2 - Lany; //经差△L decimal dB = Bmax - Bmin; //纬差(B2-B1) dL = dL * PI / 180; //(单位:弧度) dB = dB * PI / 180; //(单位:弧度) //default=西安椭球体参数 decimal b = this.EllipseParameter.b; decimal a = this.EllipseParameter.a; decimal A = this.EllipseParameter.A; decimal B = this.EllipseParameter.B; decimal C = this.EllipseParameter.C; decimal D = this.EllipseParameter.D; decimal E = this.EllipseParameter.E; decimal Bm = (Bmin + Bmax) / 2; Bm = Bm * PI / 180; //(单位:弧度) decimal CosBm = Maths.Cos(Bm); decimal Cos3Bm = Maths.Cos(3 * Bm); decimal Cos5Bm = Maths.Cos(5 * Bm); decimal Cos7Bm = Maths.Cos(7 * Bm); decimal Cos9Bm = Maths.Cos(9 * Bm); //求geo几何体的包络矩形的椭球面积 P = (2 * b * b * dL) * (A * Maths.Sin(dB * 1 / 2) * CosBm - B * Maths.Sin(dB * 3 / 2) * Cos3Bm + C * Maths.Sin(dB * 5 / 2) * Cos5Bm - D * Maths.Sin(dB * 7 / 2) * Cos7Bm + E * Maths.Sin(dB * 9 / 2) * Cos9Bm); //正算经纬度矩形的另外两个点的投影坐标值 decimal x2 = 0, y2 = 0, x4 = 0, y4 = 0; this.gassConv.GetXYFromBL(Bmin, Lmax, ref y2, ref x2, 0, this.Datum, EnumStrip.Strip3, this.IsBigNumber); this.gassConv.GetXYFromBL(Bmax, Lmin, ref y4, ref x4, 0, this.Datum, EnumStrip.Strip3, this.IsBigNumber); //求经纬度矩形的投影梯形面积(上底+下底)*高/2 decimal BLTrapeziaArea = ((x2 - xmin) + (xmax - x4)) * (ymax - ymin) / 2; decimal LLmj = P * ShapeArea / BLTrapeziaArea; return(LLmj); //(单位:平方米) }