//------------------------------------------------------------------------------------ int OpenFiles(void) throw(Exception) { try { string filename; if(InputDirectory.empty()) filename = NovatelFile; else filename = InputDirectory + string("/") + NovatelFile; instr.open(filename.c_str(),ios::in | ios::binary); if(!instr.is_open()) { cerr << "Failed to open input file " << NovatelFile << endl; return -1; } if(verbose) cout << "Opened input file " << NovatelFile << endl; instr.exceptions(fstream::failbit); TempFileName = GetTempFileName(); rostr.open(TempFileName.c_str(),ios::out); if(!rostr.is_open()) { cerr << "Failed to open temporary output file " << TempFileName << endl; return -2; } rostr.exceptions(fstream::failbit); rnstr.open(RinexNavFile.c_str(),ios::out); if(!rnstr.is_open()) { cerr << "Failed to open output nav file " << RinexNavFile << endl; return -3; } if(verbose) cout << "Opened output nav file " << RinexNavFile << endl; rnstr.exceptions(fstream::failbit); return 0; } catch(Exception& e) { GPSTK_RETHROW(e); } catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); } catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); } }
//------------------------------------------------------------------------------------ // Returns 0 when successful. int main(int argc, char *argv[]) { if (argc<2) { cout << "Usage: NavMerge [options] <RINEX nav file name(s)>\n" " Options are:\n" " [-o|--out] <file> Output RINEX navigation file name. If omitted, a data summary is displayed.\n" " [-tb|--begTime] <tb> Output data only if epoch is within 4 hours of the interval (tb,te).\n" " [-te|--endTime] <te> If one of (te,tb) is omitted, they are made equal.\n" " Times are either 'year,mon,day,hr,min,sec' or 'GPSweek,secOfWeek'\n" " NB. NavMerge corrects data for output when GPS full week number is inconsistent with epoch time.\n" ; return -1; } try { int i; string arg,filename,outfile,YMDformat("%Y,%m,%d,%H,%M,%f"),GPSformat("%F,%g"); DayTime tb,te; te = tb = DayTime::BEGINNING_OF_TIME; i = 1; while(i < argc) { arg = string(argv[i]); if(arg == "--out" || arg.substr(0,2) == "-o") { if(arg == "--out") { argv[i][0] = '\0'; if(++i == argc) { BadArg(arg); break; } outfile = string(argv[i]); } else outfile = arg.substr(2); cout << "Output file name is " << outfile << endl; argv[i][0] = '\0'; } else if(arg == "--begTime" || arg == "-tb" || arg.substr(0,3) == "-tb") { if(arg.substr(0,3) == "-tb" && arg.size() > 3) arg = arg.substr(3); else { argv[i][0] = '\0'; if(++i == argc) { BadArg(arg); break; } arg = string(argv[i]); } if(numWords(arg,',') == 2) tb.setToString(arg,GPSformat); else if(numWords(arg,',') == 6) tb.setToString(arg,YMDformat); else cout << "Unable to understand timetag option: " << arg << endl; argv[i][0] = '\0'; } else if(arg == "--endTime" || arg == "-te" || arg.substr(0,3) == "-te") { if(arg.substr(0,3) == "-te" && arg.size() > 3) arg = arg.substr(3); else { argv[i][0] = '\0'; if(++i == argc) { BadArg(arg); break; } arg = string(argv[i]); } if(numWords(arg,',') == 2) te.setToString(arg,GPSformat); else if(numWords(arg,',') == 6) te.setToString(arg,YMDformat); else cout << "Unable to understand timetag option: " << arg << endl; argv[i][0] = '\0'; } i++; } if(te != DayTime::BEGINNING_OF_TIME && tb == DayTime::BEGINNING_OF_TIME) tb = te; else if(tb != DayTime::BEGINNING_OF_TIME && te == DayTime::BEGINNING_OF_TIME) te = tb; if(tb > te) { DayTime tt=tb; tb=te; te=tt; } if(tb != DayTime::BEGINNING_OF_TIME) cout << "Time limits are " << tb.printf(YMDformat) << " - " << te.printf(YMDformat) << endl; RinexNavHeader rnh,rnhout; RinexNavData rne; GPSEphemerisStore EphStore; RinexNavStream RNFileOut; if(outfile != string("")) { RNFileOut.open(outfile.c_str(),ios::out); RNFileOut.exceptions(fstream::failbit); rnhout.version = 2.1; rnhout.valid |= RinexNavHeader::versionValid; rnhout.fileType = string("NAVIGATION"); rnhout.fileProgram = string("NavMerge"); rnhout.fileAgency = string("ARL:UT/SGL/GPSTK"); rnhout.valid |= RinexNavHeader::runByValid; rnhout.commentList.clear(); rnhout.valid |= RinexNavHeader::commentValid; rnhout.valid |= RinexNavHeader::endValid; } int na=1,n=0,nf; while(na < argc) { filename = string(argv[na]); if(filename == string("")) { na++; continue; } try { RinexNavStream RNFileIn(filename.c_str()); if(!RNFileIn) { cout << "Could not open file " << filename << endl; na++; continue; } RNFileIn.exceptions(fstream::failbit); RNFileIn >> rnh; if(rnh.valid & RinexNavHeader::ionAlphaValid) { for(i=0; i<4; i++) rnhout.ionAlpha[i]=rnh.ionAlpha[i]; rnhout.valid |= RinexNavHeader::ionAlphaValid; } if(rnh.valid & RinexNavHeader::ionBetaValid) { for(i=0; i<4; i++) rnhout.ionBeta[i]=rnh.ionBeta[i]; rnhout.valid |= RinexNavHeader::ionBetaValid; } if(rnh.valid & RinexNavHeader::deltaUTCValid) { rnhout.A0 = rnh.A0; rnhout.A1 = rnh.A1; rnhout.UTCRefWeek = rnh.UTCRefWeek; rnhout.UTCRefTime = rnh.UTCRefTime; rnhout.valid |= RinexNavHeader::deltaUTCValid; } if(rnh.valid & RinexNavHeader::leapSecondsValid) { rnhout.leapSeconds = rnh.leapSeconds; rnhout.valid |= RinexNavHeader::leapSecondsValid; } nf = 0; while (RNFileIn >> rne) { nf++; n++; // check that week number (associated with HOW) is consistent with TOC. // (NB. in Rinex nav file, the week number is associated with the TOE; // RinexNavData converts it to associate with the HOW) int wkTOC,wk; wk = rne.weeknum; // 'weeknum' associated with HOW wkTOC = rne.time.GPSfullweek(); // 'time' comes from epoch line if(ABS(wk-wkTOC) > 1) { // HOW and TOC should be w/in 1 week double dt = double(wk-wkTOC)/1024.0; dt += (dt < 0.0 ? -0.5 : 0.5); wk -= int(dt) * 1024; if(ABS(wk-wkTOC) > 1) { cout << "WARNING: Ephemeris in " << filename << " for satellite G" << setw(2) << setfill('0') << rne.PRNID << setfill(' ') << " at time " << rne.time << " has inconsistent week number " << rne.weeknum << endl; } else { cout << "NavMerge corrected the week in G" << setw(2) << setfill('0') << rne.PRNID << setfill(' ') << " " << rne.time << " " << filename << endl; rne.weeknum = wk; } } // if healthy, add to the store if(rne.health == 0) EphStore.addEphemeris(rne); } } catch(Exception& e) { cout << "Exception: " << e << endl; } na++; cout << "Read " << setw(4) << nf << " ephemerides from file " << filename << endl; } cout << "Read " << setw(4) << n << " total ephemerides." << endl; // pull out all the ephemerides list<EngEphemeris> EphList; i = EphStore.addToList(EphList); if(outfile != string("")) { // write the output header RNFileOut << rnhout; // write out all the ephemerides list<EngEphemeris>::iterator it=EphList.begin(); n=0; while(it != EphList.end()) { rne = RinexNavData(*it); if(tb == DayTime::BEGINNING_OF_TIME || (rne.time - tb > -14400.0 && rne.time - te < 14400.0)) { n++; RNFileOut << rne; } it++; } cout << "Wrote " << setw(3) << n << " unique ephemerides to file " << outfile << endl; } else { EphStore.dump(cout,1); } return 0; } catch(Exception& e) { cout << e; } catch (...) { cout << "unknown error. Done." << endl; } return 1; return 0; }
// ----------------------------------------------------------------------------------- int main(int argc, char **argv) { try { int i,n,nobs,nnav; // get the current system time time_t timer; struct tm *tblock; timer = time(NULL); tblock = localtime(&timer); CurrEpoch = SystemTime(); i = GetCommandInput(argc, argv); if(i) return 0; if(verbose) { cout << Prgm << " version " << Vers << " run " << CurrEpoch << endl; DumpCommandLine(); } i = OpenFiles(); if(i) return i; // declare data objects used for I/O long bytesread=0; // at the end, bytesread should equal the Novatel file size. NovatelData novad; novad.setWeek(gpsWeek); RinexNavHeader rnh; RinexNavData rnd; RinexObsData rod; // initialize the headers (indexes inC1,etc defined here) InitializeHeaders(roh, rnh); // write headers rostr << roh; rnstr << rnh; // prep for the I/O loop FirstEpoch = CommonTime::BEGINNING_OF_TIME; for(i=0; i<9; i++) ndt[i] = -1; // show a counter nobs = nnav = n = 0; // loop over data in the Novatel file try{ while(instr >> novad) { if(Debug) cout << "Read " << NovatelData::RecNames[novad.rectype] << " size " << novad.headersize << " + " << novad.datasize << " number " << novad.recnum; if(novad.isOEM2()) { if(roh.recVers == string("OEM2/4")) roh.recVers = "OEM2"; if(Debug) cout << " OEM2"; } if(novad.isOEM4()) { if(Debug) cout << " OEM4"; if(roh.recVers == string("OEM2/4")) roh.recVers = "OEM4"; } if(Debug) { if(novad.isObs()) cout << " obs"; if(novad.isNav()) cout << " nav"; if(novad.isAux()) cout << " aux"; cout << endl; } bytesread += novad.datasize + novad.headersize; if(novad.isOEM2()) bytesread += 1; // CRC byte if(novad.isOEM4()) bytesread += 4; // CRC bytes if(novad.isObs() && novad.datasize > 4) { // obs only, with data try{ rod = RinexObsData(novad); // convert }catch(Exception e){cout << "Malformed Novatel obs record" << endl;} if(rod.time < BegTime) continue; if(rod.time > EndTime) break; if(Debug) rod.dump(cout); // dump rostr << rod; // write out nobs++; UpdateInformation(rod); } else if(novad.isNav()) { // nav only try{ rnd = RinexNavData(novad); // convert }catch(Exception e){cout << "Malformed Novatel nav record" << endl;} if(Debug) rnd.dump(cout); // dump rnstr << rnd; // write out nnav++; } n++; if(verbose && !Debug) { if(n == 100) cout << "Reading Novatel records: (100 per .)\n"; if(!(n % 100)) { cout << "."; cout.flush(); } if(!(n % 8000)) cout << endl; } } // end while loop over data } catch(Exception& e) { GPSTK_RETHROW(e); } if(verbose && !Debug) cout << "\n"; //instr.clear(); instr.close(); //rostr.clear(); rostr.close(); //rnstr.clear(); rnstr.close(); // now update the header and (re)write it to the file i = UpdateHeader(TempFileName, RinexObsFile, roh); if(verbose) { cout << "novaRinex read " << n << " records, and wrote " << nobs << " observations and " << nnav << " ephemerides\n"; cout << "Total bytes read = " << bytesread << endl; } return i; } catch(Exception& e) { cerr << "Caught exception\n" << e << endl; } catch(...) { cerr << "Unknown error." << endl; } return -1; }