Exemplo n.º 1
0
        public void GetSatPosTest()
        {
            OFile   o = new OFile("Data/rinex/FLNM2111.15o");
            SP3File s = new SP3File("Data/sp3/igs18554.sp3");

            o.TryRead();
            s.TryRead();
            for (int i = 1; i < o.Epoches.Count; i++)
            {
                Console.WriteLine(string.Format("epoch:{0}", i));
                foreach (var prn in o.Epoches[i].PRNList)
                {
                    GPST t0 = o.Epoches[i].Epoch;
                    if (o.Epoches[i][prn].SatData.ContainsKey("P1"))
                    {
                        double p1 = o.Epoches[i][prn].SatData["P1"];
                        t0.AddSeconds(-p1 / Common.C0);
                    }
                    else if (o.Epoches[i][prn].SatData.ContainsKey("P2"))
                    {
                        double p2 = o.Epoches[i][prn].SatData["P2"];
                        t0.AddSeconds(-p2 / Common.C0);
                    }

                    double[] pos = s.GetSatPos(t0, prn);

                    Console.WriteLine("{0} {1} {2} {3}", prn, pos[0], pos[1], pos[2]);
                }
            }
        }
Exemplo n.º 2
0
        public void TestOFile()
        {
            OrderedDictionary od    = new OrderedDictionary();
            OFile             ofile = new OFile(AppDomain.CurrentDomain.BaseDirectory + "\\Data\\rinex\\fjpt1930.13o");

            ofile.TryRead();
            Console.WriteLine(".........");
        }
