/*time to day of year*/ public static double time2doy(rtktime t) { double[] ep = new double[6]; time2epoch(t, ep); ep[1] = ep[2] = 1.0; ep[3] = ep[4] = ep[5] = 0.0; return(timediff(t, epoch2time(ep)) / 86400.0 + 1.0); }
public static void time2epoch(rtktime t, double[] ep) { int[] mday = /* # of days in a month */ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int days, sec, mon, day; /* leap year if year%4==0 in 1901-2099 */ days = (int)(t.time_int / 86400); sec = (int)(t.time_int - (Int64)days * 86400); for (day = days % 1461, mon = 0; mon < 48; mon++) { if (day >= mday[mon]) { day -= mday[mon]; } else { break; } } ep[0] = 1970 + days / 1461 * 4 + mon / 12; ep[1] = mon % 12 + 1; ep[2] = day + 1; ep[3] = sec / 3600; ep[4] = sec % 3600 / 60; ep[5] = sec % 60 + t.sec; }
public static void tidedisp(time tutc, rtktime utc, double[] rr, erp_t erp, double[] disp) { time tut = new time(); rtktime ut = new rtktime(); double[] pos = new double[2], E = new double[9], erpv = new double[5], rs = new double[3], rm = new double[3]; double[] gmst = new double[1], drt = new double[3]; double r; if (erp != null) { pppcmn.geterp(tutc, utc, erp, erpv); } tut.ut1 = tutc.utc + erpv[2]; ut = rtklibcmn.timeadd(utc, erpv[2]); r = Math.Sqrt(rr[0] * rr[0] + rr[1] * rr[1] + rr[2] * rr[2]); if (r <= 0) { return; } pos[0] = Math.Asin(rr[2] / r); pos[1] = Math.Atan2(rr[1], rr[0]); transcoor.mat_xyz2enu(matrix.Array2matrix(pos), E); pppcmn.sunmoonpos(tutc, utc, erpv, rs, rm, gmst); pppcmn.tide_solid(rs, rm, pos, E, gmst[0], drt); for (int i = 0; i < 3; i++) { disp[i] += drt[i]; } }
/* time to day and sec -------------------------------------------------------*/ public static double time2sec(rtktime t, rtktime day) { double[] ep = new double[6]; double sec; time2epoch(t, ep);//转化为 y m d h m s sec = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5]; ep[3] = ep[4] = ep[5] = 0.0; day = epoch2time(ep); return(sec); }
public static rtktime gpst2time(int week, double sec) { rtktime t = epoch2time(gpst0); if (sec < -1E9 || 1E9 < sec) { sec = 0.0; } t.time_int += 86400 * 7 * week + (int)sec; t.sec = sec - (int)sec; return(t); }
public static double time2gpst(rtktime t, int[] week) { rtktime t0 = epoch2time(gpst0); Int64 sec = t.time_int - t0.time_int; int w = (int)(sec / (86400 * 7)); if (week != null) { week[0] = w; } return((double)(sec - w * 86400 * 7) + t.sec); }
public static rtktime utc2gpst(rtktime t) { int i; for (i = 0; leaps[i][0] > 0; i++) { if (timediff(t, epoch2time(leaps[i])) >= 0.0) { return(timeadd(t, -leaps[i][6])); } } return(t); }
public static rtktime adjweek(rtktime t, rtktime t0) { double tt = timediff(t, t0);//返回这两个时间所相差的秒数,t.sec是表示小于1秒的小数(double),time_t是整形 if (tt < -302400.0) { return(timeadd(t, 604800.0)); } if (tt > 302400.0) { return(timeadd(t, -604800.0)); } return(t); }
public static rtktime timeadd(rtktime t, double sec) { double tt; rtktime tep = new rtktime(); tep.time_int = t.time_int; tep.sec = t.sec; tep.sec += sec; tt = Math.Floor(tep.sec); tep.time_int += (int)tt; tep.sec -= tt; return(tep); }
public static rtktime gpst2utc(rtktime t) { rtktime tu = new rtktime(); int i; for (i = 0; leaps[i][0] > 0; i++) { tu = timeadd(t, leaps[i][6]);//加上跳秒 if (timediff(tu, epoch2time(leaps[i])) >= 0.0) { return(tu); } } return(t); }
/* utc to gmst ----------------------------------------------------------------- * convert utc to gmst (Greenwich mean sidereal time) * args : gtime_t t I time expressed in utc * double ut1_utc I UT1-UTC (s) * return : gmst (rad) *-----------------------------------------------------------------------------*/ public static double utc2gmst(rtktime t, double ut1_utc) { double[] ep2000 = { 2000, 1, 1, 12, 0, 0 }; rtktime tut = new rtktime(), tut0 = new rtktime(); double ut, t1, t2, t3, gmst0, gmst; tut = timeadd(t, ut1_utc);//这里的t是UTC表示 ut = time2sec(tut, tut0); t1 = timediff(tut0, epoch2time(ep2000)) / 86400.0 / 36525.0; t2 = t1 * t1; t3 = t2 * t1; gmst0 = 24110.54841 + 8640184.812866 * t1 + 0.093104 * t2 - 6.2E-6 * t3; gmst = gmst0 + 1.002737909350795 * ut; return((gmst % 86400.0) * Math.PI / 43200.0); /* 0 <= gmst <= 2*PI fmod函数在c#中可用%代替*/ }
public static void str2time(string line, rtktime t) { double[] ep = new double[6]; string[] s = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < 6; i++) { ep[i] = double.Parse(s[i]); } if (ep[0] < 100.0) { ep[0] += ep[0] < 80.0 ? 2000.0 : 1900.0; } rtktime t1 = epoch2time(ep); t.time_int = t1.time_int; t.sec = t1.sec; }
/* convert calendar day/time to time ------------------------------------------- * convert calendar day/time to gtime_t struct * args : double *ep I day/time {year,month,day,hour,min,sec} * return : gtime_t struct * notes : proper in 1970-2037 or 1970-2099 (64bit time_t) *-----------------------------------------------------------------------------*/ public static rtktime epoch2time(double[] ep) { int[] doy = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; rtktime time = new rtktime(); int days, sec, year = (int)ep[0], mon = (int)ep[1], day = (int)ep[2]; if (year < 1970 || 2099 < year || mon < 1 || 12 < mon) { return(time); } /* leap year if year%4==0 in 1901-2099 */ days = (year - 1970) * 365 + (year - 1969) / 4 + doy[mon - 1] + day - 2 + (year % 4 == 0 && mon >= 3 ? 1 : 0); sec = (int)Math.Floor(ep[5]); time.time_int = (Int64)days * 86400 + (int)ep[3] * 3600 + (int)ep[4] * 60 + sec; time.sec = ep[5] - sec; return(time); }
public static void propos(obs_t obss, dcb_t dcb, pcv_t pcv, station sta, nav_t nav, erp_t erp, List <result> res, RichTextBox text) { int nobs = 0; rtktime solt = new rtktime(); string timestr = null; obs_t obs = new obs_t(); ppp_t p3 = new ppp_t(); spp_t spp = new spp_t(); while ((nobs = inputobs(obs, obss)) > 0) { result re = new result(); solt = spp.tcur; if (pntpos(obs.obs_b, nav, spp, dcb) == 0) { continue; } p3.spp = spp; p3.soltime = spp.tcur; if (solt.time_int != 0) { p3.tt = rtklibcmn.timediff(p3.soltime, solt); } if (pppos(p3, obs.obs_b, nav, dcb, sta, erp) != 1) { continue; } for (int j = 0; j < 3; j++) { spp.rr[j] = p3.x[j]; } spp.dtr = p3.x[4]; re.time = obs.obs_b[0].t.calend; re.X = p3.x[0]; re.Y = p3.x[1]; re.Z = p3.x[2]; timestr = re.time[0] + "/" + re.time[1] + "/" + re.time[2] + " " + re.time[3] + ":" + re.time[4] + ":" + re.time[5]; text.AppendText(string.Format("{0,-20}", timestr) + string.Format("{0,-20}", re.X) + string.Format("{0,-20}", re.Y) + string.Format("{0,-20}", re.Z) + "\r\n"); res.Add(re); } }
const double CLIGHT = 299792458.0; /* speed of light (m/s) */ /*读取观测值文件 支持ver 2.11*/ public static int readobs(string path, obs_t obs, station sta) { using (StreamReader sr = new StreamReader(path)) { if (readobsh(sr, obs, sta) == 1 && (sta.ver < 3 && sta.ver > 0)) { string line = ""; while (!sr.EndOfStream) { time tcurrent = new time(); string[] sprn = new string[64]; rtktime rtktcur = new rtktime(); int ns = 0; //每个历元观测到的卫星数 line = sr.ReadLine(); if (line != null) //读取含历元时间信息和卫星数的一行 { tcurrent = new time(line.Substring(0, 26), "o"); //读取时间信息 rtklibcmn.str2time(line.Substring(0, 26), rtktcur); ns = int.Parse(line.Substring(29, 3)); //读取当前历元观测到的卫星数 sprn = new string[ns]; //卫星prn for (int i = 0, j = 32; i < ns; i++, j += 3) { if (j >= 68) { line = sr.ReadLine(); j = 32; } sprn[i] = line.Substring(j, 3); } } for (int i = 0; i < ns; i++)//读取每个卫星相应的观测值 { obs_s sat = new obs_s(); sat.t = tcurrent; sat.rtkt = rtktcur; sat.sprn = sprn[i]; line = sr.ReadLine(); for (int k = 0, j = 0; k < obs.ntype; k++, j += 16)//读取一颗卫星的所有观测值信息 { obssat obsat = new obssat(); if (j >= 80) { line = sr.ReadLine(); j = 0; } obsat.type = obs.obstype[k]; if (j >= line.Length) { obsat.value = 0; } else { if (line.Substring(j, 14).Trim() == "") { obsat.value = 0; } else { obsat.value = double.Parse(line.Substring(j, 14)); } } sat.type_value.Add(obsat); } obs.obs_b.Add(sat); } obs.n += ns; } return(1); } else { return(0); } } }
/*读取IGS精密星历*/ public static int readsp3(string path, sp3_t sp3) { using (StreamReader sr = new StreamReader(path)) { double value = 0.0, std = 0.0, ba; double[] bfact = new double[2]; int flag = 0; string line = ""; for (int i = 0; i < 22; i++)//IGS { line = sr.ReadLine(); if (i == 2) { sp3.ns = int.Parse(line.Substring(4, 2)); } if (i == 14) { bfact[0] = str2num(line, 3, 10); bfact[1] = str2num(line, 14, 12); } } if (sp3.ns == 0) { return(0); } while (!sr.EndOfStream) { time t1 = new time(); rtktime rtkt1 = new rtktime(); line = sr.ReadLine(); if (line.Contains("EOF")) { break; } if (line.Contains("*")) { t1 = new time(line, "sp3"); rtklibcmn.str2time(line.Substring(1), rtkt1); } for (int i = 0; i < sp3.ns; i++) { sp3b sb = new sp3b(); sb.t = t1; sb.rtkt = rtkt1; line = sr.ReadLine(); if (line.Substring(1, 1) == "G" && line.Substring(0, 1) == "P")//只读取GPS卫星 { sb.prn = line.Substring(1, 3); for (int j = 0; j < 4; j++) { value = str2num(line, 4 + j * 14, 14); std = str2num(line, 61 + j * 3, j < 3 ? 2 : 3); if (value != 0 && Math.Abs(value - 999999.999999) >= 1E-6)//读取卫星XYZ坐标,单位为米 { sb.xyzt[j] = value * (j < 3 ? 1000.0 : 1E-6); } if ((ba = bfact[j < 3 ? 0 : 1]) > 0.0 && std > 0.0) { sb.std[j] = Math.Pow(ba, std) * (j < 3 ? 1E-3 : 1E-12); } } } sp3.sp3_b.Add(sb); } } return(flag); } }
public static double timediff(rtktime t1, rtktime t2) { return(t1.time_int - t2.time_int + t1.sec - t2.sec); }
/*由广播星历计算的电离层模型,克布罗歇模型*/ public static double ionmodel(time t, rtktime rtkt, double[] alpha, double[] bela, double[] pos, double[] azel)//由广播星历计算的电离层模型,克布罗歇模型 { double[] ion_default = new double[8] { 0.1118E-07, -0.7451E-08, -0.5961E-07, 0.1192E-06, 0.1167E+06, -0.2294E+06, -0.1311E+06, 0.1049E+07 }; double tt, f, psi, phi, lam, amp, per, x; int i; if (pos[2] < -1E3 || azel[1] <= 0) { return(0.0); } for (i = 0; i < 4; i++) { if (alpha[i] != 0 || bela[i] != 0) { break; } } if (i < 4) { for (int j = 0; j < 4; j++) { ion_default[j] = alpha[j]; ion_default[j + 4] = bela[j]; } } /* earth centered angle (semi-circle) */ psi = 0.0137 / (azel[1] / Math.PI + 0.11) - 0.022; /* subionospheric latitude/longitude (semi-circle) */ phi = pos[0] / Math.PI + psi * Math.Cos(azel[0]); if (phi > 0.416) { phi = 0.416; } else if (phi < -0.416) { phi = -0.416; } lam = pos[1] / Math.PI + psi * Math.Sin(azel[0]) / Math.Cos(phi * Math.PI); /* geomagnetic latitude (semi-circle) */ phi += 0.064 * Math.Cos((lam - 1.617) * Math.PI); /* local time (s) */ //tt = 43200.0 * lam + time2gpst(t, &week); tt = 43200.0 * lam + rtklibcmn.time2gpst(rtkt, null); tt -= Math.Floor(tt / 86400.0) * 86400.0; /* 0<=tt<86400 */ /* slant factor */ f = 1.0 + 16.0 * Math.Pow(0.53 - azel[1] / Math.PI, 3.0); /* ionospheric delay */ amp = ion_default[0] + phi * (ion_default[1] + phi * (ion_default[2] + phi * ion_default[3])); per = ion_default[4] + phi * (ion_default[5] + phi * (ion_default[6] + phi * ion_default[7])); amp = amp < 0.0 ? 0.0 : amp; per = per < 72000.0 ? 72000.0 : per; x = 2.0 * Math.PI * (tt - 50400.0) / per; return(CLIGHT * f * (Math.Abs(x) < 1.57 ? 5E-9 + amp * (1.0 + x * x * (-0.5 + x * x / 24.0)) : 5E-9)); }
/*电离层改正用于标准单点定位*/ public static int ioncorr(time t, rtktime rtkt, nav_t nav, double[] pos, double[] azel, double[] ion) { ion[0] = ionmodel(t, rtkt, nav.alpha, nav.beta, pos, azel); ion[1] = Math.Pow(ion[0] * ERR_BRDCI, 2); return(1); }