/// <summary> /// 构造函数 /// </summary> /// <param name="filePath"></param> public Sp3Reader(string filePath, bool IsAvailableOnly = true) : base(filePath) { Header = Sp3Header.Read(InputPath); FilterdPrn = SatelliteNumber.Default; this.IsAvailableOnly = IsAvailableOnly; }
/// <summary> /// 构造函数。 /// </summary> /// <param name="filePath">文件路径</param> /// <param name="Sp3Header">头部信息</param> public Sp3Writer(string filePath, Sp3Header Sp3Header = null) { this.FilePath = filePath; this.Sp3Header = Sp3Header; if (Sp3Header == null) { this.Sp3Header = new Sp3Header { //StartTime = DateTime.Now, //VersionId = 3.02.ToString(), AgencyName = "Gnsser Group" }; } this.StringBuilder = new StringBuilder(); HeaderText = BuildHeaderString(this.Sp3Header); }
/// <summary> /// 读取 SP3 /// </summary> /// <param name="header"></param> /// <param name="r"></param> /// <param name="firstLine"></param> /// <param name="satNum">是否读取指定卫星的值</param> /// <param name="availableOnly">是否只返回可用的记录</param> /// <returns></returns> public static Sp3Section ReadSection(Sp3Header header, StreamReader r, string firstLine, SatelliteNumber satNum, bool availableOnly = true) { Sp3Section sec = new Sp3Section(); sec.Time = ParseTime(firstLine); //if (header.OrbitType == SatelliteType.C)//如果是历元,需要转换为北斗时间来计算。 { // time = time + 14; } int satLineCount = 1; for (int i = 0; i < header.NumberOfSatellites * satLineCount; i++) { firstLine = r.ReadLine(); if (firstLine == "EOF") { break; } var firstChar = firstLine.Substring(0, 1); var firstTwoChar = firstLine.Substring(0, 2); //判断是否内容 if (firstTwoChar == RecordHeadSymbol) { return(ReadSection(header, r, firstLine, satNum, availableOnly)); } //解析卫星编号 var prn = SatelliteNumber.Parse(firstLine.Substring(1, 3)); if (satNum != SatelliteNumber.Default && !satNum.Equals(prn)) { continue; } //过滤指定卫星否 if (!sec.Contains(prn)) { sec[prn] = new Ephemeris(prn, sec.Time) { Source = header.SourceName }; } var rec = sec[prn]; if (firstChar == PositionClockSymbol || firstTwoChar == EphemerisPosition) { double clock; var xyz = ParseLine(firstLine, out clock); //单位转换为米 rec.XYZ = xyz * 1000.0; if (clock == 999999.999999) //continue; { clock = MaxClockError; if (availableOnly) { sec.Remove(prn); continue; } } //????????????是否该标记卫星状态糟糕 //崔阳,修改,应直接去除该卫星,不能使用。 rec.ClockBias = clock * 1e-6; if (firstLine.Length > 70) { ParsePosStd(firstLine, rec); } } else if (firstChar == VelocityClockSymbol || firstTwoChar == EphemerisVelocity) { satLineCount = 2; double dclock; var xyz = ParseLine(firstLine, out dclock); rec.XyzDot = xyz * 0.1; rec.ClockDrift = dclock * 1e-10; } } return(sec); }
/// <summary> /// 读取 SP3 /// </summary> /// <param name="header"></param> /// <param name="r"></param> /// <param name="satNum">是否读取指定卫星的值</param> /// <param name="availableOnly">是否只返回可用的记录</param> /// <returns></returns> public static Sp3Section ReadSection(Sp3Header header, StreamReader r, string firstLine, SatelliteNumber satNum, bool availableOnly = true) { return(Sp3Reader.ReadSection(header, r, firstLine, satNum, availableOnly)); Sp3Section s = new Sp3Section(); //try { //读取第一行,头部。 // if (line.Substring(0, 2) != RecordHeadSymbol) throw new Exception("SP3文件不合法"); var time = ParseTime(firstLine); s.Time = time; //if (header.OrbitType == SatelliteType.C)//如果是历元,需要转换为北斗时间来计算。 { // time = time + 14; } for (int i = 0; i < header.NumberOfSatellites; i++) { firstLine = r.ReadLine(); if (firstLine == "EOF") { break; } var firstChar = firstLine.Substring(0, 1); var firstTwoChar = firstLine.Substring(0, 2); if (firstChar != PositionClockSymbol) { if (firstTwoChar == RecordHeadSymbol) { return(ReadSection(header, r, firstLine, satNum)); } throw new Exception("SP3文件不合法,行首字母为 " + firstChar + ", 非 " + PositionClockSymbol); } if (firstLine == "PC01 -0.000476 -0.005825 0.005830 -22.363000") { } if (firstLine == "PC01 -0.000475 -0.005827 0.005829 -22.366667") { } if (firstLine == "PC01 -0.000467 -0.005845 0.005817 -22.317333") { } SatelliteNumber prn = SatelliteNumber.Parse(firstLine.Substring(1, 3)); //过滤指定卫星否 if (satNum != SatelliteNumber.Default && !satNum.Equals(prn)) { continue; } Ephemeris rec = new Ephemeris(); rec.Time = s.Time; rec.Prn = prn; double x = double.Parse(firstLine.Substring(4, 14)) * 1000.0; double y = double.Parse(firstLine.Substring(18, 14)) * 1000.0; double z = double.Parse(firstLine.Substring(32, 14)) * 1000.0; rec.XYZ = new XYZ(x, y, z); double clock = double.Parse(firstLine.Substring(46, 14)); rec.ClockBias = clock * 1e-6; if (firstLine.Length > 70) { //读取精度估值stdv //Columns 62-63 x-sdev (b**n mm) 18 I2 //Column 64 Unused _ blank //Columns 65-66 y-sdev (b**n mm) 18 I2 //Column 67 Unused _ blank //Columns 68-69 z-sdev (b**n mm) 18 I2 //Column 70 Unused _ blank //Columns 71-73 c-sdev (b**n psec) 219 I3 double sdevX = 0.0, sdevY = 0.0, sdevZ = 0.0; string tmp = firstLine.Substring(61, 2); if (tmp != " ") { sdevX = double.Parse(tmp) * 0.001; } //保留为米 tmp = firstLine.Substring(64, 2); if (tmp != " ") { sdevY = double.Parse(tmp) * 0.001; } tmp = firstLine.Substring(67, 2); if (tmp != " ") { sdevZ = double.Parse(tmp) * 0.001; } rec.Rms = new XYZ(sdevX, sdevY, sdevZ); double sdevClock = 0.0; tmp = firstLine.Substring(70, 3); //保留了皮秒单位,因为10-12次方太小 if (tmp != " ") { sdevClock = double.Parse(tmp); } rec.ClockBiasRms = sdevClock; } else { rec.Rms = new XYZ(0.0, 0.0, 0.0); rec.ClockBiasRms = 0.0; } //读取速度 if (header.P_V_ModeFlag == VelocityClockSymbol) { firstLine = r.ReadLine(); firstChar = firstLine.Substring(0, 2); if (firstChar != EphemerisPosition) { throw new Exception("SP3文件不合法,‘#cV’格式星历第2行前两字符为 " + firstChar + ", 非 " + EphemerisPosition); } //double xsdev = double.Parse(firstLine.Substring(4, 4)) * 0.0001; //double ysdev = double.Parse(firstLine.Substring(9, 4)) * 0.0001; //double zsdev = double.Parse(firstLine.Substring(14, 4)) * 0.0001; //rec.XyzSdev = new XYZ(xsdev, ysdev, zsdev); //rec.ClockSdev = double.Parse(firstLine.Substring(19, 7)) * 1E-12; firstLine = r.ReadLine(); firstChar = firstLine.Substring(0, 1); if (firstChar != VelocityClockSymbol) { throw new Exception("SP3文件不合法,行首字母为 " + firstChar + ", 非 " + VelocityClockSymbol); } rec.Prn = SatelliteNumber.Parse(firstLine.Substring(1, 3)); //分米每秒 double xdot = double.Parse(firstLine.Substring(4, 14)) * 1e-1; double ydot = double.Parse(firstLine.Substring(18, 14)) * 1e-1; double zdot = double.Parse(firstLine.Substring(32, 14)) * 1e-1; rec.XyzDot = new XYZ(xdot, ydot, zdot); //(10e-4 msec/sec) = 10e-4 * 1e-6 ?? rec.ClockDrift = double.Parse(firstLine.Substring(46, 14)) * 1e-10; firstLine = r.ReadLine(); firstChar = firstLine.Substring(0, 2); if (firstChar != EphemerisVelocity) { throw new Exception("SP3文件不合法,‘#cV’格式星历第4行前两字符为 " + firstChar + ", 非 " + EphemerisVelocity); } //double xVsdev = double.Parse(firstLine.Substring(4, 4)) * 0.0001; //double yVsdev = double.Parse(firstLine.Substring(9, 4)) * 0.0001; //double zVsdev = double.Parse(firstLine.Substring(14, 4)) * 0.0001; //rec.XyzDotSdev = new XYZ(xVsdev, yVsdev, zVsdev); } s.Add(rec.Prn, rec); } } //catch (Exception ex) //{ // throw new ArgumentException("解析行“" + line + "”时出错!\r\north" + ex.Message); //} return(s); }
/// <summary> /// 构造函数 /// </summary> /// <param name="filePath"></param> public Sp3AllReader(string filePath) : base(filePath) { Header = Sp3Header.Read(InputPath); FilterdPrn = SatelliteNumber.Default; }
/// <summary> /// 读取头部信息 /// </summary> /// <param name="path"></param> /// <returns></returns> public static Sp3Header Read(string path) { Sp3Header header = new Sp3Header(); header.SourceName = Path.GetFileName(path); using (TextReader r = new StreamReader(path)) { string line = null; string symbol = null; line = r.ReadLine(); symbol = line.Substring(0, 1); if (symbol != LineSymbols[0]) { throw new Exception("SP3文件不合法"); } header.VersionId = line.Substring(1, 1); header.P_V_ModeFlag = line.Substring(2, 1); header.StartTime = Time.Parse(line.Substring(3, 28)); header.NumberOfEpochs = int.Parse(line.Substring(32, 7)); header.DataUsed = line.Substring(40, 5); header.CoordinateSystem = line.Substring(46, 5); header.OrbitType = line.Substring(52, 3); header.AgencyName = line.Substring(56, 4); int lineIndex = 0; int sartLineIndexOfSat = 0; int sartLineIndexOfSatAccuracy = 0; do { line = r.ReadLine(); lineIndex++; switch (FirstTwoCharToMarker(line)) { case Sp3HeaderLineMarker.Time: header.GPSWeek = int.Parse(line.Substring(3, 4)); header.SecondsOfWeek = double.Parse(line.Substring(9, 15)); header.EpochInterval = double.Parse(line.Substring(24, 14)); header.ModJulianDayStart = int.Parse(line.Substring(39, 5)); header.FractionalDay = double.Parse(line.Substring(45, 15)); break; case Sp3HeaderLineMarker.SatelliteCount: sartLineIndexOfSat = lineIndex; header.NumberOfSatellites = int.Parse(line.Substring(3, 3)); int len = header.NumberOfSatellites >= 17 ? 17 : header.NumberOfSatellites; header.PRNs = SatelliteNumber.ParsePRNs(line.Substring(9, len * 3)); break; //都用于存储卫星号。 case Sp3HeaderLineMarker.SatelliteNumber: int prevSatCount = 17 * (lineIndex - sartLineIndexOfSat); int satLen = header.NumberOfSatellites >= prevSatCount + 17 ? 17 : header.NumberOfSatellites - prevSatCount; if (satLen > 0) { header.PRNs.AddRange(SatelliteNumber.ParsePRNs(line.Substring(9, satLen * 3))); } break; //用于表示卫星的精度,1表示极佳, 99表示不要用,0表示未知。 case Sp3HeaderLineMarker.Accuracy: if (sartLineIndexOfSatAccuracy == 0) { sartLineIndexOfSatAccuracy = lineIndex; } if (header.SatAccuraces == null) { header.SatAccuraces = new Dictionary <SatelliteNumber, int>(); } int prevSatAccuCount = 17 * (lineIndex - sartLineIndexOfSatAccuracy); int satAccLen = header.NumberOfSatellites >= prevSatAccuCount + 17 ? 17 : header.NumberOfSatellites - prevSatAccuCount; if (satAccLen > 0) { List <string> sts = Utils.StringUtil.Split(line.Substring(9, satAccLen * 3), 3); for (int i = prevSatAccuCount, j = 0; j < satAccLen; i++, j++) { header.SatAccuraces.Add(header.PRNs[i], int.Parse(sts[j])); } } break; case Sp3HeaderLineMarker.Char: if (header.Characters == null) { header.Characters = new List <string>(); } header.Characters.AddRange(new List <String>(line.Substring(3, 57).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))); break; case Sp3HeaderLineMarker.Float: if (header.Floats == null) { header.Floats = new List <double>(); } List <String> list = new List <String>(line.Substring(3, 57).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); foreach (string Str in list) { header.Floats.Add(double.Parse(Str)); } break; case Sp3HeaderLineMarker.Int: if (header.Ints == null) { header.Ints = new List <int>(); } List <String> listINts = new List <String>(line.Substring(3, 57).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); foreach (string Str in listINts) { header.Ints.Add(int.Parse(Str)); } break; case Sp3HeaderLineMarker.Comment: if (header.Comments == null) { header.Comments = new List <string>(); } if (line.Length > 3) { header.Comments.Add(line.Substring(3)); } break; case Sp3HeaderLineMarker.End: header.LineNumber = lineIndex; return(header); // break; default: throw new ApplicationException("天啊!你是不可能看到我的!除非出错了,难道是版本变了?"); } } while (String.Compare(line.Substring(0, 2), "* ", true) != 0); header.LineNumber = lineIndex + 1; } return(header); }
/// <summary> /// 构建头部字符串。 /// </summary> /// <param name="header"></param> /// <param name="P_V_ModeFlag"></param> /// <returns></returns> public static string BuildHeaderString(Sp3Header header, string P_V_ModeFlag = "P") { StringBuilder sb = new StringBuilder(); //prevObj line if (P_V_ModeFlag == "P") { sb.Append(StringUtil.FillSpace("#cP", 3)); } else { sb.Append(StringUtil.FillSpace("#cV", 3)); } sb.Append(header.StartTime.Year //四位数的年 + " " + header.StartTime.Month.ToString("00") + " " + header.StartTime.Day.ToString("00") + " " + header.StartTime.Hour.ToString("00") + " " + header.StartTime.Minute.ToString("00") + " " + header.StartTime.Second.ToString("00.00000000")); //sb.Append(StringUtil.FillSpace(DateTime.UtcNow.ToString("yyyyMMdd HHmmss") + " UTC", 20)); //header.StartTime = Time.Parse(line.Substring(3, 28)); //header.NumberOfEpochs = int.Parse(line.Substring(32, 7)); //header.DataUsed = line.Substring(40, 5); //header.CoordinateSystem = line.Substring(46, 5); //header.OrbitType = line.Substring(52, 3); //header.AgencyName = line.Substring(56, 4); sb.Append(StringUtil.FillSpaceLeft(header.NumberOfEpochs.ToString(), 8)); sb.Append(" "); sb.Append(StringUtil.FillSpaceLeft(header.DataUsed, 5)); sb.Append(" "); sb.Append(StringUtil.FillSpaceLeft(header.CoordinateSystem, 5)); sb.Append(" "); sb.Append(StringUtil.FillSpaceLeft(header.OrbitType, 3)); sb.Append(" "); sb.Append(StringUtil.FillSpaceLeft(header.AgencyName, 4)); sb.AppendLine(); //second line sb.Append(StringUtil.FillSpace("##", 2) + " "); sb.Append(StringUtil.FillSpace(header.GPSWeek.ToString(), 4) + " "); sb.Append(StringUtil.FillSpace(header.SecondsOfWeek.ToString(".00000000"), 15)); sb.Append(StringUtil.FillSpace(header.EpochInterval.ToString(".00000000"), 15)); sb.Append(StringUtil.FillSpace(header.ModJulianDayStart.ToString(), 5) + " "); sb.Append(StringUtil.FillSpace(header.FractionalDay.ToString("0.0000000000000"), 15)); sb.AppendLine(); //存储卫星号 sb.Append(StringUtil.FillSpace("+", 4)); sb.Append(StringUtil.FillSpace(header.NumberOfSatellites.ToString(), 5)); var prns = header.PRNs; int satIndex = 0; int line = 0; if (prns != null) { foreach (var item in prns) { sb.Append(item.ToString()); satIndex++; if (satIndex % 17 == 0) { sb.AppendLine(); line++; if (line < 10) { sb.Append(StringUtil.FillSpace("+", 9)); } } } } for (int i = 0; i < 170 - header.NumberOfSatellites; i++) { sb.Append(StringUtil.FillSpace(" 0", 3)); satIndex++; if (satIndex % 17 == 0) { sb.AppendLine(); line++; if (line < 10) { sb.Append(StringUtil.FillSpace("+", 9)); } } } int satIndex1 = 0; for (int i = 0; i < 10; i++) { sb.Append(StringUtil.FillSpace("++", 9)); for (int j = 0; j < 17; j++) { if (satIndex1 < header.NumberOfSatellites) { sb.Append(StringUtil.FillSpace(" 2", 3)); } else { sb.Append(StringUtil.FillSpace(" 0", 3)); } satIndex1++; } sb.AppendLine(); } sb.Append(StringUtil.FillSpace("%c", 2)); sb.Append(" cc GPS ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc"); sb.AppendLine(); sb.Append(StringUtil.FillSpace("%c", 2)); sb.Append(" cc cc ccc ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc"); sb.AppendLine(); sb.Append(StringUtil.FillSpace("%f", 2)); sb.Append(" 0.0000000 0.000000000 0.00000000000 0.000000000000000"); sb.AppendLine(); sb.Append(StringUtil.FillSpace("%f", 2)); sb.Append(" 0.0000000 0.000000000 0.00000000000 0.000000000000000"); sb.AppendLine(); sb.Append(StringUtil.FillSpace("%i", 2)); sb.Append(" 0 0 0 0 0 0 0 0 0"); sb.AppendLine(); sb.Append(StringUtil.FillSpace("%i", 2)); sb.Append(" 0 0 0 0 0 0 0 0 0"); sb.AppendLine(); sb.Append(StringUtil.FillSpace("/*", 3)); sb.AppendLine("Gnsser Group"); sb.Append(StringUtil.FillSpace("/*", 3)); sb.AppendLine(); if (header.Comments != null) { foreach (var item in header.Comments) { if (item == "Gnsser Group") { continue; } sb.Append(StringUtil.FillSpace("/*", 3)); sb.AppendLine(StringUtil.FillSpaceRight(item, 60)); } } return(sb.ToString()); }
/// <summary> /// 默认构造函数 /// </summary> public Sp3File(Sp3Header header = null) { this.Header = header ?? new Sp3Header(); IsBuildCollection = false; }