コード例 #1
0
        //protected override void SetProperties()
        //{
        //    this.EntityType = typeof(FcbOfUpd);
        //    Properties = new List<System.Reflection.PropertyInfo>();

        //    Properties.Add(typeof(Time).);

        //    StringBuilder sb = new StringBuilder();
        //    foreach (var item in Properties.)
        //    {
        //        Properties.Add(EntityType.GetProperty(item.Trim()));
        //    }
        //}

        /// <summary>
        ///   "Epoch", "BasePrn", "Count", "WnMarker",
        ///        "G01", "G02",  "G03", "G04",  "G05", "G06",  "G07", "G08",  "G09",
        ///"G10",  "G11", "G12",  "G13", "G14",  "G15", "G16",  "G17", "G18",  "G19",
        ///"G20",  "G21", "G22",  "G23", "G24",  "G25", "G26",  "G27", "G28",  "G29",
        ///"G30",  "G31", "G32",
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override string EntityToLine(FcbOfUpd obj)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(obj.Epoch.ToString());
            sb.Append(ItemSpliter);
            sb.Append(obj.WnMarker);
            sb.Append(ItemSpliter);
            sb.Append(obj.BasePrn.ToString());
            sb.Append(ItemSpliter);
            sb.Append(obj.Count.ToString());
            //sb.Append(ItemSpliter);
            //sb.Append(obj.PrnsString.ToString());
            var prns = SatelliteNumber.GpsPrns;

            foreach (var item  in prns)
            {
                sb.Append(ItemSpliter);
                var val = obj.Get(item);
                if (RmsedNumeral.IsValid(val))
                {
                    sb.Append(val.ToString("0.0000"));
                }
                else
                {
                    sb.Append(val);
                }
            }
            return(sb.ToString());
        }
コード例 #2
0
        /// <summary>
        /// 将所有产品归算到一个卫星上面。取平均。
        /// </summary>
        /// <param name="basePrn"></param>
        /// <returns></returns>
        public FcbOfUpd GetWideLaneFcb(SatelliteNumber basePrn)
        {
            Dictionary <SatelliteNumber, RmsedNumeral> result = GetFinalFcbOfBsd(basePrn);

            result[basePrn] = new RmsedNumeral(0, 0);
            var prns = result.Keys.ToList();

            prns.Sort();
            //生成产品
            FcbOfUpd fcb = new FcbOfUpd();

            fcb.BasePrn  = basePrn;
            fcb.WnMarker = FcbOfUpd.WideLaneMaker;
            fcb.Count    = 32;// result.Count;
            fcb.Epoch    = this.First.First.FirstKey.Start;
            //fcb.Prns = prns;
            int i = 0;

            foreach (var prn in prns)
            {
                i++;
                if (i > 32)
                {
                    break;
                }
                fcb.Add(prn, result[prn]);
            }

            return(fcb);
        }
コード例 #3
0
 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="obs"></param>
 /// <param name="PrevAdjustment"></param>
 public OneDimAdjustMatrixBuilder(RmsedNumeral obs, AdjustResultMatrix PrevAdjustment = null)
 {
     this.PrevAdjustment = PrevAdjustment;
     this.ObsValue       = obs;
     this.ParamNames     = new List <string>()
     {
         "Value"
     };
 }
コード例 #4
0
ファイル: GroupedValueService.cs プロジェクト: yxw027/GNSSer
 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="table"></param>
 public ParamValueService(ObjectTableStorage table) : base(table)
 {
     Data = new Dictionary <string, RmsedNumeral>();
     foreach (var item in table.BufferedValues)
     {
         var name = item["Name"].ToString();
         var val  = (double)item["Value"];
         var rms  = (double)item["Rms"];
         Data[name] = new RmsedNumeral(val, rms);
     }
 }
コード例 #5
0
        /// <summary>
        /// 计算平滑的伪距,最快的迭代,带电离层的递推平滑算法,可以大大加快速度。
        /// 算法已验证,和窗口单独迭代相同,需要注意的式如果正式平滑时,则不需要加权了。
        /// 2018.06.20, czs, 这是推导了好几天才出的结果,并得到了验证,具体公式请参看本人发表的文章:**平滑伪距***。
        /// </summary>
        /// <returns></returns>
        public RmsedNumeral GetSmoothValueByFastUpdate() 
        {
            int count = this.Count;
            RmsedNumeral result = null;
            double extraP = 0;//外推的结果
            double deltaTail = 0;
            if (this.Count <= 1)
            {
                result = GetFirstOrDefault();
                extraP = result.Value; 
            }
            else //采用窗口内的数据进行平滑
            { 
                //所谓的推估表达式,即不采用当前的伪距观测数据,    P0 + (L1 - L0) + 2DI
                extraP = LastSmoothedRange + (this.CurrentData.IonoFittedPhaseRange - PrevData.IonoFittedPhaseRange) ;

                double sP = extraP;
                if (IsWeighted)//加权,表示采用当前的伪距观测数据
                {
                    if (this.LastRemovedItem.Value != null)//当大于指定的窗口,将扣除窗口外的数据(包括电离层延迟)影响。
                    {
                        double ionoDiffer =  CurrentData.FittedIonoAndAmbiValue - this.LastRemovedPair.FittedIonoAndAmbiValue;
                         
                        deltaTail = 1.0 / (this.Count) * (CurrentData.RangeMinusPhase - this.LastRemovedPair.RangeMinusPhase - 2.0 * ionoDiffer);
                        sP = extraP + deltaTail;
                    }
                    else //原始Hatch滤波
                    {
                        double weight = GetWeight(this.LastKey, count);
                        sP = weight * this.CurrentData.PseudoRange + (1 - weight) * extraP;
                    }
                }
        
                double stdDev = this.RawRangeStdDev * 0.1 / Math.Sqrt(count);
                result = new RmsedNumeral(sP, stdDev);

                //验证算法,2018.06.20, czs,
                //var result3  = GetSmoothValueByWholeWindowRecursionAk();      
                //double ionoDiff;
                //double Ak = GetAk(out ionoDiff);
                //double akDelta = Ak - PrevAk;
                //double differOfAkDelta = akDelta - deltaTail;
                ////var result2 = this.CurrentRaw.PhaseRange + Ak;
                ////double differ = result2 - result.Value;
                ////double differ2 = result2 - result3.Value;
                ////int oo = 0;
                //PrevAk = Ak;
            }


            this.PrevData = this.CurrentData;
            this.LastSmoothedRange = result.Value;
            return result;
        }
