/// <summary> 获取湿分量的系数 ///对流层延迟,第一个是干分量的延迟量,第二个值是湿分量的映射函数系数 /// 高精度的对流层改正 /// 对流层延迟由干、湿分量组成,常用天顶方向的干、湿分量和相应的映射函数表示:detDtrop=detDdry*Mdry(E)+detDwet*Mwet(E) /// 采用Saastamoinen模型改正对流层延迟干分量,将湿延迟分量作为未知参数进行估计,计算湿分量的系数 /// 对流层映射函数采用NMF映射函数 /// lat:测站纬度(弧度),h:测站高程(km),P:测站大气压强(mbar),TProduct:测站温度(k),e:大气中的水汽压(mbar) /// </summary> /// <returns></returns> public static double[] GetDryTropCorrectValue(Time gpsTime, XYZ satPos, XYZ receiverXyz) { Polar p = CoordTransformer.XyzToGeoPolar(satPos, receiverXyz); Geo.Coordinates.GeoCoord geoCoord = Geo.Coordinates.CoordTransformer.XyzToGeoCoord(receiverXyz, Geo.Coordinates.AngleUnit.Radian); //double troCorect = MeteorologyInfluence.TroposphereDelay(geoCoord.Lat, geoCoord.Height, info.ElevatAngle, gpsTime) //double SS = Math.Asin(1); //double SSS = Math.Asin(0); double[] NMF = NeillMF(gpsTime.DayOfYear, geoCoord.Lat, geoCoord.Height, p.Elevation); double zpd = tropol(90, geoCoord.Height / 1000d); double zpd1 = tropol(geoCoord.Lat, geoCoord.Height / 1000d); double zpd11 = tropol1(geoCoord.Lat, geoCoord.Height / 1000.0); double dryZpd = MetSeason(geoCoord.Height, geoCoord.Lat, gpsTime); double TropE = dryZpd * NMF[0];//干分量改正 double[] DryWet = new double[2]; DryWet[0] = TropE; double wetCo = NMF[2];//湿分量系数 DryWet[1] = wetCo; //return wetCo; return(DryWet); }
/// <summary> /// 对流程改正。 对流程的改正符号为负数。 /// </summary> /// <param name="gpsTime"></param> /// <param name="satPos"></param> /// <param name="receiverXyz"></param> /// <returns></returns> public static double GetTropoCorrectValue(Time gpsTime, XYZ satPos, XYZ receiverXyz) { Polar p = CoordTransformer.XyzToGeoPolar(satPos, receiverXyz, Geo.Coordinates.AngleUnit.Radian); Geo.Coordinates.GeoCoord geoCoord = Geo.Coordinates.CoordTransformer.XyzToGeoCoord(receiverXyz, Geo.Coordinates.AngleUnit.Radian); double troCorect = MeteorologyInfluence.TroposphereDelay(geoCoord.Lat, geoCoord.Height, p.Elevation, gpsTime); return(troCorect); }
/// <summary> /// 站心极坐标转换为地心大地坐标 /// </summary> /// <param name="localPolar">目标在地心极坐标的位置</param> /// <param name="sitePosInGeoCenter">测站大地坐标</param> /// <param name="el">参考椭球</param> /// <param name="unit">角度单位</param> /// <returns></returns> public static GeoCoord LocalPolarToGeoCoord(Polar localPolar, GeoCoord sitePosInGeoCenter, Geo.Referencing.Ellipsoid el = null, AngleUnit unit = AngleUnit.Degree) { if (el == null) { el = Geo.Referencing.Ellipsoid.WGS84; } NEU neu = PolarToNeu(localPolar); XYZ xyz = NeuToXyz(neu, sitePosInGeoCenter); return(XyzToGeoCoord(xyz, unit)); }
/// <summary> /// 计算 测站-卫星 方向的距离。 /// </summary> /// <param name="neuCorrection">测站改正 NEU</param> /// <param name="receiverXyz">测站坐标</param> /// <param name="satXyz">卫星坐标</param> /// <returns></returns> public static double GetDirectionLength(NEU neuCorrection, XYZ receiverXyz, XYZ satXyz) { XYZ ray = (satXyz - receiverXyz); GeoCoord geoCoord = CoordTransformer.XyzToGeoCoord(receiverXyz); //此处修改为 NEU 坐标系。Rotate vector ray to UEN reference frame NEU rayNeu = CoordTransformer.XyzToNeu(ray, geoCoord, AngleUnit.Degree); NEU directionUnit = rayNeu.UnitNeuVector();//方向向量 //计算沿着射线方向的改正数。Compute corrections = displacement vectors components along ray direction. double rangeCorretion = neuCorrection.Dot(directionUnit); return(rangeCorretion); }
/// <summary> /// XYZ转换为ENU的左乘矩阵。 /// </summary> /// <param name="geo"></param> /// <returns></returns> public static Matrix BuilTransferMatrixFromXyzToEnu(GeoCoord geo) { Geo.Algorithm.Matrix M = new Geo.Algorithm.Matrix(3); M[0, 0] = -Math.Sin(geo.Lon); M[0, 1] = Math.Cos(geo.Lon); M[0, 2] = 0; M[1, 0] = -Math.Sin(geo.Lat) * Math.Cos(geo.Lon); M[1, 1] = -Math.Sin(geo.Lat) * Math.Sin(geo.Lon); M[1, 2] = Math.Cos(geo.Lat); M[2, 0] = Math.Cos(geo.Lat) * Math.Cos(geo.Lon); M[2, 1] = Math.Cos(geo.Lat) * Math.Sin(geo.Lon); M[2, 2] = Math.Sin(geo.Lat); return(M); }
/// <summary> /// 由大地坐标计算大地线长,将采用其平均大地高计算大地线长。 /// </summary> /// <param name="longlatADeg"></param> /// <param name="longlatBDeg"></param> /// <param name="majorRadius"></param> /// <param name="inverseFlat"></param> /// <returns></returns> public static double BesselGeodeticLine(GeoCoord longlatADeg, GeoCoord longlatBDeg, double majorRadius = Ellipsoid.SemiMajorAxisOfCGCS2000, double inverseFlat = Ellipsoid.InverseFlatOfCGCS2000) { double aveGeoHeight = (longlatBDeg.Height + longlatADeg.Height) / 2.0; return(BesselGeodeticLine(longlatADeg.Lon, longlatADeg.Lat, longlatBDeg.Lon, longlatBDeg.Lat, majorRadius + aveGeoHeight, inverseFlat)); }
/// <summary> /// 站心坐标系到地心坐标系 /// </summary> /// <param name="sat"> 站心坐标系,如卫星,天线</param> /// <param name="siteCoord">坐标原点在地心坐标系中的坐标</param> /// <returns></returns> public static XYZ NeuToXyz(NEU sat, GeoCoord siteCoord) { XYZ siteXyz = CoordTransformer.GeoCoordToXyz(siteCoord); return(EnuToXyz(sat.ENU, siteXyz)); }
/// <summary> /// 站心坐标系到地心坐标系。 /// </summary> /// <param name="neu">本地坐标系</param> /// <param name="siteCoord">本地坐标原点在地心坐标系中的坐标</param> /// <returns></returns> public static XYZ NeuToXyz(NEU neu, XYZ siteCoord) { GeoCoord coord = XyzToGeoCoord(siteCoord); return(NeuToXyz(neu, coord)); }
/// <summary> /// 计算卫星的站心极坐标,全程 度 为单位,此比XYZ更精确,推荐。!!2017.10.12 /// </summary> /// <param name="satXyz">卫星的地心空间直角坐标</param> /// <param name="stationGeoCoord">测站的地心大地坐标或球坐标,不同坐标对应不同的高度角</param> /// <returns></returns> public static Polar XyzToPolar(XYZ satXyz, GeoCoord stationGeoCoord) { var staXyz = CoordTransformer.GeoCoordToXyz(stationGeoCoord); return(XyzToPolar(satXyz, staXyz, stationGeoCoord.Lon, stationGeoCoord.Lat, AngleUnit.Degree)); }
/// <summary> /// 构建。 /// </summary> /// <param name="DopCaculator"></param> /// <param name="table"></param> /// <param name="Time"></param> /// <param name="geoCoord"></param> private void Build(DopCaculator DopCaculator, Geo.ObjectTableStorage table, Time Time, Geo.Coordinates.GeoCoord geoCoord, bool isSimpleModel) { //var xyz = Geo.Coordinates.CoordTransformer.GeoCoordToXyz(geoCoord); //if (geoCoord.Lon == 0) //{ // var geoCoord2 = Geo.Coordinates.CoordTransformer.XyzToGeoCoord(xyz); // int i = 0; //} var dop = DopCaculator.Calculate(geoCoord, Time); if (dop != null) { table.NewRow(); //table.AddItem("Epoch", Time); //table.AddItem("X", xyz.X); //table.AddItem("Y", xyz.Y); //table.AddItem("Z", xyz.Z); if (!isSimpleModel) { table.AddItem("Lon", geoCoord.Lon); table.AddItem("Lat", geoCoord.Lat); } //table.AddItem("Heigh", geoCoord.Height); table.AddItem("SatCount", dop.SatCount); if (Geo.Utils.DoubleUtil.IsValid(dop.GDop)) { table.AddItem("GDOP", GetValNotExceed(dop.GDop)); table.AddItem("PDOP", GetValNotExceed(dop.PDop)); table.AddItem("HDOP", GetValNotExceed(dop.HDop)); table.AddItem("VDOP", GetValNotExceed(dop.VDop)); table.AddItem("TDOP", GetValNotExceed(dop.TDop)); } table.EndRow(); } else if (isSimpleModel) //如果没有经纬度,则采用N替代,否书数据空缺很危险 { table.NewRow(); //table.AddItem("Epoch", Time); //table.AddItem("X", xyz.X); //table.AddItem("Y", xyz.Y); //table.AddItem("Z", xyz.Z); //table.AddItem("Lon", geoCoord.Lon); //table.AddItem("Lat", geoCoord.Lat); //table.AddItem("Heigh", geoCoord.Height); table.AddItem("SatCount", "N"); table.AddItem("GDOP", "N"); table.AddItem("PDOP", "N"); table.AddItem("HDOP", "N"); table.AddItem("VDOP", "N"); table.AddItem("TDOP", "N"); table.EndRow(); } }