コード例 #1
0
        /// <summary>
        /// 获取卫星在指定时刻,相对于测站的信息
        /// </summary>
        /// <param name="service"></param>
        /// <param name="prn"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        public StationSatInfo GetInstantSatInfo(IEphemerisService service, SatelliteNumber prn, Time time)
        {
            Geo.Coordinates.XYZ satPos = service.Get(prn, time).XYZ;
            GeoCoord            coord  = CoordTransformer.XyzToGeoCoord(satPos);

            Geo.Coordinates.Polar p = CoordTransformer.XyzToGeoPolar(satPos, StationPos);
            if (p.Elevation < EleAngle)
            {
                return(null);
            }

            this.LonLats.Add(new Vector(coord.Lon, coord.Lat)
            {
                Tag = prn.ToString()
            });

            //显示到表格
            return(new StationSatInfo()
            {
                PRN = prn,
                Time = time,
                Azimuth = p.Azimuth,
                ElevatAngle = p.Elevation,
                Distance = p.Range,
                Lat = coord.Lat,
                Lon = coord.Lon,
                Height = coord.Height,
                X = satPos.X,
                Y = satPos.Y,
                Z = satPos.Z
            });
        }
コード例 #2
0
ファイル: EphemerisParam.cs プロジェクト: yxw027/GNSSer
        public Ephemeris GetEphemerisInfo(Time gpsTime, XYZ staXyz, bool IsDualFreq = false)
        {
            double dt, dtr, clockOffSet;

            //*** correct satellite time
            dt          = SatSvClock_NonRelative(gpsTime.SecondsOfWeek);              //*** icd-200 20.3.3.3.3.1
            dtr         = SatSvClock_Relative(gpsTime.SecondsOfWeek, dt);
            clockOffSet = dt + dtr;

            //*** icd-200 20.3.3.3.3.2  (not dual freq)
            //*** old version below
            //*** if( (!myModes.IsDualFreq()) && (!myModes.IsIon())) svClock = svClock - tgd;

            //*** 2006july28 notes
            //*** DOD does NOT apply sat P1P2 DCB correction (Tgd) to broadcast clocks
            //*** IGS does NOT apply sat P1P2 DCB corrections to their clocks "by agreed convention"
            //*** thus, sat P1P2 DCB must be applied to DoD/IGS clocks if single freq.
            //*** this is same convention as icd-200 20.3.3.3.3.2
            //*** this has NOTHING to do with use of any kind of normals ionosphere model
            //*** its purpose is undoing the disseminated svClock biases by means of
            //***    uncorrected (by DCB's) pseudorange ionosphere estimates

            if (!IsDualFreq)
            {
                clockOffSet = clockOffSet - TGD;
            }

            //*** compute broadcast position at corrected time

            Geo.Coordinates.XYZ xyz = GetSatXyz(gpsTime.SecondsOfWeek - clockOffSet, this.Prn);



            var state = OrbitUtil.GetPosXYZ(this, gpsTime.SecondsOfWeek - clockOffSet);


            return(new Ephemeris
            {
                XYZ = state.Value,
                ClockBias = clockOffSet,
                RelativeCorrection = dtr,
                Prn = this.Prn,
                Time = gpsTime,
                ClockDrift = ClockDrift,
                XyzDot = state.Rms
            });
        }
コード例 #3
0
 /// <summary>
 /// 构造函数
 /// </summary>
 public Ephemeris()
 {
     XYZ = new Geo.Coordinates.XYZ(); XyzDot = new Geo.Coordinates.XYZ();
 }