コード例 #6
0
        private static RmsedNumeral ParseRmedNumeral(string strVal)
        {
            var    items = strVal.Split(' ');
            var    val   = Geo.Utils.StringUtil.ParseDouble(items[0]);
            double rms   = 0;

            if (items.Length > 1)
            {
                rms = Geo.Utils.StringUtil.ParseDouble(items[1]);
            }
            var rmsedVal = new RmsedNumeral(val, rms);

            return(rmsedVal);
        }
コード例 #7
0
        /// <summary>
        /// 获取FCB
        /// </summary>
        /// <param name="time"></param>
        /// <param name="prn"></param>
        /// <param name="basePrn">基准卫星</param>
        /// <returns></returns>
        public RmsedNumeral GetNLFcbOfBsdValue(Time time, SatelliteNumber prn, SatelliteNumber basePrn)
        {
            string       fileName = CheckFileLoaded(time);
            RmsedNumeral result   = null;

            if (Files.ContainsKey(fileName))
            {
                var file = Files[fileName];
                if (file == null)
                {
                    return(null);
                }

                result = file.GetFcbOfBsdValue(time, prn, basePrn);
            }

            return(result);
        }
コード例 #8
0
        /// <summary>
        /// 计算窄巷模糊度浮点解
        /// </summary>
        /// <param name="FloatAmbiguityDiffer"></param>
        /// <param name="wideLaneInteger"></param>
        /// <returns></returns>
        public RmsedNumeral GetNarrowLaneValue(RmsedNumeral FloatAmbiguityDiffer, RmsedNumeral wideLaneInteger)
        {
            //求乘数因子
            RmsedNumeral narrowLane = RmsedNumeral.Zero;

            if (IsPppAmbiInCycleOrLen)
            {
                narrowLane = (FloatAmbiguityL1CycleMultiFactor * FloatAmbiguityDiffer
                              - WideLaneMultiFactor * wideLaneInteger);
            }
            else
            {
                narrowLane =
                    (FloatAmbiguityLenMultiFactor * FloatAmbiguityDiffer
                     - WideLaneMultiFactor * wideLaneInteger);
            }
            return(narrowLane);
        }
コード例 #9
0
        public override FcbOfUpd Parse(string[] items)
        {
            if (CurrentIndex <= 0)
            {
                Time time;
                if (!Time.TryParse(items[0], out time))
                {
                    return(null);
                }
            }
            var item = new FcbOfUpd();
            int i    = 0;

            item.Epoch    = Time.Parse(items[i++]);
            item.WnMarker = (items[i++]);
            item.BasePrn  = SatelliteNumber.Parse(items[i++]);
            item.Count    = int.Parse(items[i++]);
            //item.PrnsString = (items[i++]);
            int length = items.Length;

            for (int j = i; j < length; j++)
            {
                var prn = new SatelliteNumber(j - i + 1, SatelliteType.G);
                var val = RmsedNumeral.Parse(items[j]);
                //double rms = 0.0001;
                //int rmsIndex = j + FcbOfUpdFile.TotalGpsSatCount;
                //if(items.Length > rmsIndex)
                //{
                //    rms = Double.Parse(items[rmsIndex]);
                //}

                item.Data.Add(prn, val);// new RmsedNumeral(val,rms));
            }
            //foreach (var prn in item.Prns)
            //{
            //    item.Data.Add(prn, Double.Parse(items[i++]));
            //}

            return(item);
        }
コード例 #10
0
        private NameRmsedNumeralVector GetIntMwDoubleDiffers(ParamValueService paramValueService, GroupedValueService wmValues)
        {
            NameRmsedNumeralVector wideLaneVector = new NameRmsedNumeralVector();
            // RmsedVector wideLaneVector = new RmsedVector();

            var paramNames = paramValueService.ParamNames;

            foreach (var item in paramNames)
            {
                if (!NetDoubleDifferName.IsDifferParam(item))
                {
                    continue;
                }
                var paramName = NetDoubleDifferName.Parse(item);
                CurrentBasePrn = paramName.RefPrn;

                if (!paramName.IsValid)
                {
                    continue;
                }
                var floatWideAmbi = wmValues.GetFirstDoubleDiffer(paramName);
                if (floatWideAmbi == null)
                {
                    continue;
                }

                var wideAmbi = new RmsedNumeral(Math.Round(floatWideAmbi.Value), 1e-10);
                var differ   = (floatWideAmbi.Value - wideAmbi.Value);
                if (Math.Abs(differ) > 0.3)
                {
                    log.Info(item + " 宽项(MW)整数偏差为 " + differ + "取消固定。");
                    continue;
                }

                wideLaneVector[item] = wideAmbi;
            }

            return(wideLaneVector);
        }
コード例 #11
0
        /// <summary>
        /// 1. 处理一颗卫星的宽项值,包含和基准卫星的差分值。
        /// </summary>
        /// <param name="tableRow"></param>
        /// <param name="sat"></param>
        private void SolveAndUpdateWideLane(EpochSatellite sat)
        {
            var prn       = sat.Prn;
            var prnKey    = prn.ToString();
            var smoothKey = BuildWideLaneKey(prnKey);

            var mwCycle = sat.Combinations.MwPhaseCombinationValue; // MW 值
            var filter  = this.WideLaneFilterManager.GetOrCreate(prnKey);

            filter.Buffers = GetMwValues(prn);
            var rms           = IsSetWeightWithSat ?  SatWeightProvider.GetStdDev(sat) : 1;
            var input         = new RmsedNumeral(mwCycle, rms);
            var smoothAligned = filter.Filter(input);

            LatestEpochSatWmValues[sat.Prn] = new EpochSatDifferValue()
            {
                Index       = sat.EpochInfo.EpochIndexOfDay,
                Prn         = sat.Prn,
                RawValue    = mwCycle - filter.IntegerPart,
                SmoothValue = smoothAligned.Value
            };
        }
