Example #1
0
        ///// <summary>
        ///// .斜TEC转垂直TEC的乘法因子。
        ///// </summary>
        ///// <param name="satElevation">卫星高度角,角度degree</param>
        ///// <param name="radiusOfMeanEarth">地球平均半径</param>
        ///// <param name="heightOfIono">电离层模型高度</param>
        ///// <returns></returns>
        //private static double GetSlopeToVerticalFactor(double satElevation, double radiusOfMeanEarth, double heightOfIono)
        //{
        //    return Math.Sqrt(1.0 - Math.Pow(radiusOfMeanEarth * Math.Cos(satElevation * Geo.Coordinates.AngularConvert.DegToRadMultiplier) / (radiusOfMeanEarth + heightOfIono), 2.0));
        //}
        /// <summary>
        /// 垂直TEC转斜TEC的乘法因子。
        /// </summary>
        /// <param name="satElevation">卫星高度角,角度degree</param>
        /// <param name="radiusOfMeanEarth">地球平均半径</param>
        /// <param name="heightOfIono">电离层模型高度</param>
        /// <returns></returns>
        //private static double GetVerticalToSlopeFactor(double satElevation, double radiusOfMeanEarth, double heightOfIono)
        //{
        //    return 1.0 /  GetSlopeToVerticalFactor(satElevation, radiusOfMeanEarth, heightOfIono);
        //}

        /// <summary>
        /// 获取服务为,原始数据。单位 1e16.
        /// </summary>
        /// <param name="time"></param>
        /// <param name="geocentricLonlatDeg"></param>
        /// <returns></returns>
        public RmsedNumeral Get(Time time, LonLat geocentricLonlatDeg)
        {
            double bufferedTime = 2 * 3600;

            this.TimePeriod.SetSameBuffer(bufferedTime);
            if (!TimePeriod.BufferedContains(time))
            {
                log.Error(Name + " 不在有效服务时段内。 " + TimePeriod + ", " + time);
                return(null);

                throw new ApplicationException();
            }

            List <Time> times = TimeUtil.GetNearst(this.IonoFile.Keys, time);

            if (times.Count == 1)//刚好,或在边界,无需拟合
            {
                return(Interpolate(this.IonoFile.Get(times[0]), geocentricLonlatDeg));
            }
            else if (times.Count >= 3)//需要拟合
            {
                var         smallTime  = times[1];
                var         largerTime = times[2];
                IonoSection regoin1    = this.IonoFile.Get(smallTime);
                IonoSection regoin2    = this.IonoFile.Get(largerTime);


                var val1 = Interpolate(regoin1, geocentricLonlatDeg);
                var val2 = Interpolate(regoin2, geocentricLonlatDeg);
                var t    = time.TickTime.SecondsOfWeek;
                var t1   = smallTime.TickTime.SecondsOfWeek;
                var t2   = largerTime.TickTime.SecondsOfWeek;

                if (t2 == 0)
                {
                    t2 = SecondTime.SECOND_PER_WEEK;// 3600 * 24 * 7;
                }

                var val = Geo.Utils.DoubleUtil.Interpolate(t, t1, t2, val1.Value, val2.Value);
                var rms = Geo.Utils.DoubleUtil.Interpolate(t, t1, t2, val1.Rms, val2.Rms);

                return(new RmsedNumeral(val, rms));
            }

            IonoSection   regoin = this.IonoFile.Get(times[0]);
            List <double> lats   = Geo.Utils.DoubleUtil.GetNearst(regoin.Keys, geocentricLonlatDeg.Lat, false);

            IonoRecord    record = regoin.Get(lats[0]);
            List <double> lons   = Geo.Utils.DoubleUtil.GetNearst(record.Keys, geocentricLonlatDeg.Lon, false);

            return(record[lons[0]]);
        }
