public override SmoothTimeValue Create(SatelliteNumber key) { return(new SmoothTimeValue(this.MaxTimeSpan, MaxDifferValue, true, false) { Name = key.ToString() }); }
/// <summary> /// 获取卫星在指定时刻,相对于测站的信息 /// </summary> /// <param name="service"></param> /// <param name="prn"></param> /// <param name="time"></param> /// <returns></returns> public StationSatInfo GetInstantSatInfo(IEphemerisService service, SatelliteNumber prn, Time time) { Geo.Coordinates.XYZ satPos = service.Get(prn, time).XYZ; GeoCoord coord = CoordTransformer.XyzToGeoCoord(satPos); Geo.Coordinates.Polar p = CoordTransformer.XyzToGeoPolar(satPos, StationPos); if (p.Elevation < EleAngle) { return(null); } this.LonLats.Add(new Vector(coord.Lon, coord.Lat) { Tag = prn.ToString() }); //显示到表格 return(new StationSatInfo() { PRN = prn, Time = time, Azimuth = p.Azimuth, ElevatAngle = p.Elevation, Distance = p.Range, Lat = coord.Lat, Lon = coord.Lon, Height = coord.Height, X = satPos.X, Y = satPos.Y, Z = satPos.Z }); }
/// <summary> /// 保存结果到总表中 /// </summary> /// <param name="allInOneTable"></param> /// <param name="tableIonoParam"></param> /// <param name="prn"></param> /// <param name="typeName"></param> private static void CheckAndAddIonoValueToMainTable(ObjectTableStorage allInOneTable, ObjectTableStorage tableIonoParam, SatelliteNumber prn, string typeName) { if (tableIonoParam != null) { if (tableIonoParam.CurrentRow.ContainsKey(prn.ToString())) { allInOneTable.AddItem(prn + "_" + typeName, tableIonoParam.CurrentRow[prn.ToString()]); } } }
/// <summary> /// 返回一个距离历元最近的结果。 /// </summary> /// <param name="prn"></param> /// <param name="epoch">需要精确的时刻</param> /// <returns></returns> public double Get(SatelliteNumber prn, Time epoch) { if (Data != null) { if (Data.ContainsKeyBA(prn.ToString(), epoch)) { return(Data[epoch, prn.ToString()]); } if (!Data.ContainsKeyB(prn.ToString())) { return(0); } if (!TimePeriod.Contains(epoch)) { return(0); } var vals = Data.GetValuesByKeyB(prn.ToString()); //获取最近几个 var dic = Geo.Utils.DoubleUtil.GetNearst(vals, m => m.SecondsOfWeek, epoch, FitCount); if (IsAverageOrFit) { var ave = dic.Values.Average(); return(ave); } else { LsPolyFit fit = new LsPolyFit(2); fit.InitAndFitParams <Time>(dic, m => m.SecondsOfWeek); var y = fit.GetY(epoch.SecondsOfWeek); return(y); } } return(0); }
/// <summary> /// Method tat implements the mw cycle slip detection algorithm /// </summary> /// <param name="epoch">Time of observations</param> /// <param name="prn">SatId</param> /// <param name="mwValue">Current mw observation value</param> /// <returns></returns> public bool GetDetection(Time epoch, SatelliteNumber prn, double mwValue) { bool isFirst = false; if (!this.Contains(prn)) { this[prn] = new SmoothTimeValue(this.MaxTimeSpan, MaxDifferValue, true, false) { Name = prn.ToString() }; isFirst = true; log.Debug(epoch + ", " + prn + " 卫星第一次出现,标记为有周跳。"); return(true);//第一次出现,默认有之。 } SmoothTimeValue current = this[prn]; var isExceed = !current.Regist(epoch, mwValue); var result = isExceed || isFirst; return(result); }
/// <summary> /// 根据太阳计算卫星偏差 /// </summary> /// <param name="prn"></param> /// <param name="eph"></param> /// <param name="emissionTime"></param> /// <returns></returns> private XYZ GetSatAntOff(SatelliteNumber prn, IEphemeris eph, Time emissionTime) { ErpItem erpv = null; if (DataSouceProvider.ErpDataService != null) { erpv = DataSouceProvider.ErpDataService.Get(emissionTime); } if (erpv == null) { erpv = ErpItem.Zero; } XYZ rsun = new XYZ(); //sun position in ecef // rsun = EpochSat.EpochInfo.DataSouceProvider.UniverseObjectProvider.GetSunPosition(emissionTime); this.DataSouceProvider.UniverseObjectProvider.GetSunPosition(emissionTime, erpv, ref rsun); //unit vetcors of satellite fixed coordinates XYZ ez = -1 * eph.XYZ.UnitVector(); XYZ es = (rsun - eph.XYZ).UnitVector(); //outer product of 3D vectors XYZ r = new XYZ(); r.X = ez.Y * es.Z - ez.Z * es.Y; r.Y = ez.Z * es.X - ez.X * es.Z; r.Z = ez.X * es.Y - ez.Y * es.X; XYZ r0 = new XYZ(); r0.X = r.Y * ez.Z - r.Z * ez.Y; r0.Y = r.Z * ez.X - r.X * ez.Z; r0.Z = r.X * ez.Y - r.Y * ez.X; XYZ ex = r0.UnitVector(); XYZ ey = r.UnitVector(); //XYZ ex = new XYZ(); //ex.X = ey.Y * ez.Z - ey.Z * ez.Y; //ex.Y = ey.Z * ez.X - ey.X * ez.Z; //ex.Z = ey.X * ez.Y - ey.Y * ez.X; //use L1 value if (DataSouceProvider.AntennaDataSource == null) { return(new XYZ()); } IAntenna antenna = DataSouceProvider.AntennaDataSource.Get(prn.ToString(), emissionTime); //如果为空,则返回 0 坐标 if (antenna == null) { return(new XYZ()); } // Get antenna eccentricity for frequency "G01" (L1), in // satellite reference system. // NOTE: It is NOT in ECEF, it is in UEN!!! RinexSatFrequency freq = new RinexSatFrequency(prn, 1); // NEU satAnt = antenna.GetAntennaEccentricity(AntennaFrequency.G01); NEU satAnt = antenna.GetPcoValue(freq); XYZ dant = new XYZ(); dant.X = satAnt.E * ex.X + satAnt.N * ey.X + satAnt.U * ez.X; dant.Y = satAnt.E * ex.Y + satAnt.N * ey.Y + satAnt.U * ez.Y; dant.Z = satAnt.E * ex.Z + satAnt.N * ey.Z + satAnt.U * ez.Z; // Unitary vector from satellite to Earth mass center (ECEF) XYZ satToEarthUnit = (-1.0) * eph.XYZ.UnitVector(); // Unitary vector from Earth mass center to Sun (ECEF) XYZ earthToSunUnit = rsun.UnitVector(); // rj = rk x ri: Rotation axis of solar panels (ECEF) XYZ rj = satToEarthUnit.Cross(earthToSunUnit); // Redefine ri: ri = rj x rk (ECEF) earthToSunUnit = rj.Cross(satToEarthUnit); // Let's funcKeyToDouble ri to an unitary vector. (ECEF) earthToSunUnit = earthToSunUnit.UnitVector(); XYZ dant1 = new XYZ(); dant1.X = satAnt.E * rj.X + satAnt.N * earthToSunUnit.X + satAnt.U * satToEarthUnit.X; dant1.Y = satAnt.E * rj.Y + satAnt.N * earthToSunUnit.Y + satAnt.U * satToEarthUnit.Y; dant1.Z = satAnt.E * rj.Z + satAnt.N * earthToSunUnit.Z + satAnt.U * satToEarthUnit.Z; return(dant1); }