コード例 #12
0
        /// <summary>
        /// 计算差分产品,小数部分,区间[-0.5, 0.5]
        /// </summary>
        /// <param name="basePrn">基准卫星</param>
        /// <returns>正小数的产品</returns>
        public Dictionary <SatelliteNumber, RmsedNumeral> GetDifferFractionProduct(SatelliteNumber basePrn)
        {
            var rawDiffer = this.GetRawDiffer(basePrn);               //首先获取各站内的卫星差分
            var fractions = rawDiffer.GetAverageRoundFractionTable(); //计算小数部分的平均,以表格返回,列名为卫星,行索引为测站
            //字典法
            var dic     = new Dictionary <SatelliteNumber, RmsedNumeral>();
            var results = fractions.GetAveragesWithRms();           //所有卫星差分值求平均

            foreach (var item in results)
            {
                var prn = SatelliteNumber.Parse(item.Key);
                if (prn == SatelliteNumber.Default)
                {
                    continue;
                }

                var frac = Geo.Utils.DoubleUtil.GetRoundFraction(item.Value.Value); //产品为 [-0.5, 0.5] 区间的小数

                dic[prn] = new RmsedNumeral(frac, item.Value.Rms);
            }

            return(dic);
        }
コード例 #13
0
        /// <summary>
        /// 双频无电离层组合校正
        /// </summary>
        /// <param name="obj"></param>
        private void ReviseDualIonoFree(EpochInformation obj)
        {
            foreach (var sat in obj)
            {
                double       correction  = 0;
                double       rawRange    = 0;
                double       rawPhase    = 0;
                RmsedNumeral corredRange = RmsedNumeral.Zero;


                var PS = PhaseSmoothedRangeBuilderManager.GetOrCreate(sat.Prn);

                rawRange    = sat.Combinations.IonoFreeRange.Value;
                rawPhase    = sat.Combinations.IonoFreePhaseRange.Value;
                corredRange = PS.SetReset(sat.IsUnstable)
                              .SetRawValue(obj.ReceiverTime, rawRange, rawPhase, 0)
                              .Build();
                correction = corredRange.Value - rawRange;

                //规定:非原生观测量改正到近似值上【在观测方程的右边,因此符号相反】。 //2018.05.29, czs, int hmx
                sat.RangeOnlyCorrection.AddCorrection("IonFreePhaseSmoothRangeOfAB", -1.0 * correction);
                sat.StdDevOfRange = corredRange.StdDev;
            }
        }
コード例 #14
0
        /// <summary>
        /// 遍历每一个历元
        /// </summary>
        /// <param name="epochInfo"></param>
        /// <returns></returns>
        public override bool Revise(ref EpochInformation epochInfo)
        {
            //如果没有基准卫星,则不可计算
            if (!epochInfo.EnabledPrns.Contains(BasePrn))
            {
                return(false);
            }

            //1.计算宽项滤波值,并存储
            foreach (var sat in epochInfo)
            {
                SolveAndUpdateWideLane(sat);
            }

            //2.计算平滑宽项星间差分值
            var baseMwValue = this.LatestEpochSatWmValues[BasePrn];

            foreach (var sat in epochInfo) //只处理本历元具有的卫星
            {
                var val = this.LatestEpochSatWmValues[sat.Prn];
                //计算差分值
                SovleAndUpdateDifferValue(val, baseMwValue);
            }

            //3.提取PPP计算结果,模糊度差分结果,先不做平滑
            foreach (var prn in epochInfo.EnabledPrns)
            {
                var floatVal = PppResult.GetFloatAmbiguityCycle(prn);
                LatestEpochFloatAmbiguityValues[prn] = new EpochSatDifferValue()
                {
                    Index       = epochInfo.EpochIndexOfDay,
                    Prn         = prn,
                    RawValue    = floatVal,
                    SmoothValue = floatVal,
                };
            }
            //3.1 星间单差值,更新到结果
            var baseFloat = this.LatestEpochFloatAmbiguityValues[BasePrn];

            foreach (var prn in epochInfo.EnabledPrns)
            {
                var val = LatestEpochFloatAmbiguityValues[prn];
                val.DifferValue = val.SmoothValue - baseFloat.SmoothValue;
            }

            //4.计算窄巷值
            foreach (var sat in epochInfo.EnabledSats)
            {
                var prn      = sat.Prn;
                var prnKey   = prn.ToString();
                var val      = LatestEpochFloatAmbiguityValues[prn];
                var wideLane = this.LatestEpochSatWmValues[sat.Prn];

                double fcbOfWideLaneDiffer = 0;
                var    differkey           = BuildDifferKey(prn);
                if (DifferFcbManager != null && DifferFcbManager.Contains(differkey))
                {
                    var dcb = DifferFcbManager.Get(differkey).Last;
                    fcbOfWideLaneDiffer = dcb.WideLaneValue;
                    if (Math.Abs(dcb.Time - sat.ReceiverTime) > 7 * 3600 * 24)
                    {
                        log.Warn("提供的宽项星间单差已经超过一周!");
                    }
                }
                var intWideLane = wideLane.DifferValue - fcbOfWideLaneDiffer;            //此处应该减去星间单差的小数部分。2016.10.20.
                var wideLaneInt = (int)Math.Round(intWideLane);
                var narrowValue = GetNarrowLaneValue(sat, val.DifferValue, wideLaneInt); //此处应该固定模糊度,不应该直接取整。

                this.LatestEpochNarrowLaneValues[prn] = new EpochSatValue()
                {
                    Index    = epochInfo.EpochIndexOfDay,
                    Prn      = prn,
                    RawValue = narrowValue,
                    Tag      = wideLaneInt // 存储整型宽项模糊度
                };

                //获取小数部分
                var narrowBuffer = NarrowBufferManager.GetOrCreate(prnKey);
                if (narrowBuffer.IsFull)
                {
                    var filter = this.NarrowLaneFilterManager.GetOrCreate(prnKey);
                    filter.Buffers = narrowBuffer;
                    var rms           = IsSetWeightWithSat ? SatWeightProvider.GetStdDev(sat) : 1;
                    var input         = new RmsedNumeral(narrowValue, rms);
                    var smoothAligned = filter.Filter(input);
                    this.LatestEpochNarrowLaneValues[prn].SmoothValue = smoothAligned.Value;
                }

                narrowBuffer.Add(narrowValue);
            }

            //3.输出
            if (IsOutputDetails)
            {
                TableStorage.NewRow();
                TableStorage.AddItem("Epoch", epochInfo.ReceiverTime.ToShortTimeString());

                foreach (var sat in epochInfo.EnabledSats) //只处理本历元具有的卫星
                {
                    var val         = this.LatestEpochSatWmValues[sat.Prn];
                    var prnKey      = val.Prn.ToString();
                    var wideLaneKey = BuildWideLaneKey(prnKey);

                    //宽项
                    TableStorage.AddItem(wideLaneKey + "_Raw", val.RawValue);
                    TableStorage.AddItem(wideLaneKey + "_Smooth", val.SmoothValue);
                    TableStorage.AddItem(wideLaneKey + "_MwDiffer", val.DifferValue);

                    //浮点解
                    var floatVal  = this.LatestEpochFloatAmbiguityValues[sat.Prn];
                    var floatKey  = prnKey;
                    var differKey = BuildDifferKey(prnKey);

                    TableStorage.AddItem(floatKey + "_FloatAmbi_Raw", floatVal.RawValue);
                    //TableStorage.AddItem(floatKey + "_Smooth", floatVal.SmoothValue);
                    TableStorage.AddItem(differKey, floatVal.DifferValue);

                    //窄巷
                    var narrowVal     = this.LatestEpochNarrowLaneValues[sat.Prn];
                    var narrowLaneKey = BuildNarrowLaneKey(prnKey);
                    TableStorage.AddItem(narrowLaneKey + "_Raw", narrowVal.RawValue);
                    TableStorage.AddItem(narrowLaneKey + "_WideLaneInt", narrowVal.Tag);
                    TableStorage.AddItem(narrowLaneKey + "_Smooth", narrowVal.SmoothValue);
                    //TableStorage.AddItem(narrowLaneKey + "_MwDiffer", narrowVal.DifferValue);
                }
            }
            return(true);
        }