Exemplo n.º 3
0
        public void DetectClockJumpAndRepairTest()
        {
            OFile ofile = OFile.Read(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data", "rinex", "30900700.11o"));

            Assert.IsNotNull(ofile, "读取文件失败!");

            Console.WriteLine(ofile.Path);

            ObsHelper.DetectClockJumpAndRepair(ref ofile.Epoches, (int)ofile.Header.interval);
        }
Exemplo n.º 4
0
        public override string ToString()
        {
            switch (Game)
            {
            case Game.OcarinaOfTime: return(OFile.ToString());

            case Game.MajorasMask: return(MFile.ToString());

            default: return(base.ToString());
            }
        }
Exemplo n.º 5
0
        public void SearchAllArcsTest()
        {
            OFile ofile = OFile.Read(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data", "rinex", "30900700.11o"));

            Assert.IsNotNull(ofile, "读取文件失败!");
            ofile.DetectAllArcs();
            var arcs = ofile.Arcs;

            foreach (var key in arcs.Keys)
            {
                for (int i = 0; i < arcs[key].Count; i++)
                {
                    Console.WriteLine("{0} 第{1}段 {2,6} {3,6}", key, i + 1, arcs[key][i].StartIndex, arcs[key][i].EndIndex);
                }
                Console.WriteLine("");
            }
        }
Exemplo n.º 6
0
        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            string path = tbxPath.Text;

            if (!File.Exists(path))
            {
                MessageBox.Show("文件不存在");
                return;
            }

            OFile of = new OFile(path);

            if (!of.TryRead())
            {
                MessageBox.Show("读取文件失败");
                return;
            }

            var UTF8NoBOM = new System.Text.UTF8Encoding(false);

            string pathL1 = of.Path.Substring(0, of.Path.Length - 4) + ".meas.l1";
            string pathL2 = of.Path.Substring(0, of.Path.Length - 4) + ".meas.l2";
            string pathP1 = of.Path.Substring(0, of.Path.Length - 4) + ".meas.p1";
            string pathP2 = of.Path.Substring(0, of.Path.Length - 4) + ".meas.p2";
            string pathC1 = of.Path.Substring(0, of.Path.Length - 4) + ".meas.c1";

            StreamWriter writerL1 = new StreamWriter(new FileStream(pathL1, FileMode.Create, FileAccess.Write), UTF8NoBOM);
            StreamWriter writerL2 = new StreamWriter(new FileStream(pathL2, FileMode.Create, FileAccess.Write), UTF8NoBOM);
            StreamWriter writerP1 = new StreamWriter(new FileStream(pathP1, FileMode.Create, FileAccess.Write), UTF8NoBOM);
            StreamWriter writerP2 = new StreamWriter(new FileStream(pathP2, FileMode.Create, FileAccess.Write), UTF8NoBOM);
            StreamWriter writerC1 = new StreamWriter(new FileStream(pathC1, FileMode.Create, FileAccess.Write), UTF8NoBOM);

            OSat   os;
            OEpoch oe;
            string prn;
            string date;

            for (int i = 0; i < of.Epoches.Count; i++)
            {
                oe   = of.Epoches[i];
                date = string.Format("{0},{1}", oe.Epoch.Year, oe.Epoch.DOYTime);
                writerL1.Write(date);
                writerL2.Write(date);
                writerP1.Write(date);
                writerP2.Write(date);
                writerC1.Write(date);

                for (int j = 1; j <= 32; j++)
                {
                    if (j < 10)
                    {
                        prn = "G0" + j.ToString();
                    }
                    else
                    {
                        prn = "G" + j.ToString();
                    }

                    writerL1.Write(',');
                    writerL2.Write(',');
                    writerP1.Write(',');
                    writerP2.Write(',');
                    writerC1.Write(',');

                    if (!oe.AllSat.ContainsKey(prn))
                    {
                        writerL1.Write("0.0000000000");
                        writerL2.Write("0.0000000000");
                        writerP1.Write("0.000");
                        writerP2.Write("0.000");
                        writerC1.Write("0.000");
                        continue;
                    }

                    os = oe[prn];
                    writerL1.Write(os["L1"].ToString("#.000"));
                    writerL2.Write(os["L2"].ToString("#.000"));
                    writerP1.Write(os["P1"].ToString("#.000"));
                    writerP2.Write(os["P2"].ToString("#.000"));
                    writerC1.Write(os["C1"].ToString("#.000"));
                }

                writerL1.Write("\r\n");
                writerL2.Write("\r\n");
                writerP1.Write("\r\n");
                writerP2.Write("\r\n");
                writerC1.Write("\r\n");
            }

            writerL1.Close();
            writerL2.Close();
            writerP1.Close();
            writerP2.Close();
            writerC1.Close();

            MessageBox.Show("提取成功!");
        }
Exemplo n.º 7
0
        /// <summary>
        /// 解算DCB
        /// </summary>
        /// <param name="filePathList">用于计算的观测文件列表</param>
        /// <param name="estimateReceiverDCB">是否估计接收机DCB(默认true)</param>
        /// <param name="estimateSatelliteDCB">是否估计卫星DCB(默认true)</param>
        /// <returns></returns>
        public bool ResolveDCB(int doy,
                               string[] filePathList,
                               DCBOption receiverDCBOpt,
                               DCBOption satelliteDCBOpt,
                               out Dictionary <string, double> receiverDCB,
                               out Dictionary <string, double> satelliteDCB)
        {
            receiverDCB  = new Dictionary <string, double>();
            satelliteDCB = new Dictionary <string, double>();
            if (filePathList is null || filePathList.Length <= 0)
            {
                return(false);
            }

            int year2, year4, month, dom;

            Time.DOY2MonthDay(doy, out year4, out month, out dom);
            year2 = Time.GetYear2(year4);

            PrintWithTime("读取星历文件...");
            int   beforeDay = DOY.AddDays(doy, -1);
            int   afterDay  = DOY.AddDays(doy, 1);
            Orbit Orb       = new Orbit(orbFolder);

            Orb.Read(orbFolder, beforeDay, afterDay);

            OFile[] oFiles = new OFile[filePathList.Length];
            for (int i = 0; i < filePathList.Length; i++)
            {
                PrintWithTime("正在处理文件:" + filePathList[i]);
                try
                {
                    OFile of = new OFile(filePathList[i]);
                    of.TryRead();
                    Orb.GetSatPos(ref of);
                    of.CalAzElIPP();
                    of.DetectOutlier();
                    of.DetectAllArcs();
                    of.DetectCycleSlip();
                    of.CalSP4();
                    oFiles[i] = of;
                }
                catch (Exception ex)
                {
                    PrintWithTime(string.Format("处理失败,原因是:{0}", ex.ToString()));
                    continue;
                }
            }

            List <string>               stationNames = new List <string>(oFiles.Length * 2);
            List <LinkedList <int> >    prn          = new List <LinkedList <int> >();
            List <LinkedList <double> > lat          = new List <LinkedList <double> >();
            List <LinkedList <double> > lon          = new List <LinkedList <double> >();
            List <LinkedList <double> > sp4          = new List <LinkedList <double> >();
            List <LinkedList <double> > ele          = new List <LinkedList <double> >();

            double           b, l;
            HashSet <string> prnStr = new HashSet <string>();
            int prnNum = 0;

            foreach (var of in oFiles)
            {
                stationNames.Add(of.StationName);
                LinkedList <int>    prns = new LinkedList <int>();
                LinkedList <double> lats = new LinkedList <double>();
                LinkedList <double> lons = new LinkedList <double>();
                LinkedList <double> tecs = new LinkedList <double>();
                LinkedList <double> eles = new LinkedList <double>();
                foreach (var p in of.Arcs.Keys)
                {
                    prnStr.Add(p);
                    prnNum = int.Parse(p.Substring(1));
                    var arcs = of.Arcs[p];
                    foreach (var arc in arcs)
                    {
                        for (int i = 0; i < arc.Length; i++)
                        {
                            if (arc[i]["SP4"] > 0)
                            {
                                Coordinate.SunGeomagnetic(arc[i].IPP[0], arc[i].IPP[1],
                                                          arc[i].Epoch.Hour, arc[i].Epoch.Minute, arc[i].Epoch.Second,
                                                          GeoFun.GNSS.Common.GEOMAGNETIC_POLE_LAT, GeoFun.GNSS.Common.GEOMAGENTIC_POLE_LON,
                                                          out b, out l);
                                prns.AddLast(prnNum);
                                tecs.AddLast(arc[i]["SP4"]);
                                lats.AddLast(b);
                                lons.AddLast(l);
                                eles.AddLast(arc[i].Elevation);
                            }
                        }
                    }
                }

                prn.Add(prns);
                lat.Add(lats);
                lon.Add(lons);
                sp4.Add(tecs);
                ele.Add(eles);
            }

            // 从文件中读取dcb
            if (satelliteDCBOpt.Option == enumDCBOption.ReadFromFile)
            {
                if (!File.Exists(satelliteDCBOpt.DCBFilePath))
                {
                    throw new FileNotFoundException("卫星DCB文件无法找到", satelliteDCBOpt.DCBFilePath);
                }

                DCBFile df = new DCBFile(satelliteDCBOpt.DCBFilePath);
                if (!df.TryRead())
                {
                    throw new IOException(string.Format("卫星DCB文件读取失败:{0}", satelliteDCBOpt.DCBFilePath));
                }

                satelliteDCB = df.DCBDict;

                // 将dcb单位转换为米
                foreach (var p in satelliteDCB.Keys)
                {
                    satelliteDCB[p] *= GeoFun.GNSS.Common.C0;
                }
            }
            // 忽略卫星dcb
            else if (satelliteDCBOpt.Option == enumDCBOption.Regardless)
            {
                foreach (var p in prnStr)
                {
                    satelliteDCB.Add(p, 0d);
                }
            }

            PrintWithTime("估计DCB...");
            SphericalHarmonicIonoModel spm;

            if (satelliteDCBOpt.Option == enumDCBOption.Estimation)
            {
                bool flag = IonoModel.CalSphericalHarmonicModel(9, 9, stationNames, prn, lat, lon, sp4, ele,
                                                                out spm, out receiverDCB, out satelliteDCB);
                spm.SaveAs(@"C:\Users\Administrator\Desktop\data\out\0.spm.txt");
                return(flag);
            }
            else if (satelliteDCBOpt.Option == enumDCBOption.ReadFromFile ||
                     satelliteDCBOpt.Option == enumDCBOption.Regardless)
            {
                return(IonoModel.CalSphericalHarmonicModel(9, 9, stationNames, prn, lat, lon, sp4, ele,
                                                           satelliteDCB, out spm, out receiverDCB));
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// 单站单天解
        /// </summary>
        public void ResolveSingleStationSingleDay()
        {
            if (string.IsNullOrWhiteSpace(obsFolder))
            {
                FrmIono.MessHelper.Print("\r\n文件夹不存在:" + obsFolder);
                return;
            }

            DirectoryInfo dir   = new DirectoryInfo(obsFolder);
            var           files = dir.GetFiles("*.??o");

            for (int i = 0; i < files.Length; i++)
            {
                FrmIono.MessHelper.Print(string.Format("\r\n{0}:{1}", DateTime.Now, "开始读取文件:" + files[i].Name));
                try
                {
                    OFile of = new OFile(files[i].FullName);
                    if (of.TryRead())
                    {
                        int    year, doy;
                        string stationName;
                        FileName.ParseRinex2(files[i].Name, out stationName, out doy, out year);

                        // 下载星历
                        Dictionary <string, List <DOY> > doys = new Dictionary <string, List <DOY> >();
                        doys.Add(stationName, new List <DOY> {
                            new DOY(year, doy)
                        });
                        if (!Download(doys))
                        {
                            PrintWithTime("下载星历失败!");
                            return;
                        }

                        DOY fileDOY = new DOY(year, doy);
                        DOY start   = fileDOY.AddDays(-1);
                        DOY end     = fileDOY.AddDays(1);

                        // 读取星历
                        PrintWithTime("正在读取星历...");
                        Orbit orb = new Orbit(orbFolder);
                        orb.GetAllSp3Files(orbFolder, start, end);
                        orb.Read(orbFolder);

                        // 计算轨道
                        PrintWithTime("正在计算轨道...");
                        for (int j = 0; j < of.Epoches.Count; j++)
                        {
                            var epo = of.Epoches[j];
                            orb.GetSatPos(ref epo);
                        }

                        //探测粗差
                        PrintWithTime("正在探测粗差...");
                        of.DetectOutlier();

                        // 探测弧段
                        of.DetectAllArcs();

                        // 探测周跳
                        PrintWithTime("正在探测周跳...");
                        of.DetectCycleSlip();

                        // 计算穿刺点
                        of.CalIPP();

                        // 相位平滑伪距
                        PrintWithTime("正在计算VTEC...");
                        of.CalSP4();

                        // 计算VTEC
                        of.CalVTEC();

                        // 多项式拟合
                        Print("正在拟合多项式...");
                        if (FitType == enumFitType.Polynomial)
                        {
                            of.Fit();
                        }
                        else if (FitType == enumFitType.DoubleDifference)
                        {
                            of.DoubleDifference();
                        }
                        else if (FitType == enumFitType.Smooth)
                        {
                            of.Smooth();
                        }

                        // 输出结果
                        PrintWithTime("正在写入文件...");
                        of.WriteTEC(resFolder);
                    }
                    else
                    {
                        FrmIono.MessHelper.Print(string.Format("\r\n{0}:{1}", DateTime.Now, "读取文件失败!"));
                    }
                }
                catch (Exception e)
                {
                    FrmIono.MessHelper.Print(string.Format("\r\n{0}:{1}:{2}", DateTime.Now, "解算失败,原因是", e.ToString()));
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// 读取所有数据,统一进行解算,很耗内存和时间
        /// </summary>
        public void MultiStationMultiDay()
        {
            if (!Directory.Exists(obsFolder))
            {
                PrintWithTime("文件夹不存在,结束解算!");
                return;
            }
            DirectoryInfo obsDir = new DirectoryInfo(obsFolder);

            PrintWithTime("正在搜索o文件...");
            FileInfo[] files = obsDir.GetFiles("*.??o");
            PrintWithTime(string.Format("共找到{0}个o文件", files.Length));

            Dictionary <int, List <string> > stationsPerDOY           = new Dictionary <int, List <string> >();
            Dictionary <string, List <int> > doysPerStation           = new Dictionary <string, List <int> >();
            Dictionary <int, Dictionary <string, FileInfo> > fileDict = new Dictionary <int, Dictionary <string, FileInfo> >();
            string stationName;
            int    year, day, doy;

            foreach (var file in files)
            {
                FileName.ParseRinex2(file.Name, out stationName, out day, out year);
                doy = year * 1000 + day;
                if (!stationsPerDOY.ContainsKey(doy))
                {
                    stationsPerDOY[doy] = new List <string>();
                }
                if (!doysPerStation.ContainsKey(stationName))
                {
                    doysPerStation[stationName] = new List <int>();
                }

                if (!fileDict.ContainsKey(doy))
                {
                    fileDict[doy] = new Dictionary <string, FileInfo>();
                }

                stationsPerDOY[doy].Add(stationName);
                doysPerStation[stationName].Add(doy);
                fileDict[doy].Add(stationName, file);
            }

            // 观测值起止时间
            int minObsDOY = (from d in stationsPerDOY
                             select d.Key).Min();
            int maxObsDOY = (from d in stationsPerDOY
                             select d.Key).Max();

            // 轨道起止时间
            int minOrbDOY = DOY.AddDays(minObsDOY, -1);
            int maxOrbDOY = DOY.AddDays(maxObsDOY, 1);

            // 下载星历,钟差
            Download(DOY.AddDays(minObsDOY, -1), DOY.AddDays(maxObsDOY, 1));

            // 估计DCB
            PrintWithTime("估计DCB...");
            string[] filePathList = (from p in fileDict[minObsDOY].Values
                                     select p.FullName).ToArray();
            Dictionary <string, double> recDCB, satDCB;

            ResolveDCB(minObsDOY, filePathList, DCBOption.Estimate, DCBOption.Estimate, out recDCB, out satDCB);

            string recDCBName = "0station_dcb.txt";
            string satDCBName = "0satellite_dcb.txt";
            string recDCBPath = Path.Combine(resFolder, recDCBName);
            string satDCBPath = Path.Combine(resFolder, satDCBName);

            string txt = "***\n";
            double dcb = 0d;

            foreach (var rec in recDCB.Keys)
            {
                dcb  = recDCB[rec] / GeoFun.GNSS.Common.C0 * 1e9;
                txt += rec + "," + dcb.ToString("#.0000000000") + "\n";
            }
            File.WriteAllText(recDCBPath, txt, Encoding.UTF8);

            txt = "***\n";
            foreach (var sat in satDCB.Keys)
            {
                dcb  = satDCB[sat] / GeoFun.GNSS.Common.C0 * 1e9;
                txt += sat + "," + dcb.ToString("#.0000000000") + "\n";
            }
            File.WriteAllText(satDCBPath, txt, Encoding.UTF8);

            int epoSegNum = 240;

            foreach (var d in fileDict.Keys)
            {
                PrintWithTime(string.Format("正在处理DOY:{0:000}", d));

                int   beforeDOY = DOY.AddDays(d, -1);
                int   afterDOY  = DOY.AddDays(d, 1);
                Orbit orb       = new Orbit(orbFolder);
                orb.Read(orbFolder, beforeDOY, afterDOY);

                List <OFile> oFiles = new List <OFile>();
                foreach (var s in fileDict[d].Keys)
                {
                    try
                    {
                        OFile of = new OFile(fileDict[d][s].FullName);
                        PrintWithTime(string.Format("正在处理文件:{0}", of.Path));

                        if (!of.TryRead())
                        {
                            continue;
                        }
                        orb.GetSatPos(ref of);
                        of.CalAzElIPP();
                        of.DetectOutlier();
                        of.DetectAllArcs();
                        of.DetectCycleSlip();
                        of.CalSP4();
                        oFiles.Add(of);
                    }
                    catch (Exception ex)
                    {
                        continue;
                    }
                }

                double b, l;
                OFile  ofile;
                SphericalHarmonicIonoModel spm;
                int epoNum = oFiles[0].Epoches.Count;
                int startIndex = 0, endIndex = epoSegNum;
                while (startIndex < epoNum)
                {
                    PrintWithTime(string.Format("电离层二维模型计算 开始历元{0:0000} 结束历元{1:0000}", startIndex, endIndex));
                    List <string>               stationNames = new List <string>(oFiles.Count * 2);
                    List <LinkedList <int> >    prn          = new List <LinkedList <int> >();
                    List <LinkedList <double> > lat          = new List <LinkedList <double> >();
                    List <LinkedList <double> > lon          = new List <LinkedList <double> >();
                    List <LinkedList <double> > sp4          = new List <LinkedList <double> >();
                    List <LinkedList <double> > ele          = new List <LinkedList <double> >();

                    for (int i = 0; i < oFiles.Count; i++)
                    {
                        ofile = oFiles[i];

                        stationNames.Add(ofile.StationName);
                        LinkedList <int>    prns = new LinkedList <int>();
                        LinkedList <double> lats = new LinkedList <double>();
                        LinkedList <double> lons = new LinkedList <double>();
                        LinkedList <double> sp4s = new LinkedList <double>();
                        LinkedList <double> eles = new LinkedList <double>();

                        foreach (var p in ofile.Arcs.Keys)
                        {
                            int prnNum = int.Parse(p.Substring(1));
                            var arcs   = ofile.Arcs[p];
                            foreach (var arc in arcs)
                            {
                                int si = startIndex;
                                int ei = endIndex;

                                if (si > arc.EndIndex)
                                {
                                    continue;
                                }
                                if (ei <= arc.StartIndex)
                                {
                                    continue;
                                }

                                si = 0;
                                if (startIndex > arc.StartIndex)
                                {
                                    si = startIndex - arc.StartIndex;
                                }

                                ei = endIndex - startIndex;
                                if (ei > arc.Length)
                                {
                                    ei = arc.Length;
                                }

                                for (int j = si; j < ei; j++)
                                {
                                    if (arc[j]["SP4"] <= 0)
                                    {
                                        continue;
                                    }
                                    Coordinate.SunGeomagnetic(arc[i].IPP[0], arc[i].IPP[1],
                                                              arc[i].Epoch.Hour, arc[i].Epoch.Minute, arc[i].Epoch.Second,
                                                              GeoFun.GNSS.Common.GEOMAGNETIC_POLE_LAT, GeoFun.GNSS.Common.GEOMAGENTIC_POLE_LON,
                                                              out b, out l);
                                    prns.AddLast(prnNum);
                                    lats.AddLast(b);
                                    lons.AddLast(l);
                                    eles.AddLast(arc[j].Elevation);
                                    sp4s.AddLast(arc[j]["SP4"]);
                                }
                            }
                        }

                        prn.Add(prns);
                        lat.Add(lats);
                        lon.Add(lons);
                        sp4.Add(sp4s);
                        ele.Add(eles);
                    }

                    IonoModel.CalSphericalHarmonicModel(9, 9, stationNames, prn,
                                                        lat, lon, sp4, ele, out spm, recDCB, satDCB);

                    string outFileName = string.Format("{0}_{1:0000}.spm.txt", d, startIndex);
                    string outFilePath = Path.Combine(resFolder, outFileName);
                    spm.SaveAs(outFilePath);

                    startIndex = endIndex;
                    endIndex  += epoSegNum;
                    if (endIndex > epoNum)
                    {
                        endIndex = epoNum;
                    }
                }
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// 计算对应o文件的P4,穿刺点
        /// </summary>
        /// <param name="oPath"></param>
        public static void Calculate(string oPath)
        {
            FileInfo info = new FileInfo(oPath);

            if (info.Name.Length != 12)
            {
                throw new ArgumentException("文件名称正确,请检查:" + info.FullName);
            }

            // 分解出测站名,doy和年份
            string stationName;
            int    doy, year, week, dow;

            FileName.ParseRinex2(info.Name, out stationName, out doy, out year);


            Time.DOY2GPS(year, doy, out week, out dow);

            // 检查是否存在sp3文件
            string sp3Path = Path.Combine(info.DirectoryName, string.Format("igs{0}{1}.sp3", week, dow));

            if (!File.Exists(sp3Path))
            {
                if (!Downloader.DownloadSp3(week, dow, info.DirectoryName))
                {
                    throw new Exception("下载sp3文件失败...");
                }
            }

            // 读取文件
            OFile   oFile = new OFile(oPath);
            SP3File sp3   = new SP3File(sp3Path);

            oFile.TryRead();
            sp3.TryRead();

            //Observation.EliminateSatellites(ref oFile.AllEpoch);
            ObsHelper.CalP4(ref oFile.Epoches);
            ObsHelper.CalL4(ref oFile.Epoches);
            ObsHelper.DetectOutlier(ref oFile.Epoches);

            oFile.DetectAllArcs();
            var arcs = oFile.Arcs;

            foreach (var prn in arcs.Keys)
            {
                for (int i = 0; i < arcs[prn].Count; i++)
                {
                    OArc arc = arcs[prn][i];
                    Smoother.SmoothP4ByL4(ref arc);
                }
            }

            double[,] ippb = new double[2880, 32];
            double[,] ippl = new double[2880, 32];
            double[,] sp4  = new double[2880, 32];

            if (oFile.Header.approxPos.X == 0d)
            {
                throw new Exception("无法获得近似坐标");
            }

            double recX = oFile.Header.approxPos.X;
            double recY = oFile.Header.approxPos.Y;
            double recZ = oFile.Header.approxPos.Z;

            double[] recp = { recX, recY, recZ };
            double   b, l, h;

            Coordinate.XYZ2BLH(recX, recY, recZ, out b, out l, out h, Ellipsoid.ELLIP_WGS84);
            for (int p = 0; p < arcs.Keys.Count; p++)
            {
                string prn = arcs.Keys.ElementAt(p);
                for (int i = 0; i < arcs[prn].Count; i++)
                {
                    OArc arc = arcs[prn][i];
                    //多项式拟合
                    List <double> x = new List <double>();
                    List <double> y = new List <double>();
                    for (int j = 0; j < arc.Length; j++)
                    {
                        x.Add(j);
                        y.Add(arc[j]["SP4"]);
                    }
                    PolynomialModel pm = new PolynomialModel();
                    pm.Order = 3;
                    pm.Fit(x, y);
                    var yy = pm.CalFit(x);
                    for (int j = 0; j < arc.Length; j++)
                    {
                        arc[j]["SP4"] = y[j] - yy[j];
                    }

                    for (int j = 0; j < arc.Length; j++)
                    {
                        GPST t0 = new GPST(arc[j].Epoch);
                        t0.AddSeconds(-arc[j]["P2"] / GeoFun.GNSS.Common.C0);

                        double[] satp = sp3.GetSatPos(t0, prn);
                        arc[j].SatCoor = satp;

                        double az, el;
                        MathHelper.CalAzEl(recp, satp, out az, out el);
                        double bb, ll;
                        MathHelper.CalIPP(b, l, 63781000, 450000, az, el, out bb, out ll);
                        arc[j].IPP[0]               = bb;
                        arc[j].IPP[1]               = ll;
                        arc[j].Azimuth              = az;
                        arc[j].Elevation            = el;
                        ippb[arc.StartIndex + j, p] = bb;
                        ippl[arc.StartIndex + j, p] = ll;

                        double tec = 9.52437 * arc[j]["SP4"];
                        if (tec > 0.5d || tec < -0.5d)
                        {
                            tec = 0d;
                        }
                        sp4[arc.StartIndex + j, p] = tec;
                    }
                }
            }

            for (int i = 0; i < 24; i++)
            {
                StringBuilder sb = new StringBuilder();
                for (int j = i * 120; j < i * 120 + 120; j++)
                {
                    var epoch = oFile.Epoches[j];
                    foreach (var prn in epoch.AllSat.Keys)
                    {
                        var sat = epoch[prn];
                        if (sat["SP4"] > 0.5d || sat["SP4"] < -0.5d)
                        {
                            sat["SP4"] = 0d;
                        }
                        if (sat["SP4"] != 0d)
                        {
                            sb.AppendFormat("{0:0#},{1:f10},{2:f10},{3:f3}\r\n",
                                            int.Parse(prn.Substring(1)),
                                            sat.IPP[1] * Angle.R2D,
                                            sat.IPP[0] * Angle.R2D,
                                            sat["SP4"]
                                            );
                        }
                    }
                }

                File.WriteAllText(string.Format("{0}.{1:0#}-{2:0#}.tec.txt", oPath, i, i + 1), sb.ToString(), Encoding.UTF8);
            }

            //// 2个小时一幅图
            //for (int i = 0; i < 12; i++)
            //{
            //    List<double> lat = new List<double>();
            //    List<double> lon = new List<double>();
            //    List<double> tec = new List<double>();
            //    for (int j = i * 240; j < i * 240 + 240; j++)
            //    {
            //        if (j >= oFile.AllEpoch.Count)
            //        {
            //            break;
            //        }

            //        foreach (var item in oFile.AllEpoch[j].AllSat)
            //        {
            //            var epoch = oFile.AllEpoch[i].Epoch;
            //            var sunL0 = Coordinate.SunLon(epoch.CommonT.Hour,
            //                epoch.CommonT.Minute, (double)epoch.CommonT.second, 8);
            //            var sat = item.Value;
            //            if (sat["SP4"] != 0 && sat["SP4"] > 0)
            //            {
            //                lat.Add(sat.IPP[0]);
            //                lon.Add(sat.IPP[1] - sunL0);

            //                double vtec = Iono.STEC2VTEC(sat["SP4"], sat.Elevation);
            //                tec.Add(vtec);
            //            }
            //        }
            //    }
            //    var shm = SphericalHamonicIonoModel.CalculateModel(5, 5, lat, lon, tec);
            //    for (int j = i * 240; j < i * 240 + 240; j++)
            //    {
            //        if (j - oFile.AllEpoch.Count >= 0)
            //        {
            //            break;
            //        }

            //        foreach (var item in oFile.AllEpoch[j].AllSat)
            //        {
            //            var epoch = oFile.AllEpoch[i].Epoch;
            //            var sunL0 = Coordinate.SunLon(epoch.CommonT.Hour,
            //                epoch.CommonT.Minute, (double)epoch.CommonT.second, 8);
            //            var sat = item.Value;
            //            if (sat["SP4"] != 0)
            //            {
            //                double sp4Est = shm.Calculate(sat.IPP[0], sat.IPP[1] - sunL0);
            //                double sp4Org = sat["SP4"];
            //                sat["SP4"] -= sp4Est;
            //            }
            //        }
            //    }
            //}


            Write(oPath + ".ipp.b.txt", ippb);
            Write(oPath + ".ipp.l.txt", ippl);
            Write(oPath + ".meas.p4.txt", sp4);
        }