コード例 #4
0
        /// <summary>
        /// 获取插值后的 EphemerisInfo。
        /// 注意:不对钟差相对论误差进行改正,此处时间是卫星钟时间,没有相对信息。2014.09.08
        /// 失败,如超过时间,则返回null
        /// 由于一般没有卫星速度的数据,必须通过插值坐标计算速度。2015.03.
        /// 如果有速度信息,以下的方法就不合适了。
        /// </summary>
        /// <param name="gpsTime">时间</param>
        /// <returns></returns>
        public Ephemeris GetEphemerisInfo(Time gpsTime)
        {
            SatelliteNumber PRN       = sortedRecords[0].Prn;
            Time            min       = sortedRecords[0].Time;
            Time            max       = sortedRecords[sortedRecords.Count - 1].Time;
            double          span      = (double)(max - min);
            double          gpsSecond = (gpsTime - min); //减去序列中第一个数
            //老是在这里出问题,宽限一点呢??16分钟
            double expand = 60 * 16;

            if (gpsSecond + expand < 0 || gpsSecond - expand > span)
            {
                //return null;
                throw new ArgumentException("历元在给定的时间段外,不可进行插值。");
            }
            //计算位置
            double x = 0, y = 0, z = 0; double dtime = 0;
            double dx = 0, dy = 0, dz = 0; double ddtime = 0;


            int count = sortedRecords.Count;
            int order = 10;

            order = Math.Min(order, count);

            //czs
            //   List<int> indexes = GetNearstIndexes(sortedRecords, gpsSecond, order);
            //cy
            List <int> indexes = GetNearstIndexes(sortedRecords, gpsTime, order);


            double[] t     = new double[order + 1];
            double[] tList = new double[order + 1];

            double[] xList     = new double[order + 1];
            double[] yList     = new double[order + 1];
            double[] zList     = new double[order + 1];
            double[] clockList = new double[order + 1];

            int i = 0;

            foreach (var item in indexes)
            {
                Ephemeris record = sortedRecords[item];

                t[i] = (record.Time - gpsTime);  //秒。


                #region 方案1:顾及地球自转效应
                //correction for earth rotation
                double sinl = Math.Sin(SunMoonPosition.OMGE * t[i]);
                double cosl = Math.Cos(SunMoonPosition.OMGE * t[i]);

                xList[i] = cosl * record.XYZ.X - sinl * record.XYZ.Y;
                yList[i] = sinl * record.XYZ.X + cosl * record.XYZ.Y;
                zList[i] = record.XYZ.Z;
                #endregion


                #region 方案2:不顾及地球自转效应

                //xList[time] = record.XYZ.X;
                //yList[time] = record.XYZ.Y;
                //zList[time] = record.XYZ.Z;

                #endregion

                tList[i]     = (record.Time - sortedRecords[0].Time); //秒。
                clockList[i] = record.ClockBias;

                i++;
            }


            Lagrange(tList, xList, gpsSecond, ref x, ref dx);

            Lagrange(tList, yList, gpsSecond, ref y, ref dy);

            Lagrange(tList, zList, gpsSecond, ref z, ref dz);

            Lagrange(tList, clockList, gpsSecond, ref dtime, ref ddtime);

            int Nhalf  = (int)(order / 2) - 1;
            int Nmatch = indexes[Nhalf];

            //fitX.GetYdY(gpsSecond, ref x, ref dx);
            //fitY.GetYdY(gpsSecond, ref y, ref dy);
            //fitZ.GetYdY(gpsSecond, ref z, ref dz);
            //fitClock.GetYdY(gpsSecond, ref dtime, ref ddtime);

            XYZ SatXyz = new XYZ(x, y, z);


            if (!SatXyz.IsValid)
            {
                throw new Exception("插值失败!");
            }

            //精度赋值
            XYZ    SatXyzSig    = sortedRecords[Nmatch].Rms;
            double clockSig     = sortedRecords[Nmatch].ClockBiasRms;
            XYZ    SatXyzDotSig = new Geo.Coordinates.XYZ(0);

            //计算速度
            //double nextSecond = gpsSecond + 0.001;
            //XYZ xyzNext = new XYZ(fitX.GetY(nextSecond), fitY.GetY(nextSecond), fitZ.GetY(nextSecond));
            //XYZ speed = (xyzNext-xyz) / 0.001;


            XYZ SatSpeed = new XYZ(dx, dy, dz);

            //Add relativity correction to dtime
            //This only for consistency with GPSEphemerisInter
            //dtr=-2*dot(R,V)/(C*C)

            //dtime +=EphemerisUtil.GetRelativeCorrection(SatXyz, SatSpeed);

            return(new Ephemeris()
            {
                Prn = PRN,
                XYZ = SatXyz,
                Rms = SatXyzSig,
                // Clock = fitClock.GetY(gpsSecond),
                ClockBias = dtime,
                ClockBiasRms = clockSig,
                ClockDrift = ddtime,
                Time = gpsTime,
                XyzDot = SatSpeed,
                XyzDotRms = SatXyzDotSig
            });
        }