コード例 #15
0
ファイル: SmoothRangeWindowOld.cs プロジェクト: yxw027/GNSSer
        /// <summary>
        /// 计算平滑的伪距,最快的迭代,带电离层的递推平滑算法,可以大大加快速度。
        /// 算法已验证,和窗口单独迭代相同,需要注意的式如果正式平滑时,则不需要加权了。
        /// 2018.06.20, czs, 这是推导了好几天才出的结果,并得到了验证,具体公式请参看本人发表的文章:**平滑伪距***。
        /// </summary>
        /// <returns></returns>
        public RmsedNumeral GetSmoothValueByFastUpdate()
        {
            int          count     = this.Count;
            RmsedNumeral result    = null;
            double       extraP    = 0;//外推的结果
            double       deltaTail = 0;

            if (this.Count <= 1)
            {
                result = GetFirstOrDefault();
                extraP = result.Value;

                CurrentData.FittedIonoAndAmbiValue = CurrentData.GetRawIonoAndHalfAmbiValue();
            }
            else //采用窗口内的数据进行平滑
            {
                double ionDiffer = 0;
                if (IsDeltaIonoCorrect)//电离层改正赋值
                {
                    //var fit = IonoWindow.GetPolyFitValue(CurrentData.Time,  OrderOfDeltaIonoPolyFit, IonoFitDataCount);
                    //if (fit != null)
                    //{
                    //    CurrentData.FittedIonoAndAmbiValue = fit.Value;
                    //}
                    //else
                    //{
                    //    CurrentData.FittedIonoAndAmbiValue = CurrentData.GetRawIonoAndHalfAmbiValue();
                    //}
                    ionDiffer = (CurrentData.FittedIonoAndAmbiValue - PrevData.FittedIonoAndAmbiValue);
                }

                //所谓的推估表达式,即不采用当前的伪距观测数据,    P0 + (L1 - L0) + 2DI
                extraP = LastSmoothedRange + (this.CurrentData.PhaseRange - PrevData.PhaseRange) + 2 * ionDiffer;

                double sP = extraP;
                if (IsWeighted)                             //加权,表示采用当前的伪距观测数据
                {
                    if (this.LastRemovedItem.Value != null) //当大于指定的窗口,将扣除窗口外的数据(包括电离层延迟)影响。
                    {
                        double ionoDiffer = 0;
                        if (IsDeltaIonoCorrect)
                        {
                            ionoDiffer = CurrentData.FittedIonoAndAmbiValue - this.LastRemovedPair.FittedIonoAndAmbiValue;

                            //var bigFit = BigIonoWindow.GetTimedLsPolyFit(1);
                            //ionoDiffer = bigFit.GetY( CurrentData.Time) - bigFit.GetY(LastRemovedPair.Time);
                        }
                        deltaTail = 1.0 / (this.Count) * (CurrentData.RangeMinusPhase - this.LastRemovedPair.RangeMinusPhase - 2.0 * ionoDiffer);
                        sP        = extraP + deltaTail;
                    }
                    else //原始Hatch滤波
                    {
                        double weight = GetWeight(this.LastKey, count);
                        sP = weight * this.CurrentData.PseudoRange + (1 - weight) * extraP;
                    }
                }

                double stdDev = this.RawRangeStdDev * 0.1 / Math.Sqrt(count);
                result = new RmsedNumeral(sP, stdDev);

                //验证算法,2018.06.20, czs,
                //var result3  = GetSmoothValueByWholeWindowRecursionAk();
                //double ionoDiff;
                //double Ak = GetAk(out ionoDiff);
                //double akDelta = Ak - PrevAk;
                //double differOfAkDelta = akDelta - deltaTail;
                ////var result2 = this.CurrentRaw.PhaseRange + Ak;
                ////double differ = result2 - result.Value;
                ////double differ2 = result2 - result3.Value;
                ////int oo = 0;
                //PrevAk = Ak;
            }


            this.PrevData          = this.CurrentData;
            this.LastSmoothedRange = result.Value;
            return(result);
        }
