// Private helper routine for casts from this to OrbitEph-based Ephemerides void Rinex3NavData::castTo(OrbitEph *oeptr) const { try { // Glonass and Geosync do not have a orbit-based ephemeris if(satSys == "R" || satSys == "S") { oeptr->dataLoadedFlag = false; return; } // Overhead RinexSatID sat; sat.fromString(satSys + StringUtils::asString(PRNID)); oeptr->satID = SatID(sat); //obsID = ?? ObsID obsID; // Defines carrier and tracking code oeptr->ctToe = time; // clock model oeptr->af0 = af0; oeptr->af1 = af1; oeptr->af2 = af2; // Major orbit parameters oeptr->M0 = M0; oeptr->dn = dn; oeptr->ecc = ecc; oeptr->A = Ahalf * Ahalf; oeptr->OMEGA0 = OMEGA0; oeptr->i0 = i0; oeptr->w = w; oeptr->OMEGAdot = OMEGAdot; oeptr->idot = idot; // modern nav msg oeptr->dndot = 0.; oeptr->Adot = 0.; // Harmonic perturbations oeptr->Cuc = Cuc; oeptr->Cus = Cus; oeptr->Crc = Crc; oeptr->Crs = Crs; oeptr->Cic = Cic; oeptr->Cis = Cis; oeptr->dataLoadedFlag = true; } catch(Exception& e) { GPSTK_RETHROW(e); } }
RinexDatum Rinex3ObsData::getObs(const RinexSatID& svID, const RinexObsID& obsID, const Rinex3ObsHeader& hdr ) const throw(InvalidRequest) { string sys(1,svID.systemChar()); return getObs(svID, hdr.getObsIndex(sys, obsID)); }
void Rinex3ObsData::setObs(const RinexDatum& data, const RinexSatID& svID, const RinexObsID& obsID, const Rinex3ObsHeader& hdr ) throw(InvalidRequest) { size_t index = hdr.getObsIndex(string(1,svID.systemChar()), obsID); if (obs[svID].size() <= index) obs[svID].resize(index+1); obs[svID][index] = data; }
RinexDatum Rinex3ObsData::getObs(const RinexSatID& svID, const std::string& type, const Rinex3ObsHeader& hdr ) const throw(InvalidRequest) { string obsID; // Add GNSS code if needed if( type.size() == 3 ) obsID = svID.systemChar() + type; else obsID = type; return getObs(svID, hdr.getObsIndex(obsID)); }
void reallyGetRecordVer2(Rinex3ObsStream& strm, Rinex3ObsData& rod) throw(Exception) { static CommonTime previousTime(CommonTime::BEGINNING_OF_TIME); // get the epoch line and check string line; while(line.empty()) // ignore blank lines in place of epoch lines strm.formattedGetLine(line, true); if(line.size()>80 || line[0] != ' ' || line[3] != ' ' || line[6] != ' ') { FFStreamError e("Bad epoch line: >" + line + "<"); GPSTK_THROW(e); } // process the epoch line, including SV list and clock bias rod.epochFlag = asInt(line.substr(28,1)); if((rod.epochFlag < 0) || (rod.epochFlag > 6)) { FFStreamError e("Invalid epoch flag: " + asString(rod.epochFlag)); GPSTK_THROW(e); } // Not all epoch flags are required to have a time. // Specifically, 0,1,5,6 must have an epoch time; it is optional for 2,3,4. // If there is and epoch time, parse it and load it in the member "time". // If epoch flag=0, 1, 5, or 6 and there is NO epoch time, then throw. // If epoch flag=2, 3, or 4 and there is no epoch time, // use the time of the previous record. bool noEpochTime = (line.substr(0,26) == string(26, ' ')); if(noEpochTime && (rod.epochFlag==0 || rod.epochFlag==1 || rod.epochFlag==5 || rod.epochFlag==6 )) { FFStreamError e("Required epoch time missing: " + line); GPSTK_THROW(e); } else if(noEpochTime) rod.time = previousTime; else { try { // check if the spaces are in the right place - an easy // way to check if there's corruption in the file if((line[0] != ' ') || (line[3] != ' ') || (line[6] != ' ') || (line[9] != ' ') || (line[12] != ' ') || (line[15] != ' ')) { FFStreamError e("Invalid time format"); GPSTK_THROW(e); } // if there's no time, just use a bad time if(line.substr(0,26) == string(26, ' ')) rod.time = CommonTime::BEGINNING_OF_TIME; //rod.time = previousTime; ?? else { int year, month, day, hour, min; double sec; int yy = (static_cast<CivilTime>(strm.header.firstObs)).year/100; yy *= 100; year = asInt( line.substr(1, 2 )); month = asInt( line.substr(4, 2 )); day = asInt( line.substr(7, 2 )); hour = asInt( line.substr(10, 2 )); min = asInt( line.substr(13, 2 )); sec = asDouble(line.substr(15, 11)); // Real Rinex has epochs 'yy mm dd hr 59 60.0' surprisingly often.... double ds(0); if(sec >= 60.) { ds=sec; sec=0.0; } CivilTime rv(yy+year, month, day, hour, min, sec, TimeSystem::GPS); if(ds != 0) rv.second += ds; rod.time = rv.convertToCommonTime(); } } // string exceptions for substr are caught here catch(exception &e) { FFStreamError err("std::exception: " + string(e.what())); GPSTK_THROW(err); } catch(Exception& e) { string text; for(size_t i=0; i<e.getTextCount(); i++) text += e.getText(i); FFStreamError err("gpstk::Exception in parseTime(): " + text); GPSTK_THROW(err); } // end rod.time = parseTime(line, strm.header); // save for next call previousTime = rod.time; } // number of satellites rod.numSVs = asInt(line.substr(29,3)); // clock offset if(line.size() > 68 ) rod.clockOffset = asDouble(line.substr(68, 12)); else rod.clockOffset = 0.0; // Read the observations ... if(rod.epochFlag==0 || rod.epochFlag==1 || rod.epochFlag==6) { // first read the SatIDs off the epoch line int isv, ndx, line_ndx; string satsys; RinexSatID sat; vector<RinexSatID> satIndex(rod.numSVs); for(isv=1, ndx=0; ndx<rod.numSVs; isv++, ndx++) { if(!(isv % 13)) { // get a new continuation line strm.formattedGetLine(line); isv = 1; if(line.size() > 80) { FFStreamError err("Invalid line size:" + asString(line.size())); GPSTK_THROW(err); } } // read the sat id try { sat = RinexSatID(line.substr(30+isv*3-1, 3)); satIndex[ndx] = sat; //// if this system does not have obs types assigned, do so //string satsys = asString(sat.systemChar()); //if(strm.header.mapObsTypes[satsys].size() == 0) { // strm.header.mapObsTypes[satsys] = strm.header.mapObsTypes["G"]; //} } catch (Exception& e) { FFStreamError ffse(e); GPSTK_THROW(ffse); } } // end loop over numSVs // loop over all sats, reading obs data int numObs(strm.header.R2ObsTypes.size());// number of R2 OTs in header rod.obs.clear(); for(isv=0; isv < rod.numSVs; isv++) { //strm.formattedGetLine(line); // get a line //line.resize(80, ' '); // pad just in case sat = satIndex[isv]; // sat for this data satsys = asString(sat.systemChar()); // system for this sat vector<RinexDatum> data; // loop over data in the line for(ndx=0, line_ndx=0; ndx < numObs; ndx++, line_ndx++) { if(! (line_ndx % 5)) { // get a new line strm.formattedGetLine(line); line.resize(80, ' '); // pad just in case line_ndx = 0; if(line.size() > 80) { FFStreamError err("Invalid line size:" + asString(line.size())); GPSTK_THROW(err); } } // does this R2 OT map into a valid R3 ObsID? string R2ot(strm.header.R2ObsTypes[ndx]); string R3ot(strm.header.mapSysR2toR3ObsID[satsys][R2ot].asString()); if(R3ot != string(" ")) { RinexDatum tempData; tempData.data = asDouble(line.substr(line_ndx*16, 14)); tempData.lli = asInt(line.substr(line_ndx*16+14, 1)); tempData.ssi = asInt(line.substr(line_ndx*16+15, 1)); data.push_back(tempData); } } rod.obs[sat] = data; } // end loop over sats to read obs data } // ... or the auxiliary header information else if(rod.numSVs > 0) { rod.auxHeader.clear(); for(int i=0; i<rod.numSVs; i++) { strm.formattedGetLine(line); StringUtils::stripTrailing(line); try { rod.auxHeader.ParseHeaderRecord(line); } catch(FFStreamError& e) { GPSTK_RETHROW(e); } catch(StringException& e) { GPSTK_RETHROW(e); } } } } // end void reallyGetRecordVer2(Rinex3ObsStream& strm, Rinex3ObsData& rod)
bool convertRinex2ObsFile(std::string& fileName, std::string& outFile) { bool retBool = true; try { // Open the input & output files. if (debug) cout << "Trying to open input file:" << fileName << endl; RinexObsStream obsIn(fileName.c_str(), ios::in); if (!obsIn) return false; else if (debug) cout << "...opened" << endl; if (outFile.length() == 0) { if (outputPath.length() > 0) outFile = outputPath; int lastIndexOf = fileName.find_last_of("\\/"); if (lastIndexOf == -1) lastIndexOf = 0; outFile = fileName.substr(lastIndexOf); } if (debug) cout << "Trying to open output file: " << outFile << endl; Rinex3ObsStream obsOut(outFile.c_str(), ios::out); if (!obsOut) return false; else if (debug) cout << "...opened" << endl; // Declare the header and its converted version. RinexObsHeader robsHead; Rinex3ObsHeader convHead; // Read in the header data. if (debug) cout << "Reading in header..." << endl; obsIn >> robsHead; if (debug) cout << "...finished" << endl; // Convert the obs header and test, all in one step. // If the header couldn't be converted return false. if (debug) cout << "Converting header..." << endl; if (!RinexConverter::convertToRinex3(convHead, robsHead)) return false; if (debug) cout << "...finished" << endl; // Write out the converted header data. obsOut << convHead; if (debug) { convHead.dump(cout); /* cout << " Version: " << convHead.version << endl; cout << " File Type: " << convHead.fileType << endl; cout << " System: " << convHead.system << endl; cout << " File Program: " << convHead.fileProgram << endl; cout << " File Agency: " << convHead.fileAgency << endl; cout << " Date: " << convHead.date << endl; cout << " Marker Name: " << convHead.markerName << endl; cout << " Marker Number: " << convHead.markerNumber << endl; cout << " Marker Type: " << convHead.markerType << endl; cout << " Observer: " << convHead.observer << endl; cout << " Agency: " << convHead.agency << endl; cout << " Rec. No: " << convHead.recNo << endl; cout << " Rec. Type: " << convHead.recType << endl; cout << " Rec. Version: " << convHead.recVers << endl; cout << " Ant. No: " << convHead.antNo << endl; cout << " Ant. Type: " << convHead.antType << endl; cout << " Ant. Position: " << convHead.antennaPosition << endl; cout << " Ant. Delta HEN: " << convHead.antennaDeltaHEN << endl; cout << " Interval: " << convHead.interval << endl; cout << "Receiver Offset: " << convHead.receiverOffset << endl; cout << " Leap Seconds: " << convHead.leapSeconds << endl; cout << " Num SVs: " << convHead.numSVs << endl; cout << " Valid: " << convHead.valid << endl; */ } // All of the data contained in the file. vector<RinexObsData> robsData; // A temporary data object for reading in from the stream. RinexObsData temp; // Converted data object. Rinex3ObsData convData; // Last observed epoch CommonTime lastEpoch = CommonTime::BEGINNING_OF_TIME; // Flags for the presence of the different systems bool hasGPS, hasGLO, hasGAL, hasGEO; hasGPS = hasGLO = hasGAL = hasGEO = false; if (debug) cout << "Start reading in data..." << endl; while(1) { try { obsIn >> temp; } catch (Exception gpstkEx) { if (printExceptions) cout << "Exception Reading Data:" << endl << gpstkEx << endl; continue; } catch (exception stdEx) { if (printExceptions) cout << "Exception Reading Data:" << endl << stdEx.what() << endl; continue; } catch (...) { if (printExceptions) cout << "Exception Reading Data" << endl; continue; } // Break for bad data or end of file. if (!obsIn.good() || obsIn.eof()) break; // Otherwise, save the data. robsData.push_back(temp); if (temp.time > lastEpoch) lastEpoch = temp.time; // Set the system flags. RinexSatID id; RinexObsData::RinexSatMap::const_iterator iter = temp.obs.begin(); while(iter != temp.obs.end()) { id = RinexSatID(iter->first); if (id.systemChar() == 'G') hasGPS = true; else if (id.systemChar() == 'R') hasGLO = true; else if (id.systemChar() == 'E') hasGAL = true; else if (id.systemChar() == 'S') hasGEO = true; ++iter; } } /// For now, comment out the following. While logical, we will abide by the /// philosophy that this converter sould simply read in and write out, not /// alter the data in any way. /* // Erase any systems that were not present. map<string, vector<ObsID> >::const_iterator mapIter; mapIter = convHead.mapObsTypes.find("G"); if (!hasGPS && mapIter != convHead.mapObsTypes.end()) convHead.mapObsTypes.erase("G"); mapIter = convHead.mapObsTypes.find("R"); if (!hasGPS && mapIter != convHead.mapObsTypes.end()) convHead.mapObsTypes.erase("R"); mapIter = convHead.mapObsTypes.find("E"); if (!hasGPS && mapIter != convHead.mapObsTypes.end()) convHead.mapObsTypes.erase("E"); mapIter = convHead.mapObsTypes.find("S"); if (!hasGPS && mapIter != convHead.mapObsTypes.end()) convHead.mapObsTypes.erase("S"); // close the input stream obsIn.clear(); obsIn.close(); */ for (int i = 0; i < robsData.size(); ++i) { RinexConverter::convertToRinex3(convData, robsData[i], robsHead); obsOut << convData; } // obsOut.flush(); obsOut.close(); } catch(Exception gpstkException) { if (printExceptions) cout << "GPSTk Exception:" << gpstkException << endl; return false; } catch(exception stdException) { if (printExceptions) cout << "Exception:" << stdException.what() << endl; return false; } catch(...) { if (printExceptions) cout << "Exception!" << endl; return false; } }