コード例 #5
0
ファイル: TimedMotionState.cs プロジェクト: yxw027/GNSSer
 /// <summary>
 /// Creates an instance of the class with the given position, velocity, and time.
 /// </summary>
 /// <param name="pos">The position vector.</param>
 /// <param name="vel">The velocity vector.</param>
 /// <param name="date">The time associated with the position.</param>
 public TimedMotionState(XYZ pos, XYZ vel, Julian date)
     : base(pos, vel)
 {
     Date = date;
 }
コード例 #6
0
        /// <summary>
        /// 指定时段内,可以看见的卫星。
        /// </summary>
        /// <returns></returns>
        public List <VisibilityOfSat> GetPeriodSatAppearTimes()
        {
            this.LonLats.Clear();
            List <VisibilityOfSat> sats  = new List <VisibilityOfSat>();
            List <StationSatInfo>  infos = new List <StationSatInfo>();
            List <SatelliteNumber> prns  = new List <SatelliteNumber>();

            //  EphemerisService.EphemerisDataSource.GetEphemerisInfos(
            foreach (SatelliteNumber rec in EphemerisService.Prns)//卫星一颗一颗的算
            {
                if (prns.Contains(rec))
                {
                    continue;
                }
                prns.Add(rec);

                VisibilityOfSat satA = new VisibilityOfSat()
                {
                    PRN = rec, VisibleTimes = new List <BufferedTimePeriod>()
                };
                sats.Add(satA);
                Polar lastP = null;

                DateTime f = DateTime.MinValue;
                for (int i = 0; i < Count; i++)
                {
                    DateTime            time  = From + TimeSpan.FromMinutes(i * SpanMinutes);
                    Time                g     = new Time(time);
                    Geo.Coordinates.XYZ xyz   = EphemerisService.Get(rec, g).XYZ;
                    GeoCoord            coord = CoordTransformer.XyzToGeoCoord(xyz);
                    Polar               p     = CoordTransformer.XyzToGeoPolar(xyz, StationPos);

                    if (lastP == null)
                    {
                        lastP = p; continue;
                    }

                    if (p.Elevation >= EleAngle)
                    {
                        if (f.Equals(DateTime.MinValue) || lastP.Elevation < EleAngle)
                        {
                            f     = time;
                            lastP = p;
                            continue;
                        }
                    }
                    if (p.Elevation < EleAngle || i == Count - 1)                       //当前小于指定高度角
                    {
                        if (!f.Equals(DateTime.MinValue) && lastP.Elevation > EleAngle) //且上一个时刻是大于的,则终端出现了。
                        {
                            BufferedTimePeriod s = new BufferedTimePeriod(f, time);
                            satA.VisibleTimes.Add(s);
                            this.LonLats.Add(new Vector(coord.Lon, coord.Lat)
                            {
                                Tag = rec.PRN.ToString()
                            });
                        }
                    }
                    lastP = p;
                }
            }
            sats.Sort();

            return(sats);
        }
コード例 #7
0
ファイル: XyzFrameConverter.cs プロジェクト: yxw027/GNSSer
 /// <summary>
 /// 默认构造函数
 /// </summary>
 /// <param name="Offset"></param>
 /// <param name="RotationAngleSecond"></param>
 /// <param name="ScaleFactorPpm"></param>
 public XyzFrameConvertParam(XYZ Offset, XYZ RotationAngleSecond, double ScaleFactorPpm)
 {
     this.Offset = Offset;
     this.RotationAngleSecond = RotationAngleSecond;
     this.ScaleFactorPpm      = ScaleFactorPpm;
 }
コード例 #8
0
ファイル: XyzFrameConverter.cs プロジェクト: yxw027/GNSSer
 /// <summary>
 /// 转换
 /// </summary>
 /// <param name="old"></param>
 /// <returns></returns>
 public XYZ Convert(XYZ old)
 {
     return(CoordinateTransform(old, ConvertParam));
 }