コード例 #16
0
 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="count"></param>
 public SphericalHarmonicsItem(int count)
 {
     C    = new RmsedNumeral[count];
     S    = new RmsedNumeral[count];
     S[0] = RmsedNumeral.Zero;//第一个始终为0.
 }
コード例 #17
0
        private void button_combine_Click(object sender, EventArgs e)
        {
            var fcbPathes = fileOpenControl_fcbPathes.FilePathes;
            var basePrn   = this.baseSatSelectingControl1.SelectedPrn;

            log.Info("即将转换FCB文件基准到 " + basePrn);
            //文件读取
            Dictionary <string, FcbOfUpdFile> data = new Dictionary <string, FcbOfUpdFile>();
            FcbOfUpdFile baseFile = null;

            foreach (var path in fcbPathes)
            {
                var file = new FcbOfUpdReader(path).ReadToFile();
                if (file.Count == 0)
                {
                    continue;
                }

                var target = file.ToFile(basePrn);//基准转换到统一的卫星
                if (target == null || target.Count == 0)
                {
                    continue;
                }

                var fileName = Path.GetFileName(path);
                data[fileName] = target;
                if (baseFile == null)
                {
                    baseFile = target;
                }
            }
            log.Info("文件读取完毕,数量: " + fcbPathes.Length);

            //汇集
            log.Info("即将汇集各文件到一个对象,然后方便进行平均,这个过程比较耗时。。。 ");
            EpochSatSiteValueList valList = new EpochSatSiteValueList("多基准FCB合成");

            foreach (var epochProduct in baseFile)
            {
                var epoch = epochProduct.Epoch;
                valList.GetOrCreate(epoch).GetOrCreate(basePrn).Add("BasePrn", RmsedNumeral.Zero); //基准卫星和数据不用计算。

                foreach (var kv in data)
                {
                    var epochVal = kv.Value.Get(epoch);
                    if (epochVal == null)
                    {
                        continue;
                    }

                    foreach (var item in epochVal.Data.KeyValues)
                    {
                        if (item.Key == basePrn)
                        {
                            continue;
                        }

                        if (RmsedNumeral.IsValid(item.Value))
                        {
                            valList.GetOrCreate(epoch).GetOrCreate(item.Key).Add(kv.Key, item.Value);
                        }
                    }
                }
            }
            log.Info("各文件汇集转换完成,即将求平均 ");

            //求平均
            var ave = valList.GetAverage(0, 3);

            //生成窄巷FCB 产品,并写入文件
            var FcbOfUpds = ave.GetFcbProduct(basePrn);

            //写入文件  //写入文件
            var outpath = FcbOfUpdWriter.WriteEpochProducts(FcbOfUpds, basePrn + "_CombiedEpochNLFcbOfDcb");

            log.Info("执行完毕! ");

            Geo.Utils.FormUtil.ShowOkAndOpenDirectory(Path.GetDirectoryName(outpath));
        }
コード例 #18
0
        /// <summary>
        /// 校正其中一个。
        /// </summary>
        /// <param name="sat"></param>
        /// <param name="freq"></param>
        /// <param name="obsFreq"></param>
        private void ReviseOneFreq(EpochSatellite sat, FrequenceType freq, FreqenceObservation obsFreq)
        {
            double       correction       = 0;
            RmsedNumeral corredRange      = RmsedNumeral.Zero;
            var          rangeObservation = obsFreq.PseudoRange;
            double       rawRange         = rangeObservation.Value;
            double       rawPhase         = obsFreq.PhaseRange.Value;

            var PS = PhaseSmoothedRangeBuilderManager.GetOrCreate(BuildSatFreqName(sat, freq));

            double ionoDiffer = 0;

            switch (this.PhaseSmoothedRangeBuilderManager.IonoDifferCorrectionType)
            {
            case IonoDifferCorrectionType.No:
                break;

            case IonoDifferCorrectionType.DualFreqCarrier:
                ionoDiffer = sat.GetIonoLenByDifferPhase(freq);
                break;

            case IonoDifferCorrectionType.WindowPolyfit:
                break;

            case IonoDifferCorrectionType.WindowWeightedAverage:
                break;

            case IonoDifferCorrectionType.IndicatedFile:
                if (IonoDeltaTable == null)
                {
                    log.Warn("电离层延迟变化表格为NULL!无法改正");
                }
                else
                {
                    var dat = InputedIonoDelta.Get(sat.Prn.ToString());
                    if (dat != null)
                    {
                        var win = dat.GetNumeralWindowData(sat.ReceiverTime);

                        if (win != null)
                        {
                            ionoDiffer = win.GetPolyFitValue(sat.ReceiverTime, 1, 2).Value;
                        }
                    }
                }
                break;

            default:
                break;
            }

            corredRange = PS.SetReset(sat.IsUnstable)
                          .SetRawValue(sat.ReceiverTime, rawRange, rawPhase, ionoDiffer)
                          .Build();
            correction = corredRange.Value - rawRange;

            //规定:原生观测量改正到观测值上【在观测方程的左边,因此符号不变】。 //2018.05.29, czs, int hmx
            CorrectionNames name = CorrectionNames.PhaseSmoothRange;

            switch (freq)
            {
            case FrequenceType.A:
                name = CorrectionNames.PhaseSmoothRangeA;
                break;

            case FrequenceType.B:
                name = CorrectionNames.PhaseSmoothRangeB;
                break;

            case FrequenceType.C:
                name = CorrectionNames.PhaseSmoothRangeC;
                break;

            default:
                name = CorrectionNames.PhaseSmoothRange;
                break;
            }

            rangeObservation.SetCorrection(name, correction);

            sat.StdDevOfRange = corredRange.StdDev;

            //检查更新电离层改正
            if (PS is GnsserWindowedPhaseSmoothedRangeBuilder)
            {
                obsFreq.TempAmbiguityAndIonoLength = ((GnsserWindowedPhaseSmoothedRangeBuilder)PS).SmoothRangeWindow.CurrentIonoAndHalfLambdaLen;
            }
        }
