/// <summary> /// 读取历元对象 /// </summary> /// <param name="Header"></param> /// <param name="StreamReader"></param> /// <returns></returns> private IonoSection ReadSection(IonoFile ionoFile, IonoHeader Header, StreamReader StreamReader) { string line = StreamReader.ReadLine(); var isValueOrRms = (IsStartLineOfEpochMapSection(line)); if (isValueOrRms) { IsCurrentValueOrRms = true; return(ReadSection(ionoFile, Header, StreamReader)); } isValueOrRms = !(IsStartLineOfRmsEpochMapSection(line)); while (!IsFirstLineOfEpochMapSectionWithTime(line)) { line = StreamReader.ReadLine(); if (line == null) { return(null); } if (line.Length > 60 && line.Substring(60).Trim() == RinexHeaderLabel.END_OF_FILE) { return(null); } } IonoSection IonoSection = null; var time = this.ParseTime(line); if (ionoFile.Contains(time)) { IonoSection = ionoFile[time]; } else { IonoSection = new IonoSection() { Header = Header, Time = time }; } while ((line = StreamReader.ReadLine()) != null && IsStartOfRecord(line) && !IsEndLineOfEpochMapSection(line)) { var lat = double.Parse(line.Substring(2, 6)); IonoRecord record = null; if (IonoSection.Contains(lat)) { record = IonoSection[lat]; } else { record = new IonoRecord() { LonRange = new IncreaseValue { Start = double.Parse(line.Substring(8, 6)), End = double.Parse(line.Substring(14, 6)), Increament = double.Parse(line.Substring(20, 6)), }, Height = double.Parse(line.Substring(26, 6)), Lat = lat, }; } double lineCount = Math.Ceiling(record.LonRange.Count / 16.0); List <double> vals = new List <double>(); for (int i = 0; i < lineCount; i++) { line = StreamReader.ReadLine(); var items = StringUtil.Split(line, 5); foreach (var item in items) { if (String.IsNullOrWhiteSpace(item)) { continue; } vals.Add(StringUtil.ParseDouble(item)); } } for (int i = 0; i < vals.Count; i++) { //TEC values in 0.1 TECU(10^16) double val = vals[i]; if (Header.Exponent == 0) { val *= 0.1; } else { val *= Math.Pow(10, Header.Exponent); } var alat = record.LonRange.Start + i * record.LonRange.Increament; if (record.Contains(alat)) { record[alat].Rms = val; } else { record.Add(alat, new RmsedNumeral(val, Double.NaN)); } } IonoSection[lat] = record; } if (isValueOrRms) { ionoFile[time] = IonoSection; return(ReadSection(ionoFile, Header, StreamReader)); } return(IonoSection); }
/// <summary> /// 读取RINEX文件的头文件。 /// </summary> /// <param name="path">文件路径</param> /// <returns></returns> public IonoHeader ReadHeader(string path) { if (!Geo.Utils.FileUtil.IsValid(path)) { return(null); } IonoHeader header = new IonoHeader(); header.FileName = Path.GetFileName(path); using (StreamReader r = new StreamReader(path, true)) { int lineIndex = 0; string line = null; while ((line = ReadNextNoNullLine(r)) != null) { lineIndex++; //中文字符支持 int nonAscCount = StringUtil.GetNonAscCount(line.Substring(0, 60 > line.Length ? line.Length : 60)); string headerLabel = line.Substring(60 - nonAscCount).TrimEnd();//header label 61-80 if (headerLabel.Contains(RinexHeaderLabel.END_OF_HEADER)) { break; } string content = line.Substring(0, 60); if (String.IsNullOrWhiteSpace(content)) { continue; } //没有内容 switch (headerLabel) { case RinexHeaderLabel.IONEX_VERSION_TYPE: header.Version = double.Parse(line.Substring(0, 8)); header.FileType = line.Substring(20, 1); header.SatSysOrTheoModel = line.Substring(40, 3); break; case RinexHeaderLabel.PGM_RUN_BY_DATE: header.FileInfo.CreationProgram = line.Substring(0, 20).TrimEnd(); header.FileInfo.CreationAgence = line.Substring(20, 20).Trim(); header.FileInfo.CreationDate = line.Substring(40, 20).TrimEnd(); break; case RinexHeaderLabel.COMMENT: if (header.Comments == null) { header.Comments = new List <string>(); } header.Comments.Add(line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.DESCRIPTION: header.Description = (line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.EPOCH_OF_FIRST_MAP: header.EpochOfFirstMap = Time.Parse(line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.EPOCH_OF_LAST_MAP: header.EpochOfLastMap = Time.Parse(line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.INTERVAL: header.Interval = double.Parse(line.Substring(0, 10)); break; case RinexHeaderLabel.OF_MAPS_IN_FILE: var str = line.Substring(0, 60); if (String.IsNullOrWhiteSpace(str)) { break; } header.NumOfTotalMaps = IntUtil.TryParse(str); break; case RinexHeaderLabel.MAPPING_FUNCTION: header.Description = (line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.ELEVATION_CUTOFF: header.ElevatonCutOff = StringUtil.ParseDouble(line.Substring(0, 10)); break; case RinexHeaderLabel.OBSERVABLES_USED: header.ObservablesUsed = (line.Substring(0, 60 - nonAscCount).Trim()); break; case RinexHeaderLabel.OF_STATIONS: var str2 = line.Substring(0, 6); if (String.IsNullOrWhiteSpace(str2)) { break; } header.NumOfStations = IntUtil.TryParse(str2); break; case RinexHeaderLabel.OF_SATELLITES: var str3 = line.Substring(0, 6); if (String.IsNullOrWhiteSpace(str3)) { break; } header.NumOfSatellites = IntUtil.TryParse(str3); break; case RinexHeaderLabel.BASE_RADIUS: header.MeanEarthRadius = double.Parse(line.Substring(0, 10)); break; case RinexHeaderLabel.MAP_DIMENSION: var str4 = line.Substring(0, 6); if (String.IsNullOrWhiteSpace(str4)) { break; } header.MapDimension = IntUtil.TryParse(str4); break; case RinexHeaderLabel.HGT1_HGT2_DHGT: header.HeightRange = ParseIncreaseValue(line); break; case RinexHeaderLabel.LON1_LON2_DLON: header.HeightRange = ParseIncreaseValue(line); break; case RinexHeaderLabel.LAT1_LAT2_DLAT: header.HeightRange = ParseIncreaseValue(line); break; case RinexHeaderLabel.EXPONENT: header.Exponent = int.Parse(line.Substring(0, 6)); break; case RinexHeaderLabel.START_OF_AUX_DATA: header.StartOfAuxData = line.Substring(0, 60).Trim(); break; case RinexHeaderLabel.END_OF_AUX_DATA: header.EndOfAuxData = line.Substring(0, 60).Trim(); break; case RinexHeaderLabel.STATION_BIAS_RMS: var satFlag = line.Substring(3, 1); //GNSS系统标识 如 G var siteName = satFlag + "_" + line.Substring(6, 4).Trim().ToLower(); //IGS code var val = new RmsedNumeral() { Value = Double.Parse(line.Substring(26, 10)), Rms = Double.Parse(line.Substring(36, 10)), }; header.StationsWithBiasRms[siteName] = val; break; case RinexHeaderLabel.PRN_BIAS_RMS: var Name = SatelliteNumber.Parse(line.Substring(0, 6).Trim()); var val2 = new RmsedNumeral() { Value = Double.Parse(line.Substring(6, 10)), Rms = Double.Parse(line.Substring(16, 10)), }; header.SatellitesWithBiasRms[Name] = val2; break; case RinexHeaderLabel.END_OF_HEADER: return(header); default: break; } header.LineNumber = lineIndex + 1; } } return(header); }