static public ObjectTableStorage GetLiTable(RinexObsFile ObsFile, FileEphemerisService FileEphemerisService)
        {
            var table = new ObjectTableStorage("LI values of " + ObsFile.SiteInfo.SiteName);

            foreach (var epoch in ObsFile)
            {
                table.NewRow();
                table.AddItem("Epoch", epoch.ReceiverTime);
                foreach (var sat in epoch)
                {
                    if (sat.PhaseA == null || sat.PhaseB == null)
                    {
                        continue;
                    }
                    table.AddItem(sat.Prn + "_Li", sat.GfValue);
                    if (FileEphemerisService != null)
                    {
                        var eph = FileEphemerisService.Get(sat.Prn, epoch.ReceiverTime);
                        if (eph != null)
                        {
                            var polar = CoordTransformer.XyzToGeoPolar(eph.XYZ, ObsFile.Header.ApproxXyz);
                            table.AddItem(sat.Prn + "_Ele", polar.Elevation);
                        }
                    }
                }
            }
            return(table);
        }
        /// <summary>
        /// 数据刚刚进入,立即执行,最优先的执行,初探
        /// </summary>
        /// <param name="current"></param>
        public override void RawRevise(RinexEpochObservation current)
        {
            //时段过滤
            if (Option.IsEnableTimePeriod)
            {
                if (!Option.TimePeriod.Contains(current.ReceiverTime))
                {
                    current.Clear(); return;
                }
            }

            //采样率时间赋值
            if (this.CurrentIndex == 0 || this.CurrentIndex == -1)
            {
                this.CurrentIndex = 1;
                InitSeconds       = current.ReceiverTime.DateTime.TimeOfDay.TotalSeconds;
                if (Option.IsEnableInterval && Option.Interval > 1 && InitSeconds % 5 != 0) // 若非0, 5秒整数倍的采样间隔,则强制采用10秒整数倍间隔
                {
                    InitSeconds = 0;
                }
            }

            //采样间隔过滤
            if (Option.IsEnableInterval)
            {
                //首先考虑采样率大于1s
                var diff = Math.Round(current.ReceiverTime.DateTime.TimeOfDay.TotalSeconds - InitSeconds) % Option.Interval;
                if (diff > 0.5 && Option.Interval > 1)//相差0.5s,认为是同一个历元
                {
                    current.Clear();
                    return;
                }

                //采样率太小,直接过滤
                if (current.ReceiverTime - PrevOkEpoch < Option.Interval)
                {
                    current.Clear();
                    return;
                }

                //10s 以上的整数必须为10倍的整数秒,如 30s采样率,只能出现 00 和 30 秒
                if (Option.Interval >= 10 && Option.Interval <= 30 && current.ReceiverTime.Seconds % Option.Interval > 1)
                {
                    current.Clear();
                    return;
                }
            }


            //移除其它系统
            if (Option.IsEnableSatelliteTypes)
            {
                current.RemoveOther(Option.SatelliteTypes);
            }


            //观测类型过滤凭借第一字母判断,此处过滤可以加快速度,避免多余计算
            if (Option.IsEnableObsTypes)
            {
                current.RemoveOthers(Option.ObsTypes);
            }

            //删除观测频率
            if (Option.IsEnableRemoveIndicatedFrequence)
            {
                current.RemoveFrequences(Option.FrequenceNumToBeRemoved);
                // log.Info("除频率:" + Geo.Utils.StringUtil.ToString(Option.FrequenceNumToBeRemoved));
            }

            //移除不能组成电离层组合的卫星
            if (Option.IsRemoveIonoFreeUnavaliable)
            {
                List <RinexSatObsData> list = new List <RinexSatObsData>();
                foreach (var sat in current)
                {
                    if (!sat.IsIonoFreeCombinationAvaliable)
                    {
                        list.Add(sat);
                    }
                }
                foreach (var item in list)
                {
                    current.Remove(item.Prn);
                }
            }

            //移除卫星中对于双频无电离层组合多余的观测值
            if (Option.IsRemoveRedundantObsForIonoFree)
            {
                foreach (var sat in current)
                {
                    sat.RemoveRedundantObsForIonoFree();
                }
            }


            //观测码数量不足的移除
            if (ObsCodesToBeRemove != null && ObsCodesToBeRemove.Count > 0)
            {
                foreach (var sat in current)
                {
                    if (!ObsCodesToBeRemove.ContainsKey(sat.Prn.SatelliteType))
                    {
                        continue;
                    }

                    var codes = this.ObsCodesToBeRemove[sat.Prn.SatelliteType];

                    foreach (var item in codes)
                    {
                        sat.Remove(item);
                    }
                }
            }

            //移除指定卫星
            if (Option.IsEnableRemoveSats && Option.SatsToBeRemoved != null && Option.SatsToBeRemoved.Count > 0)
            {
                current.Remove(Option.SatsToBeRemoved);
            }

            //卫星高度角过滤
            if (Option.SatCutOffAngle.Enabled && !XYZ.IsZeroOrEmpty(OldHeader.ApproxXyz))
            {
                //如果星历范围不包括,则不做更改
                if (EphemerisService.TimePeriod.Contains(current.ReceiverTime))
                {
                    List <RinexSatObsData> list = new List <RinexSatObsData>();
                    foreach (var item in current)
                    {
                        var   eph   = EphemerisService.Get(item.Prn, current.ReceiverTime);
                        Polar polar = null;
                        if (eph != null)
                        {
                            polar = CoordTransformer.XyzToGeoPolar(eph.XYZ, OldHeader.ApproxXyz);
                        }
                        //移除了没有星历的卫星
                        if (polar == null || polar.Elevation < Option.SatCutOffAngle.Value)
                        {
                            list.Add(item);
                        }
                    }
                    foreach (var item in list)
                    {
                        current.Remove(item.Prn);
                    }
                }
            }
            //删除指定数据为空的卫星
            if (Option.IsDeleteVacantSat)
            {
                List <SatelliteNumber> tobeDeletes = new List <SatelliteNumber>();
                foreach (var sat in current)
                {
                    foreach (var item in Option.NotVacantCodeList)
                    {
                        if (sat.TryGetValue(item) == 0)
                        {
                            tobeDeletes.Add(sat.Prn);
                        }
                    }
                }
                current.Remove(tobeDeletes);
            }

            base.RawRevise(current);

            //小时段过滤
            if (Option.IsEnableMinEpochCount)
            {
                SmallObsPeriodRemover.Revise(ref current);
            }
        }
        static public ObjectTableStorage GetMp3Table(RinexObsFile ObsFile, FileEphemerisService FileEphemerisService, double maxGfDiffer = 0.15, double maxMwDiffer = 2)
        {
            var           table     = new ObjectTableStorage("Mp2 values of " + ObsFile.SiteInfo.SiteName);
            var           prns      = ObsFile.GetPrns();
            double        interval  = ObsFile.Header.Interval;
            List <double> validData = new List <double>();

            foreach (var prn in prns)
            {
                //if (prn.SatelliteType != SatelliteType.C)
                //{
                //    continue;
                //}
                double                    lastGfVal = 0;
                double                    lastMwVal = 0;
                Time                      lastTime  = null;
                Time                      firstTime = null;
                List <Time>               Times     = new List <Time>();
                List <double>             DataMp3   = new List <double>();
                Dictionary <Time, double> dicMp3    = new Dictionary <Time, double>();

                foreach (var epoch in ObsFile)
                {
                    dicMp3.Add(epoch.ReceiverTime, 0);
                    if (epoch.Contains(prn))
                    {
                        var sat = epoch[prn];
                        if (FileEphemerisService != null)
                        {
                            var eph = FileEphemerisService.Get(sat.Prn, epoch.ReceiverTime);
                            if (eph != null)
                            {
                                var    polar     = CoordTransformer.XyzToGeoPolar(eph.XYZ, ObsFile.Header.ApproxXyz);
                                double elevation = polar.Elevation;
                                if (elevation < 5)
                                {
                                    continue;
                                }
                            }
                        }

                        if (sat.PhaseA == null || sat.RangeA == null || sat.PhaseC == null || sat.RangeC == null)
                        {
                            if (Times.Count > 30)
                            {
                                double averageMp2 = DataMp3.Average();

                                for (int i = 0; i < Times.Count - 1; i++)
                                {
                                    if (dicMp3.ContainsKey(Times[i]))
                                    {
                                        dicMp3[Times[i]] = DataMp3[i] - averageMp2;
                                    }
                                }
                            }
                            lastGfVal = 0;
                            lastMwVal = 0;
                            Times     = new List <Time>();
                            DataMp3   = new List <double>();

                            firstTime = null;
                            // table.AddItem(strEpoch, " ");
                            continue;
                        }

                        if (firstTime == null)
                        {
                            lastTime  = epoch.ReceiverTime;
                            firstTime = epoch.ReceiverTime;
                        }
                        if (lastGfVal == 0 || lastMwVal == 0)
                        {
                            lastGfVal = sat.GfValue;
                            lastMwVal = sat.MwCycle;
                        }
                        var differGf = Math.Abs(sat.GfValue - lastGfVal);
                        var differMw = Math.Abs(sat.MwCycle - lastMwVal);

                        if (epoch.ReceiverTime - lastTime > interval + 0.05 || differGf > maxGfDiffer || differMw > maxMwDiffer || epoch == ObsFile.Last())
                        {
                            double averageMp2 = DataMp3.Average();

                            if (Times.Count > 30) //arc
                            {
                                for (int i = 0; i < Times.Count - 1; i++)
                                {
                                    if (dicMp3.ContainsKey(Times[i]))
                                    {
                                        dicMp3[Times[i]] = DataMp3[i] - averageMp2;
                                    }
                                }
                            }
                            Times     = new List <Time>();
                            DataMp3   = new List <double>();
                            lastGfVal = 0;
                            lastMwVal = 0;
                            firstTime = epoch.ReceiverTime;
                        }
                        Times.Add(epoch.ReceiverTime);
                        DataMp3.Add(sat.Mp3Value);
                        lastTime  = epoch.ReceiverTime;
                        lastGfVal = sat.GfValue;
                        lastMwVal = sat.MwCycle;
                    }
                }
                if (Times.Count > 30) //last arc
                {
                    double averageMp3 = DataMp3.Average();
                    for (int i = 0; i < Times.Count - 1; i++)
                    {
                        if (dicMp3.ContainsKey(Times[i]))
                        {
                            dicMp3[Times[i]] = DataMp3[i] - averageMp3;
                        }
                    }
                }

                table.NewRow();
                table.AddItem("Prn", prn.ToString());

                foreach (var item in dicMp3)
                {
                    string strEpoch = item.Key.Hour.ToString() + ":" + item.Key.Minute.ToString() + ":" + item.Key.Seconds.ToString();
                    if (item.Value != 0)
                    {
                        table.AddItem(strEpoch, item.Value);
                        validData.Add(item.Value);
                    }
                    else
                    {
                        table.AddItem(strEpoch, "");
                    }
                }
            }

            //RMS to evaluate the MP
            //double average = validData.Average();
            //double countData = 0;
            //double countData1 = 0;
            //for (int i = 0; i < validData.Count - 1; i++)
            //{
            //    countData += (validData[i] - average) * (validData[i] - average);
            //    countData1 += validData[i] * validData[i];
            //}

            //double rmsMp = Math.Sqrt(countData / validData.Count);
            //double rmsMp3 = Math.Sqrt(countData1 / validData.Count);

            //table.NewRow();
            //table.AddItem("rmsMp", rmsMp);
            //table.AddItem("rmsMp3", rmsMp3);

            return(table);
        }