コード例 #19
0
 public void Add(string name, RmsedNumeral val)
 {
     this.Add(val.Value, name);
     this.rmsVecror.Add(val.Rms);
 }
コード例 #20
0
        /// <summary>
        ///  读取RINEX文件的头文件。
        /// </summary>
        /// <param name="reader">数据流</param>
        /// <returns></returns>
        public IonoHarmonicHeader ReadHeader(StreamReader reader)
        {
            //if (!Geo.Utils.FileUtil.IsValid(path)) { return null; }
            IonoHarmonicHeader header = new IonoHarmonicHeader();
            //header.FileName = Path.GetFileName(path);
            int    lineIndex = 0;
            string line      = null;

            while ((line = ReadNextNoNullLine(reader)) != null)
            {
                lineIndex++;
                if (line.StartsWith(IonoHarmonicHeaderLabel.COEFFICIENTS))
                {
                    break;
                }
                if (line.StartsWith(IonoHarmonicHeaderLabel.DEGREE))
                {
                    break;
                }

                string strVal = GetValueString(line);

                if (line.StartsWith(IonoHarmonicHeaderLabel.MODEL_NUMBER_STATION_NAME))
                {
                    header.ModelNumberStationName = strVal;
                    continue;
                }
                if (line.StartsWith(IonoHarmonicHeaderLabel.MODEL_TYPE))
                {
                    header.ModelType = strVal; continue;
                }
                if (line.StartsWith(IonoHarmonicHeaderLabel.MAXIMUM_DEGREE_OF_SPHERICAL_HARMONICS))
                {
                    header.MaxDegree = Geo.Utils.StringUtil.ParseInt(strVal); continue;
                }
                if (line.StartsWith(IonoHarmonicHeaderLabel.MAXIMUM_ORDER))
                {
                    header.MaxOrder = Geo.Utils.StringUtil.ParseInt(strVal); continue;
                }
                if (line.StartsWith(IonoHarmonicHeaderLabel.EVELOPMENT_WITH_RESPECT_TO))
                {
                    line   = ReadNextNoNullLine(reader);
                    strVal = GetValueString(line);
                    header.IsGeographicalOrGeomeagnetic = Geo.Utils.StringUtil.ParseInt(strVal) == 1;

                    line   = ReadNextNoNullLine(reader);
                    strVal = GetValueString(line);
                    header.IsMeanOrTruePosOfTheSun = Geo.Utils.StringUtil.ParseInt(strVal) == 1;

                    continue;
                }

                if (line.StartsWith(IonoHarmonicHeaderLabel.MAPPING_FUNCTION))
                {
                    header.MappingFunction = (IonoMappingFunction)Geo.Utils.StringUtil.ParseInt(strVal); continue;
                }
                if (line.StartsWith(IonoHarmonicHeaderLabel.HEIGHT_OF_SINGLE_LAYER_AND_ITS_RMS_ERROR))
                {
                    RmsedNumeral rmsedVal = ParseRmedNumeral(strVal);
                    header.LayerHeight = rmsedVal; continue;
                }
                if (line.StartsWith(IonoHarmonicHeaderLabel.COORDINATES_OF_EARTH_CENTERED_DIPOLE_AXIS))
                {
                    line   = ReadNextNoNullLine(reader);
                    strVal = GetValueString(line);
                    line   = ReadNextNoNullLine(reader);
                    strVal = GetValueString(line); continue;
                }
                if (line.StartsWith(IonoHarmonicHeaderLabel.PERIOD_OF_VALIDITY))
                {
                    line   = ReadNextNoNullLine(reader);
                    strVal = GetValueString(line);
                    var start = Time.Parse(strVal);
                    line   = ReadNextNoNullLine(reader);
                    strVal = GetValueString(line);
                    var end = start;
                    if (!String.IsNullOrWhiteSpace(strVal))
                    {
                        end = Time.Parse(strVal);
                    }
                    header.ValidPeroid = new TimePeriod(start, end); continue;
                }
                if (line.StartsWith(IonoHarmonicHeaderLabel.LATITUDE_BAND_COVERED))
                {
                    line   = ReadNextNoNullLine(reader);
                    strVal = GetValueString(line);
                    var min = Geo.Utils.StringUtil.ParseDouble(strVal);
                    line   = ReadNextNoNullLine(reader);
                    strVal = GetValueString(line);
                    var max = Geo.Utils.StringUtil.ParseDouble(strVal);
                    header.LatSpan = new NumerialSegment(min, max);
                    continue;
                }
                if (line.StartsWith(IonoHarmonicHeaderLabel.ADDITIONAL_INFORMATION))
                {
                    while ((line = ReadNextNoNullLine(reader)) != null)
                    {
                        if (line.StartsWith(IonoHarmonicHeaderLabel.COEFFICIENTS))
                        {
                            break;
                        }
                        if (line.StartsWith(IonoHarmonicHeaderLabel.DEGREE))
                        {
                            break;
                        }
                        strVal = GetValueString(line);

                        if (line.StartsWith(IonoHarmonicHeaderLabel.NUMBER_OF_CONTRIBUTING_STATIONS))
                        {
                            header.NumOfStations = Geo.Utils.StringUtil.ParseInt(strVal); continue;
                        }
                        if (line.StartsWith(IonoHarmonicHeaderLabel.NUMBER_OF_CONTRIBUTING_SATELLITES))
                        {
                            header.NumOfSatellites = Geo.Utils.StringUtil.ParseInt(strVal); continue;
                        }
                        if (line.StartsWith(IonoHarmonicHeaderLabel.ELEVATION_CUT_OFF_ANGLE))
                        {
                            header.ElevationCutOff = Geo.Utils.StringUtil.ParseDouble(strVal); continue;
                        }
                        if (line.StartsWith(IonoHarmonicHeaderLabel.MAXIMUM_TEC_AND_ITS_RMS))
                        {
                            header.MaxTec = ParseRmedNumeral(strVal);
                            continue;
                        }
                    }
                    if (line.StartsWith(IonoHarmonicHeaderLabel.COEFFICIENTS))
                    {
                        break;
                    }
                    if (line.StartsWith(IonoHarmonicHeaderLabel.DEGREE))
                    {
                        break;
                    }
                }
            }
            return(header);
        }
