/// <summary> /// 构建观测历元。 /// </summary> /// <param name="row"></param> /// <param name="indexColName"></param> /// <returns></returns> public RinexEpochObservation BuildObs(Dictionary <String, object> row, string indexColName) { var obs = new RinexEpochObservation(); obs.ReceiverTime = new Geo.Times.Time((DateTime)row[indexColName]); foreach (var item in row) { var name = item.Key; if (name == indexColName) { continue; } var code = name.Substring(4); var prn = SatelliteNumber.Parse(name); if (!obs.Contains(prn)) { obs[prn] = new RinexSatObsData(prn); } var obsValue = new RinexObsValue((double)item.Value, code); obs[prn].Add(code, obsValue); } return(obs); }
/// <summary> /// 转换 /// </summary> /// <returns></returns> private RinexObsFile Convert() { InitProcess(RawTable.RowCount); TimeConverter = null; CurrentEpochInfo = null; RinexOFile = CreateRinexObsFile(); int index = 0;//只有有效的观测历元才开始计数 foreach (var item in RawTable.BufferedValues) { if (IsCancel) { break; } if (RecordProcessed != null) { RecordProcessed(index); } RinexSatObsData satData = ParseOneRecord(item); if (satData != null) { CurrentEpochInfo.Add(satData); } index++; PerformProcessStep(); } FullProcess(); return(RinexOFile); }
/// <summary> /// 创建RINEX观测数据 /// </summary> /// <param name="prn"></param> /// <param name="C1"></param> /// <param name="D1"></param> /// <param name="L1"></param> /// <param name="S1"></param> /// <returns></returns> private static RinexSatObsData BuildRinexSatObsData(SatelliteNumber prn, double C1, double L1, double S1, double D1) { RinexSatObsData satData = new RinexSatObsData(prn); satData.Add("C1", C1); satData.Add("L1", L1); satData.Add("S1", S1); satData.Add("D1", D1);//存储为距离递增量,方便调试 return(satData); }
public RinexEpochObservation GetEpochObservation(GlonassEpochMessage EpochMessage) { RinexEpochObservation rinex = new RinexEpochObservation(); rinex.ReceiverTime = EpochMessage.Header.Time; foreach (var item in EpochMessage) { var msg = item as GlonassNormalMessage1012; RinexSatObsData satData = GetSatObsData(msg); rinex.Add(satData.Prn, satData); } return(rinex); }
/// <summary> /// 对上面的函数重新编写 /// </summary> /// <param name="msg1004"></param> /// <returns></returns> public RinexSatObsData GetSatObsData(NormalMessage1004 msg1004) { RinexSatObsData obsData = new RinexSatObsData(); double L1Pseudorange = 0; double L1Phase = 0; double L2Pseudorange = 0; double L2Phase = 0; obsData.Prn = msg1004.Prn; L1Pseudorange = GetL1PseudoRange(msg1004.GpsL1Pseudorange, msg1004.GpsIntegerL1PseudorangeModulusAmbiguity); if (msg1004.GpsL1PhaseRangeMinusPseudorange != RtcmConst.MaxGpsL1PhaseRangeMinusPseudorange) { double L1PhaseMinusPseudorange = msg1004.GpsL1PhaseRangeMinusPseudorange * RtcmConst.PhaseRangeResolution / Frequence.GpsL1.WaveLength; L1PhaseMinusPseudorange = RevisePhaseRange(obsData.Prn, FrequenceType.A, L1PhaseMinusPseudorange); L1Phase = L1Pseudorange / Frequence.GpsL1.WaveLength + L1PhaseMinusPseudorange; } if (msg1004.GpsL2MinusL1PseudorangeDifference != RtcmConst.MaxL2MinusL1PseudorangeDifference) { L2Pseudorange = GetL2PseudoRange(L1Pseudorange, msg1004.GpsL2MinusL1PseudorangeDifference); } if (msg1004.GpsL2PhaseRangeMinusL1Pseudorange != RtcmConst.MaxGpsL1PhaseRangeMinusPseudorange) { double L2PhaseMinusL1Pseudorange = msg1004.GpsL2PhaseRangeMinusL1Pseudorange * RtcmConst.PhaseRangeResolution / Frequence.GpsL2.WaveLength; L2PhaseMinusL1Pseudorange = RevisePhaseRange(obsData.Prn, FrequenceType.B, L2PhaseMinusL1Pseudorange); L2Phase = L1Pseudorange / Frequence.GpsL2.WaveLength + L2PhaseMinusL1Pseudorange; } //obsData. //ObservationCode ObservationCodeOfC = new ObservationCode(); //ObservationCode ObservationCodeOfL = new ObservationCode(); //ObservationCode ObservationCodeOfS = new ObservationCode(); //ObservationCode ObservationCodeOfD = new ObservationCode(); obsData.Add("C1X", L1Pseudorange); obsData.Add("L1X", L1Phase); obsData.Add("P2X", L2Pseudorange); obsData.Add("L2X", L2Phase); return(obsData); }
/// <summary> /// 对上面的函数重新编写 /// </summary> /// <param name="msg1012"></param> /// <returns></returns> public RinexSatObsData GetSatObsData(GlonassNormalMessage1012 msg1012) { RinexSatObsData obsData = new RinexSatObsData(); double L1Pseudorange = 0; double L1Phase = 0; double L2Pseudorange = 0; double L2Phase = 0; obsData.Prn = msg1012.Prn; L1Pseudorange = GetL1PseudoRange(msg1012.GlonassL1Pseudorange, msg1012.GlonassIntegerL1PseudorangeModulusAmbiguity); if (msg1012.GlonassL1PhaseRangeMinusPseudorange < RtcmConst.MaxGpsL1PhaseRangeMinusPseudorange) { double L1PhaseMinusPseudorange = msg1012.GlonassL1PhaseRangeMinusPseudorange * RtcmConst.PhaseRangeResolution / Frequence.GpsL1.WaveLength; L1PhaseMinusPseudorange = RevisePhaseRange(obsData.Prn, FrequenceType.A, L1PhaseMinusPseudorange); L1Phase = L1Pseudorange / Frequence.GpsL1.WaveLength + L1PhaseMinusPseudorange; } if (msg1012.GlonassL2MinusL1PseudorangeDifference < RtcmConst.MaxL2MinusL1PseudorangeDifference) { L2Pseudorange = GetL2PseudoRange(L1Pseudorange, msg1012.GlonassL2MinusL1PseudorangeDifference); } if (msg1012.GlonassL2PhaseRangeMinusL1Pseudorange < RtcmConst.MaxGpsL1PhaseRangeMinusPseudorange) { double L2PhaseMinusL1Pseudorange = msg1012.GlonassL2PhaseRangeMinusL1Pseudorange * RtcmConst.PhaseRangeResolution / Frequence.GpsL2.WaveLength; L2PhaseMinusL1Pseudorange = RevisePhaseRange(obsData.Prn, FrequenceType.B, L2PhaseMinusL1Pseudorange); L2Phase = L1Pseudorange / Frequence.GpsL2.WaveLength + L2PhaseMinusL1Pseudorange; } //obsData. obsData.Add("C1X", L1Pseudorange); obsData.Add("L1X", L1Phase); obsData.Add("P2X", L2Pseudorange); obsData.Add("L2X", L2Phase); return(obsData); }
/// <summary> /// RTCM MSM文件信息转换为观测文件信息.此处返回的是RINEX3.0的数据类型。 /// </summary> /// <param name="msg"></param> /// <param name="HeaderOfMSM"></param> /// <returns></returns> public RinexEpochObservation GetRinexEpochObservation(BaseMSM msg, HeaderOfMSM HeaderOfMSM) { RinexEpochObservation RinexEpochObservation = new RinexEpochObservation(); uint messageNumber = HeaderOfMSM.MessageNumber; double wavelength = 0; int frequencyBand = 0; string str = null; string attribute = null; double P = 0, L = 0, D = 0, S = 0; int j = 0; int index = 0; double p = 0; SatelliteType satType = SatelliteType.G; for (int i = 0; i < HeaderOfMSM.SatCount; i++) { RinexSatObsData SatObsData = new RinexSatObsData(); for (int k = 0; k < HeaderOfMSM.Nsig; k++) { if (HeaderOfMSM.CellMask[index++] == 0) { continue; } if (messageNumber >= 1071 && messageNumber <= 1077)//GPS { satType = SatelliteType.G; SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.G); str = msm_sig_gps[HeaderOfMSM.SignalMask[k] - 1]; frequencyBand = int.Parse(str.Substring(0, 1)); attribute = str.Substring(1, 1); if (frequencyBand == 1) { wavelength = Frequence.GpsL1.WaveLength; } else if (frequencyBand == 2) { wavelength = Frequence.GpsL2.WaveLength; } else if (frequencyBand == 5) { wavelength = Frequence.GpsL5.WaveLength; } } else if (messageNumber >= 1081 && messageNumber <= 1087)//GLONASS { satType = SatelliteType.R; SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.R); } else if (messageNumber >= 1091 && messageNumber <= 1097)//GALILEO { satType = SatelliteType.E; SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.E); } else if (messageNumber >= 1101 && messageNumber <= 1017)//SBS { satType = SatelliteType.S; SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.S); } else if (messageNumber >= 1111 && messageNumber <= 1117)//QZS { satType = SatelliteType.J; SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.J); } else if (messageNumber >= 1121 && messageNumber <= 1127)//BDS { satType = SatelliteType.C; SatObsData.Prn = new SatelliteNumber(HeaderOfMSM.SatlliteMask[i], SatelliteType.C); str = msm_sig_gps[HeaderOfMSM.SignalMask[k] - 1]; frequencyBand = int.Parse(str.Substring(0, 1)); attribute = str.Substring(1, 1); if (frequencyBand == 2) { wavelength = Frequence.CompassB1.WaveLength; } else if (frequencyBand == 6) { wavelength = Frequence.CompassB3.WaveLength; } else if (frequencyBand == 7) { wavelength = Frequence.CompassB2.WaveLength; } } var ObservationCodeOfC = new ObservationCode(ObservationType.C, frequencyBand, attribute); var ObservationCodeOfL = new ObservationCode(ObservationType.L, frequencyBand, attribute); var ObservationCodeOfS = new ObservationCode(ObservationType.S, frequencyBand, attribute); var ObservationCodeOfD = new ObservationCode(ObservationType.D, frequencyBand, attribute); if (msg.NumberOfIntegerMsInSatRoughRange.Count != 0) { p = msg.NumberOfIntegerMsInSatRoughRange[i] * 0.001 + msg.SatelliteRoughRangesModulo1ms[i] * Math.Pow(2, -13); } else { p = msg.SatelliteRoughRangesModulo1ms[i] * Math.Pow(2, -13); } if (msg.SignalFinePseudorange.Count != 0) { P = msg.SignalFinePseudorange[j] * Math.Pow(2, -24) + p; } else if (msg.SignalFinePseudorangeWithExtendedResolution.Count != 0) { P = msg.SignalFinePseudorangeWithExtendedResolution[j] * Math.Pow(2, -29) + p; } P = P * RtcmConst.LightSpeedPerMillisecond; if (msg.SignalFinePhaseRange.Count != 0) { L = msg.SignalFinePhaseRange[j] * Math.Pow(2, -29) + p; } else if (msg.SignalFinePhaseRangeWithExtendedResolution.Count != 0) { L = msg.SignalFinePhaseRangeWithExtendedResolution[j] * Math.Pow(2, -31) + p; } L = L * RtcmConst.LightSpeedPerMillisecond / wavelength; if (msg.PhaseRangeLockTimeIndicator.Count != 0) { S = msg.PhaseRangeLockTimeIndicator[j]; } else if (msg.PhaseRangeLockTimeIndicatorWithExtendedRangeAndResolution[j] != 0) { S = msg.PhaseRangeLockTimeIndicatorWithExtendedRangeAndResolution[j]; } if (messageNumber % 10 == 5 || messageNumber % 10 == 7 && msg.SatRoughPhaseRangeRate.Count != 0) { if (msg.SatRoughPhaseRangeRate[i] > -1638.4) { D = -(msg.SatRoughPhaseRangeRate[i] * 0.001 + msg.SignalFinePhaseRangeRate[j] * 0.0001) / wavelength; } } SatObsData.Add(ObservationCodeOfC.ToString(), P); SatObsData.Add(ObservationCodeOfL.ToString(), L); SatObsData.Add(ObservationCodeOfS.ToString(), S); SatObsData.Add(ObservationCodeOfD.ToString(), D); //更新头部信息 var obsCodes = new List <string>(); obsCodes.Add(ObservationCodeOfC.ToString()); obsCodes.Add(ObservationCodeOfL.ToString()); obsCodes.Add(ObservationCodeOfS.ToString()); obsCodes.Add(ObservationCodeOfD.ToString()); if (ObsHeader != null) { ObsHeader.ObsCodes[satType] = obsCodes; } j++; } RinexEpochObservation.Add(SatObsData.Prn, SatObsData); } RinexEpochObservation.Header = ObsHeader; RinexEpochObservation.ReceiverTime = HeaderOfMSM.EpochTime; return(RinexEpochObservation); }
/// <summary> /// 解析一行数据。 /// </summary> /// <param name="item"></param> /// <returns></returns> private RinexSatObsData ParseOneRecord(Dictionary <string, object> item) { RinexSatObsData satData = null; #region 赋值 long timeNanos = ParseLong(item, TimeNanos); //当前时间到GPS起始时间的纳秒数,为负数。 long fullBiasNanos = ParseLong(item, FullBiasNanos); double biasNanos = ParseDouble(item, BiasNanos); double timeOffsetNanos = ParseDouble(item, TimeOffsetNanos); long receivedSvTimeNanos = ParseLong(item, ReceivedSvTimeNanos); long receivedSvTimeUncertaintyNanos = ParseLong(item, ReceivedSvTimeUncertaintyNanos); int hardwareClockDiscontinuityCount = ParseInt(item, HardwareClockDiscontinuityCount); int accumulatedDeltaRangeState = ParseInt(item, AccumulatedDeltaRangeState); double cn0DbHz = ParseDouble(item, Cn0DbHz); double accumulatedDeltaRangeMeters = ParseDouble(item, AccumulatedDeltaRangeMeters); #endregion SatelliteNumber prn = ParsePrn(item); //伪距不确定度太大,本数据作废 if (receivedSvTimeUncertaintyNanos > 1e8) { log.Debug(prn + " 卫星时间不确定度太大,忽略本数据 " + receivedSvTimeUncertaintyNanos); return(satData); }//简单判断伪距 //如果钟跳发生了,或指定的被减伪距值无效,则重置被减伪距 bool isClockDisCountChanged = (_prevHardwareClockDisCount != hardwareClockDiscontinuityCount); _prevHardwareClockDisCount = hardwareClockDiscontinuityCount; //决定是否新建时间计算器。 if (TimeConverter == null || !TimeConverter.IsEpochValid) { TimeConverter = new AndroidGnssTimeConverter(fullBiasNanos, Option.IsFromFirstEpoch);//fullBiasNanos值并不准确,含有偏差,不能用于计算所有伪距。 if (!TimeConverter.IsEpochValid) { log.Debug("当前历元时间不合法," + TimeConverter.FirstEpochOfUtc + ",将重试。"); return(satData); } } TimeConverter.SetFullBias(fullBiasNanos) .SetTimeNanos(timeNanos) .SeBiasNanos(biasNanos) .SetTimeOffsetNanos(timeOffsetNanos); Time currentUtcTime = TimeConverter.GetReceiverUtcTime(); TimeConverter.SetSatelliteType(prn.SatelliteType); //若是新历元 if (IsNewEpoch(CurrentEpochInfo, _currentTimeNanos, timeNanos)) //新历元 { _currentTimeNanos = timeNanos; //记录当接收机时间,用于判断是否是同一个历元 CurrentEpochInfo = new RinexEpochObservation(currentUtcTime); RinexOFile.Add(CurrentEpochInfo); } //计算伪距 double transTime = TimeConverter.GetTransmissionTime(receivedSvTimeNanos); double C1 = transTime * GnssConst.LIGHT_SPEED; bool isPassed = CheckPsuedorange(ref prn, C1); if (!isPassed) { C1 = 0; } if (C1 == 0 && Option.IsSkipZeroPseudorange) { log.Debug(currentUtcTime + ", " + prn + "伪距为0,忽略本数据 "); return(satData); } if (accumulatedDeltaRangeMeters == 0 && Option.IsSkipZeroPhase) { log.Debug(currentUtcTime + ", " + prn + "载波为 0,忽略本数据 "); return(satData); } //时间积累差,带来的近距离变化差 double timeErrorDistance = TimeConverter.GetDifferDistance(); var phaseRange = accumulatedDeltaRangeMeters - timeErrorDistance;//相位距离 var aligner = NumericalAlignerManager.GetOrCreate(prn); if (isClockDisCountChanged) //如果钟跳发生,则将第一个差分伪距设置为当前伪距值。 { aligner.IsReset = true; } phaseRange = aligner.GetAlignedValue(currentUtcTime, phaseRange, C1); double L1 = GetL1(phaseRange, prn, Option.IsToCylePhase); double S1 = cn0DbHz; double D1 = phaseRange; //test for range satData = BuildRinexSatObsData(prn, C1, L1, S1, D1); return(satData); }