Example #2
0
        /// <summary>
        /// 内插不同经纬度的值。
        /// </summary>
        /// <param name="IonoSection"></param>
        /// <param name="geoCoord">待内插坐标</param>
        /// <returns></returns>
        public RmsedNumeral Interpolate(IonoSection IonoSection, LonLat geoCoord)
        {
            List <double> lats = Geo.Utils.DoubleUtil.GetNearst(IonoSection.Keys, geoCoord.Lat, false);

            if (lats.Count == 1)//在指定的纬度圈上面
            {
                var           lat    = lats[0];
                IonoRecord    record = IonoSection.Get(lat);
                List <double> lons   = Geo.Utils.DoubleUtil.GetNearst(record.Keys, geoCoord.Lon, false);
                if (lons.Count == 1) //刚好,找到你了,不用差值
                {
                    var lon = lons[0];
                    return(record[lon]);
                }
                else if (lons.Count == 3)//差值
                {
                    var lon1 = lons[1];
                    var lon2 = lons[2];
                    var val1 = record[lon1];
                    var val2 = record[lon2];
                    var val  = Geo.Utils.DoubleUtil.Interpolate(geoCoord.Lon, lon1, lon2, val1.Value, val2.Value);
                    var rms  = Geo.Utils.DoubleUtil.Interpolate(geoCoord.Lon, lon1, lon2, val1.Rms, val2.Rms);
                    return(new RmsedNumeral(val, rms));
                }
                else
                {
                    throw new Exception("内插错误,获取经度值失败");
                }
            }
            else if (lats.Count == 3)
            {
                var lat1 = lats[1];
                var lat2 = lats[2];

                IonoRecord record1 = IonoSection.Get(lat1);
                IonoRecord record2 = IonoSection.Get(lat2);

                var           lat    = lats[0];
                IonoRecord    record = IonoSection.Get(lat);
                List <double> lons   = Geo.Utils.DoubleUtil.GetNearst(record1.Keys, geoCoord.Lon, false);

                if (lons.Count == 1)
                {
                    var lon  = lons[0];
                    var val0 = record1[lon];
                    var val1 = record2[lon];
                    var val  = Geo.Utils.DoubleUtil.Interpolate(geoCoord.Lat, lat1, lat2, val0.Value, val1.Value);
                    var rms  = Geo.Utils.DoubleUtil.Interpolate(geoCoord.Lat, lat1, lat2, val0.Rms, val1.Rms);
                    return(new RmsedNumeral(val, rms));
                }
                else if (lons.Count >= 3)
                {
                    var lon1 = lons[1];
                    var lon2 = lons[2];

                    var val11 = record1[lon1];
                    var val12 = record1[lon2];
                    var val21 = record2[lon1];
                    var val22 = record2[lon2];


                    var val = Geo.Utils.DoubleUtil.Interpolate(geoCoord.Lon, geoCoord.Lat, lon1, lon2, lat1, lat2, val11.Value, val12.Value, val21.Value, val22.Value);
                    var rms = Geo.Utils.DoubleUtil.Interpolate(geoCoord.Lon, geoCoord.Lat, lon1, lon2, lat1, lat2, val11.Rms, val12.Rms, val21.Rms, val22.Rms);
                    return(new RmsedNumeral(val, rms));
                }
            }
            else
            {
                throw new Exception("内插错误,获取值纬度失败");
            }
            throw new Exception("内插错误,不可能出现");
        }
Example #3
0
        /// <summary>
        /// 读取历元对象
        /// </summary>
        /// <param name="Header"></param>
        /// <param name="StreamReader"></param>
        /// <returns></returns>
        private IonoSection ReadSection(IonoFile ionoFile, IonoHeader Header, StreamReader StreamReader)
        {
            string line         = StreamReader.ReadLine();
            var    isValueOrRms = (IsStartLineOfEpochMapSection(line));

            if (isValueOrRms)
            {
                IsCurrentValueOrRms = true;
                return(ReadSection(ionoFile, Header, StreamReader));
            }
            isValueOrRms = !(IsStartLineOfRmsEpochMapSection(line));


            while (!IsFirstLineOfEpochMapSectionWithTime(line))
            {
                line = StreamReader.ReadLine();
                if (line == null)
                {
                    return(null);
                }
                if (line.Length > 60 && line.Substring(60).Trim() == RinexHeaderLabel.END_OF_FILE)
                {
                    return(null);
                }
            }
            IonoSection IonoSection = null;
            var         time        = this.ParseTime(line);

            if (ionoFile.Contains(time))
            {
                IonoSection = ionoFile[time];
            }
            else
            {
                IonoSection = new IonoSection()
                {
                    Header = Header, Time = time
                };
            }
            while ((line = StreamReader.ReadLine()) != null && IsStartOfRecord(line) && !IsEndLineOfEpochMapSection(line))
            {
                var        lat    = double.Parse(line.Substring(2, 6));
                IonoRecord record = null;
                if (IonoSection.Contains(lat))
                {
                    record = IonoSection[lat];
                }
                else
                {
                    record = new IonoRecord()
                    {
                        LonRange = new IncreaseValue
                        {
                            Start      = double.Parse(line.Substring(8, 6)),
                            End        = double.Parse(line.Substring(14, 6)),
                            Increament = double.Parse(line.Substring(20, 6)),
                        },
                        Height = double.Parse(line.Substring(26, 6)),
                        Lat    = lat,
                    };
                }
                double        lineCount = Math.Ceiling(record.LonRange.Count / 16.0);
                List <double> vals      = new List <double>();
                for (int i = 0; i < lineCount; i++)
                {
                    line = StreamReader.ReadLine();
                    var items = StringUtil.Split(line, 5);
                    foreach (var item in items)
                    {
                        if (String.IsNullOrWhiteSpace(item))
                        {
                            continue;
                        }
                        vals.Add(StringUtil.ParseDouble(item));
                    }
                }
                for (int i = 0; i < vals.Count; i++)
                {
                    //TEC values in 0.1 TECU(10^16)
                    double val = vals[i];
                    if (Header.Exponent == 0)
                    {
                        val *= 0.1;
                    }
                    else
                    {
                        val *= Math.Pow(10, Header.Exponent);
                    }
                    var alat = record.LonRange.Start + i * record.LonRange.Increament;
                    if (record.Contains(alat))
                    {
                        record[alat].Rms = val;
                    }
                    else
                    {
                        record.Add(alat, new RmsedNumeral(val, Double.NaN));
                    }
                }

                IonoSection[lat] = record;
            }

            if (isValueOrRms)
            {
                ionoFile[time] = IonoSection;
                return(ReadSection(ionoFile, Header, StreamReader));
            }

            return(IonoSection);
        }