コード例 #21
0
ファイル: IonoFreePppOld2.cs プロジェクト: yxw027/GNSSer
        /// <summary>
        /// 滤波计算
        /// </summary>
        /// <param name="epochInfo"></param>
        /// <param name="lastResult"></param>
        /// <returns></returns>
        public override SingleSiteGnssResult CaculateKalmanFilter(EpochInformation epochInfo, SingleSiteGnssResult lastResult)
        {
            //极速模式。
            if (Option.TopSpeedModel)
            {
                return(base.CaculateKalmanFilter(epochInfo, lastResult));
            }

            epochInfo.RemoveIonoFreeUnavailable();
            if (epochInfo.Count < 2)
            {
                log.Error("卫星可用数量不足:" + epochInfo.Count);
                return(null);
            }
            var result = base.CaculateKalmanFilter(epochInfo, lastResult) as PppResult;

            //外部模糊度文件直接固定
            if (Option.IsFixingAmbiguity && Option.IsUseFixedParamDirectly && File.Exists(Option.AmbiguityFilePath) && Option.IsUsingAmbiguityFile)
            {
                return(result);
            }

            //var testBasePrn = new SatelliteNumber(12, SatelliteType.G);

            //平滑MW
            if (Option.IsFixingAmbiguity)
            {
                SmoothMwProvider.Add(epochInfo);
            }

            if (this.IsFixingAmbiguity
                //&& epochInfo.Contains(testBasePrn)
                && epochInfo.ReceiverTime.DateTime.TimeOfDay > TimeSpan.FromHours(2)
                )
            {
                //this.CurrentBasePrn = testBasePrn;

                var time  = epochInfo.ReceiverTime;
                var SD_MW = SmoothMwProvider.GetDifferMwValue(CurrentBasePrn); //周为单位
                if (SD_MW.Count < 2)                                           //MW精度不足
                {
                    return(result);
                }

                var wmFcb = WideLaneBiasService.Get(time).GetMwDiffer(CurrentBasePrn);        //用于模糊度固定,精度要求不高,一次任务获取一次即可

                SatWideNarrowValueManager wideNarrowValues = new SatWideNarrowValueManager(); //存储用于模糊度固定的宽窄项及对应的浮点产品
                //基本参数定义
                double maxMwRms      = 0.3;                                                   //MW 至少的平滑精度
                double maxDevOfInt   = 0.2;                                                   //MW 取整时允许最大的偏差
                var    f1            = Frequence.GetFrequenceA(CurrentBasePrn, time).Value;   // 1575.42;
                var    f2            = Frequence.GetFrequenceB(CurrentBasePrn, time).Value;   //  1227.60;
                var    wideWaveLen   = Frequence.GetMwFrequence(CurrentBasePrn, time).WaveLength;
                var    narrowWaveLen = Frequence.GetNarrowLaneFrequence(CurrentBasePrn, time).WaveLength;

                #region 对MW值(宽巷模糊度)进行固定
                foreach (var item in SD_MW)
                {
                    //简单的质量控制
                    if (item.Value.Rms > maxMwRms && !Double.IsNaN(item.Value.Rms))
                    {
                        continue;
                    }
                    var f = wmFcb[item.Key]; //已经归算为和WM的定义相同,在[0-1]区间,满足 B=N+f, N=B-f.
                    if (f == double.NaN)
                    {
                        continue;
                    }

                    var B = item.Value.Value;

                    var nearN = B - f;

                    var N = (int)Math.Round(nearN);                                                    //直接进行取整数
                    if (Math.Abs(nearN - N) <= maxDevOfInt)                                            //fixedSD_MW=0代表无效
                    {
                        wideNarrowValues.GetOrCreate(item.Key).WideLane = new IntFractionNumber(f, N); //改正后的 WLFCB
                    }
                }
                #endregion

                //提取浮点解星间单差
                SetPppFloatAmbiguityLen(result, wideNarrowValues);

                #region 固定窄巷模糊度                                           //星间单差,窄巷模糊度
                var tempCoeef  = f2 / (f1 + f2);                          //算法1
                var tempCoeef2 = (f1 + f2) * 1e6 / GnssConst.LIGHT_SPEED; //算法2:单位转换,窄巷波长的倒数
                var tempCoeef3 = f2 / (f1 - f2);                          //算法2
                foreach (var kv in wideNarrowValues.Data)
                {
                    //  var nFcb = SDNL_FCB[kv];//获取窄巷的产品
                    var prn     = kv.Key;
                    var satData = kv.Value;
                    var f       = NarrawLaneFcbService.GetBsdOfNarrowLane(prn, CurrentBasePrn, time); //获取窄巷的产品f, 符合B=N+f
                    if (!RmsedNumeral.IsValid(f))
                    {
                        continue;
                    }

                    var wideInt         = satData.WideLane.Int;//只需要整数部分,小数部分化为窄巷小数部分,不影响整体
                    var floatPppAmbiLen = satData.FloatAmbiguityLength;

                    var B = (floatPppAmbiLen - tempCoeef * wideWaveLen * wideInt) / narrowWaveLen;//算法1

                    #region 算法验证
                    var B2     = tempCoeef2 * floatPppAmbiLen - tempCoeef3 * wideInt;             //算法2
                    var differ = B - B2;
                    if (differ > 0.0001)
                    {
                        int ii = 0;
                        throw new Exception("Error!");
                    }
                    #endregion

                    var nearN = B - f;
                    var N     = (int)Math.Round(nearN.Value);                   //直接进行取整数
                    if (Math.Abs(nearN.Value - N) <= maxDevOfInt)               //fixedSD_MW=0代表无效
                    {
                        satData.NarrowLane = new IntFractionNumber(f.Value, N); //改正后的 WLFCB
                    }
                }
                #endregion

                //提取协方差,采用Lambda去相关后固定模糊度

                #region LAMBDA固定窄巷模糊度
                //提取已选择的模糊度协方差阵


                //#region 星间单差窄巷模糊度协方差矩阵
                //IMatrix B = new ArrayMatrix(this.Adjustment.ParamNames.Count - 6, this.Adjustment.ParamNames.Count - 5, 0.0); //将非差模糊度转换为星间单差模糊度的旋转矩阵
                //int index = 0;//参考星的索引位置???,参考星不同,index不同
                //for (int i = 5; i < this.Adjustment.ParamNames.Count; i++)
                //{
                //    SatelliteNumber sat = SatelliteNumber.Parse(this.Adjustment.ParamNames[i].Substring(0, 3));
                //    if (sat == MaxPrn)
                //    {
                //        break;
                //    }
                //    else
                //    {
                //        index++;
                //    }

                //}
                //for (int i = 0; i < this.Adjustment.ParamNames.Count - 6; i++)
                //{
                //    if (i < index)
                //    {
                //        B[i, index] = -1; B[i, i] = 1;
                //    }
                //    if (i >= index)
                //    {
                //        B[i, index] = -1; B[i, i + 1] = 1;
                //    }
                //}

                //IMatrix BT = B.Transposition;
                //IMatrix covaAmb = new ArrayMatrix(this.Adjustment.ParamNames.Count - 5, this.Adjustment.ParamNames.Count - 5, 0); //非差模糊度的协方差矩阵
                //for (int i = 0; i < this.Adjustment.ParamNames.Count - 5; i++)
                //{
                //    for (int j = 0; j < this.Adjustment.ParamNames.Count - 5; j++)
                //    {
                //        covaAmb[i, j] = this.Adjustment.CovaOfEstimatedParam[i + 5, j + 5];
                //    }
                //}
                //IMatrix SD_covaAmb = B.Multiply(covaAmb).Multiply(BT); //星间单差模糊度的协方差矩阵
                //IMatrix SDNL_covaAmb = new ArrayMatrix(this.Adjustment.ParamNames.Count - 6, this.Adjustment.ParamNames.Count - 6, 0.0); //星间单差窄巷模糊度的协方差矩阵
                //for (int i = 0; i < this.Adjustment.ParamNames.Count - 6; i++)
                //{
                //    for (int j = 0; j < this.Adjustment.ParamNames.Count - 6; j++)
                //    {
                //        SDNL_covaAmb[i, j] = SD_covaAmb[i, j] * (1575.42 + 1227.60) / (1575.42 * GnssConst.GPS_L1_WAVELENGTH);//系数
                //    }
                //}
                //#endregion

                //#region 部分模糊度固定,先将可以固定的星间单差窄巷模糊度 及其 协方差矩阵挑出来
                //List<string> old_ambpara = new List<string>();
                //foreach (var item in SD_floatAmb.Keys)
                //{
                //    old_ambpara.Add(item.ToString());//所有的模糊度(除了参考星)
                //}
                //List<string> new_ambpara = new List<string>();
                //foreach (var item in SDNL_floatAmb.Keys)
                //{
                //    new_ambpara.Add(item.ToString());//可以固定的模糊度(宽巷 < 0.25 && NLFCB != 0)
                //}
                //IMatrix newtrix = NamedMatrix.GetNewMatrix(new_ambpara, old_ambpara, SDNL_covaAmb.Array); //将可以固定的模糊度的协方差矩阵挑出来
                //#endregion



                #endregion


                StringBuilder sb = new StringBuilder();
                sb.Append("PPP模糊度固定," + time + ", BasePrn : " + CurrentBasePrn + ", 其它:" + wideNarrowValues.Count + ", " + Geo.Utils.StringUtil.ToString(wideNarrowValues.Keys));

                log.Info(sb.ToString());

                //计算固定后的模糊度距离
                //已经固定的模糊度
                var fixedPppAmbi = new Dictionary <SatelliteNumber, double>();
                foreach (var kv in wideNarrowValues.Data)
                {
                    if (!kv.Value.IsValid)
                    {
                        continue;
                    }
                    var prn             = kv.Key;
                    var satData         = kv.Value;
                    var wideInt         = satData.WideLane.Int;      //宽巷模糊度仍然采用整数
                    var floatNarrowAmbi = satData.NarrowLane.Value;  //浮点部分包括在窄巷硬件延迟中
                    var fixedAmbiLen    = tempCoeef * wideWaveLen * wideInt + narrowWaveLen * floatNarrowAmbi;

                    satData.FixedAmbiguityLength = fixedAmbiLen;
                    //简单质量控制
                    if (satData.DifferOfAmbiguityLength < 0.5)
                    {
                        fixedPppAmbi[prn] = fixedAmbiLen;
                    }
                }

                #region 条件平差  模糊度固定
                return(FixPppResult(result, fixedPppAmbi));

                #endregion
            }
            return(result);
        }
コード例 #22
0
ファイル: IonoReader.cs プロジェクト: yxw027/GNSSer
        /// <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);
        }