diff --git a/BuildSetup.cmake b/BuildSetup.cmake index d5141e08e..acda1236d 100644 --- a/BuildSetup.cmake +++ b/BuildSetup.cmake @@ -51,7 +51,7 @@ elseif( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -O2" ) set( CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -O3" ) elseif( ${CMAKE_SYSTEM_NAME} MATCHES "Linux" ) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Werror=return-type -Werror=deprecated" ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-type -Werror=deprecated" ) # Do not optimize for debug builds. Do the same for RELWITHDEBINFO ? set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -g" ) set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3" ) @@ -170,12 +170,12 @@ if( DEBUG_VERBOSE ) message( STATUS "---- ${_variableName} = ${${_variableName}}" ) endforeach() endif() - + #---------------------------------------- # Get CMake vars into C++ #---------------------------------------- configure_file( "${PROJECT_SOURCE_DIR}/build_config.h.in" "${PROJECT_BINARY_DIR}/generated/build_config.h" ) -include_directories( "${PROJECT_BINARY_DIR}/generated/" ) +include_directories( "${PROJECT_BINARY_DIR}/generated/" ) install( FILES "${PROJECT_BINARY_DIR}/generated/build_config.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) #---------------------------------------- @@ -204,14 +204,14 @@ elseif( ${CMAKE_SYSTEM_NAME} MATCHES "Linux" ) set( CPACK_GENERATOR "DEB;TGZ" ) else (${LINUX_DISTRO} MATCHES "RedHatEnterpriseServer") message( STATUS "Detected a Linux machine") - set( CPACK_GENERATOR "DEB;TGZ" ) + set( CPACK_GENERATOR "DEB;TGZ" ) endif() elseif( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) set( CPACK_GENERATOR "NSIS;ZIP" ) set( CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE.md") endif() -set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Libraries for the GNSS processing GNSSTk toolkit.") +set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Libraries for the GNSS processing GNSSTk toolkit.") set( CPACK_PACKAGE_VENDOR "ARL:UT SGL" ) set( CPACK_PACKAGE_CONTACT "David Barber " ) set( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md" ) @@ -220,7 +220,7 @@ set( CPACK_PACKAGE_VERSION_MINOR "${GNSSTK_VERSION_MINOR}" ) set( CPACK_PACKAGE_VERSION_PATCH "${GNSSTK_VERSION_PATCH}" ) set( CPACK_INCLUDE_TOPLEVEL_DIRECTORY "OFF" ) set( CPACK_PACKAGE_INSTALL_DIRECTORY "gnsstk${GNSSTK_VERSION_MAJOR}.${GNSSTK_VERSION_MINOR}.${GNSSTK_VERSION_PATCH}" ) -set( CPACK_TOPLEVEL_TAG "gnsstk" ) +set( CPACK_TOPLEVEL_TAG "gnsstk" ) set( CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.13)" ) set( CPACK_DEBIAN_SECTION "stable" ) diff --git a/CMakeLists.txt b/CMakeLists.txt index c98adf361..138350c85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,8 +196,12 @@ install( FILES ${GNSSTK_INC_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) # GNSSTK Library parameters #============================================================ -set_target_properties(gnsstk PROPERTIES VERSION "${GNSSTK_VERSION_MAJOR}.${GNSSTK_VERSION_MINOR}.${GNSSTK_VERSION_PATCH}" - SOVERSION "${GNSSTK_VERSION_MAJOR}") +set_target_properties(gnsstk PROPERTIES + VERSION "${GNSSTK_VERSION_MAJOR}.${GNSSTK_VERSION_MINOR}.${GNSSTK_VERSION_PATCH}" + SOVERSION "${GNSSTK_VERSION_MAJOR}" + CXX_STANDARD 20 + CXX_EXTENSIONS YES +) #============================================================ # Testing diff --git a/core/lib/FileHandling/RINEX3/Rinex3NavHeader.cpp b/core/lib/FileHandling/RINEX3/Rinex3NavHeader.cpp index bbddeff2c..1284db6fd 100644 --- a/core/lib/FileHandling/RINEX3/Rinex3NavHeader.cpp +++ b/core/lib/FileHandling/RINEX3/Rinex3NavHeader.cpp @@ -56,12 +56,28 @@ #include #include #include +#include +#include using namespace gnsstk::StringUtils; using namespace std; namespace gnsstk { + + static const unordered_map + dependent_pairs + { + {IonoCorr::CorrType::GPSA, IonoCorr::CorrType::GPSB}, + {IonoCorr::CorrType::QZSA, IonoCorr::CorrType::QZSB}, + {IonoCorr::CorrType::BDSA, IonoCorr::CorrType::BDSB}, + {IonoCorr::CorrType::IRNA, IonoCorr::CorrType::IRNB}, + {IonoCorr::CorrType::GPSB, IonoCorr::CorrType::GPSA}, + {IonoCorr::CorrType::QZSB, IonoCorr::CorrType::QZSA}, + {IonoCorr::CorrType::BDSB, IonoCorr::CorrType::BDSA}, + {IonoCorr::CorrType::IRNB, IonoCorr::CorrType::IRNA} + }; + const string Rinex3NavHeader::stringVersion = "RINEX VERSION / TYPE"; const string Rinex3NavHeader::stringRunBy = "PGM / RUN BY / DATE"; const string Rinex3NavHeader::stringComment = "COMMENT"; @@ -128,6 +144,12 @@ namespace gnsstk case GAL: return std::string("GAL"); case GPSA: return std::string("GPSA"); case GPSB: return std::string("GPSB"); + case QZSA: return std::string("QZSA"); + case QZSB: return std::string("QZSB"); + case BDSA: return std::string("BDSA"); + case BDSB: return std::string("BDSB"); + case IRNA: return std::string("IRNA"); + case IRNB: return std::string("IRNB"); case Unknown: break; } @@ -138,18 +160,24 @@ namespace gnsstk void IonoCorr :: fromString(const std::string str) { - std::string STR(gnsstk::StringUtils::upperCase(str)); - if (STR == std::string("GAL")) - type = GAL; - else if (STR == std::string("GPSA")) - type = GPSA; - else if (STR == std::string("GPSB")) - type = GPSB; - else + static const std::unordered_map from_string { - Exception e("Unknown IonoCorr type: " + str); - GNSSTK_THROW(e); - } + {"GAL", CorrType::GAL}, + {"GPSA", CorrType::GPSA}, + {"GPSB", CorrType::GPSB}, + {"QZSA", CorrType::QZSA}, + {"QZSB", CorrType::QZSB}, + {"BDSA", CorrType::BDSA}, + {"BDSB", CorrType::BDSB}, + {"IRNA", CorrType::IRNA}, + {"IRNB", CorrType::IRNB} + }; + std::string key = gnsstk::StringUtils::upperCase(str); + + if (!from_string.contains(key)) + GNSSTK_THROW(Exception("Unknown ionospheric correction parameter: " + str)); + + type = from_string.at(key); } @@ -266,21 +294,21 @@ namespace gnsstk { // GPS alpha "ION ALPHA" R2.11 IonoCorr ic("GPSA"); - for(i=0; i < 4; i++) + for(i = 0; i < 4; i++) ic.param[i] = line.substr(2 + 12*i, 12); - mapIonoCorr[ic.asString()] = ic; - if(mapIonoCorr.find("GPSB") != mapIonoCorr.end()) - valid |= validIonoCorrGPS; + mapIonoCorr[ic.type] = ic; + if (mapIonoCorr.contains(IonoCorr::CorrType::GPSB)) + valid |= validIonoCorr; } else if(thisLabel == stringIonBeta) { // GPS beta "ION BETA" R2.11 IonoCorr ic("GPSB"); - for(i=0; i < 4; i++) + for(i = 0; i < 4; i++) ic.param[i] = line.substr(2 + 12*i, 12); - mapIonoCorr[ic.asString()] = ic; - if(mapIonoCorr.find("GPSA") != mapIonoCorr.end()) - valid |= validIonoCorrGPS; + mapIonoCorr[ic.type] = ic; + if (mapIonoCorr.contains(IonoCorr::CorrType::GPSA)) + valid |= validIonoCorr; } else if(thisLabel == stringIonoCorr) { @@ -295,25 +323,12 @@ namespace gnsstk FFStreamError fse(e.what()); GNSSTK_THROW(e); } - for(i=0; i < 4; i++) + for(i = 0; i < 4; i++) ic.param[i] = line.substr(5 + 12*i, 12); - - if(ic.type == IonoCorr::GAL) - { - valid |= validIonoCorrGal; - } - else if(ic.type == IonoCorr::GPSA) - { - if(mapIonoCorr.find("GPSB") != mapIonoCorr.end()) - valid |= validIonoCorrGPS; - } - else if(ic.type == IonoCorr::GPSB) - { - if(mapIonoCorr.find("GPSA") != mapIonoCorr.end()) - valid |= validIonoCorrGPS; - } - //else - mapIonoCorr[ic.asString()] = ic; + mapIonoCorr[ic.type] = ic; + if (!dependent_pairs.contains(ic.type) + || mapIonoCorr.contains(dependent_pairs.at(ic.type))) + valid |= validIonoCorr; } else if(thisLabel == stringDeltaUTC) { @@ -511,68 +526,17 @@ namespace gnsstk } } - if ((valid & validIonoCorrGPS) || (valid & validIonoCorrGal)) + if (valid & validIonoCorr) { // "IONOSPHERIC CORR" - map::const_iterator it; - for(it=mapIonoCorr.begin(); it != mapIonoCorr.end(); ++it) + for (auto const& [type, value] : mapIonoCorr) { - switch(it->second.type) - { - case IonoCorr::GAL: - strm << "GAL "; - for(j=0; j<3; j++) - { - strm << it->second.param[j]; - } - strm << " " << setw(7) << ' ' << stringIonoCorr; - break; - case IonoCorr::GPSA: - if(version >= 3) - { - strm << "GPSA "; - for(j=0; j<4; j++) - { - strm << it->second.param[j]; - } - strm << setw(7) << ' ' << stringIonoCorr; - } - else - { - // "ION ALPHA" // R2.11 - strm << " "; - for(j=0; j<4; j++) - { - strm << it->second.param[j]; - } - strm << setw(10) << ' ' << stringIonAlpha; - } - break; - case IonoCorr::GPSB: - if(version >= 3) - { - strm << "GPSB "; - for(j=0; j<4; j++) - strm << it->second.param[j]; - strm << setw(7) << ' ' << stringIonoCorr; - } - else - { - // "ION BETA" // R2.11 - strm << " "; - for(j=0; j<4; j++) - strm << it->second.param[j]; - strm << setw(10) << ' ' << stringIonBeta; - } - break; - case IonoCorr::Unknown: - default: - FFStreamError err("Unknown IonoCorr type " + - asString(it->second.type)); - GNSSTK_THROW(err); - break; - } - strm << endlpp; + std::stringstream data; + + data << std::left << std::setw(5) << value.asString(); + for (auto const& parameter : value.param) + data << parameter; + strm << std::setw(60) << data.str() << stringIonoCorr << endlpp; } } @@ -724,38 +688,30 @@ namespace gnsstk s << endl; } - map::const_iterator icit; - for(icit=mapIonoCorr.begin(); icit != mapIonoCorr.end(); ++icit) + for (auto const & [type, value] : mapIonoCorr) { - s << "Iono correction for " << icit->second.asString() << " : " + s << "Iono correction for " << value.asString() << ": " << scientific << setprecision(4); - switch(icit->second.type) + switch (type) { - case IonoCorr::GAL: - s << "ai0 = " << icit->second.param[0] - << ", ai1 = " << icit->second.param[1] - << ", ai2 = " << icit->second.param[2]; - break; - case IonoCorr::GPSA: - s << "alpha " << icit->second.param[0] - << " " << icit->second.param[1] - << " " << icit->second.param[2] - << " " << icit->second.param[3]; - break; - case IonoCorr::GPSB: - s << "beta " << icit->second.param[0] - << " " << icit->second.param[1] - << " " << icit->second.param[2] - << " " << icit->second.param[3]; - break; - case IonoCorr::Unknown: - default: - FFStreamError err("Unknown IonoCorr type " + - asString(icit->second.type)); - GNSSTK_THROW(err); - break; + case IonoCorr::CorrType::GPSA: + case IonoCorr::CorrType::QZSA: + case IonoCorr::CorrType::BDSA: + case IonoCorr::CorrType::IRNA: + s << "aplha"; + break; + case IonoCorr::CorrType::GPSB: + case IonoCorr::CorrType::QZSB: + case IonoCorr::CorrType::BDSB: + case IonoCorr::CorrType::IRNB: + s << "beta"; + break; + default: + s << "ai"; } - s << endl; + for (auto const& parameter : value.param) + s << " " << parameter; + s << std::endl; } if(valid & validLeapSeconds) @@ -891,26 +847,6 @@ namespace gnsstk else { lineMap[stringDUTC] = true; - } - if (((lici = mapIonoCorr.find("GPSA")) != mapIonoCorr.end()) && - ((rici = right.mapIonoCorr.find("GPSA")) != right.mapIonoCorr.end())) - - { -// lineMap[stringIonAlpha] = lici->second == rici->second; - } - else - { - lineMap[stringIonAlpha] = true; - } - if (((lici = mapIonoCorr.find("GPSB")) != mapIonoCorr.end()) && - ((rici = right.mapIonoCorr.find("GPSB")) != right.mapIonoCorr.end())) - - { -// lineMap[stringIonBeta] = lici->second == rici->second; - } - else - { - lineMap[stringIonBeta] = true; } // ...then filter by inclExclList later if (incl) diff --git a/core/lib/FileHandling/RINEX3/Rinex3NavHeader.hpp b/core/lib/FileHandling/RINEX3/Rinex3NavHeader.hpp index 81f4ebb98..a7e9bd54e 100644 --- a/core/lib/FileHandling/RINEX3/Rinex3NavHeader.hpp +++ b/core/lib/FileHandling/RINEX3/Rinex3NavHeader.hpp @@ -72,8 +72,13 @@ namespace gnsstk Unknown, ///< A default value GAL, ///< Galileo GPSA, ///< GPS alpha - GPSB ///< GPS beta - /// @todo add support for remaining systems in RINEX 3.04 + GPSB, ///< GPS beta + QZSA, ///< QZSS alpha + QZSB, ///< QZSS beta + BDSA, ///< BeiDou alpha + BDSB, ///< BeiDou beta + IRNA, ///< IRNSS alpha + IRNB ///< IRNSS beta }; /// Set data members to default values @@ -112,20 +117,20 @@ namespace gnsstk /// Constructor Rinex3NavHeader() - : valid(0), version(3.02), + : valid(0), version(3.04), leapSeconds(0), leapDelta(0), leapWeek(0),leapDay(0) {} /// Destructor - virtual ~Rinex3NavHeader() + ~Rinex3NavHeader() override {} /// Rinex3NavHeader is a "header" so this function always returns true. - virtual bool isHeader() const + bool isHeader() const override { return true; } /// This function dumps the contents of the header. - virtual void dump(std::ostream& s) const; + void dump(std::ostream& s) const override; /** Change the file system, keeping fileType, fileSys, and fileSysSat * consistent. @@ -158,8 +163,7 @@ namespace gnsstk validVersion = 0x01, ///< Set if RINEX version is valid. validRunBy = 0x02, ///< Set if Run-by value is valid. validComment = 0x04, ///< Set if Comments are valid - validIonoCorrGPS = 0x08, ///< Set if GPS Iono Correction data is valid. - validIonoCorrGal = 0x010, ///< Set if Gal Iono Correction data is valid. + validIonoCorr = 0x08, ///< Set if Iono Correction data is valid. validTimeSysCorr = 0x020, ///< Set if Time System Correction is valid. validLeapSeconds = 0x040, ///< Set if the Leap Seconds value is valid. validEoH = 0x080000000, ///< Set if the End of Header is valid. @@ -186,7 +190,7 @@ namespace gnsstk /// map of label: GAUT, GPUT, etc, and TimeCorr std::map mapTimeCorr; /// map of label : GAL, GPSA or GPSB, and IONO CORRs - std::map mapIonoCorr; + std::map mapIonoCorr; long leapSeconds; ///< Leap seconds long leapDelta; ///< Change in Leap seconds at ref time long leapWeek; ///< Week number of ref time diff --git a/core/lib/NewNav/NewNavToRinex.cpp b/core/lib/NewNav/NewNavToRinex.cpp index 3f2e16eee..ee44c2a5f 100644 --- a/core/lib/NewNav/NewNavToRinex.cpp +++ b/core/lib/NewNav/NewNavToRinex.cpp @@ -180,9 +180,9 @@ namespace gnsstk icB.param[1] = kiPtr->beta[1]; icB.param[2] = kiPtr->beta[2]; icB.param[3] = kiPtr->beta[3]; - h.mapIonoCorr[icA.asString()] = icA; - h.mapIonoCorr[icB.asString()] = icB; - h.valid |= Rinex3NavHeader::validIonoCorrGPS; + h.mapIonoCorr[icA.type] = icA; + h.mapIonoCorr[icB.type] = icB; + h.valid |= Rinex3NavHeader::validIonoCorr; rv = true; } else @@ -202,8 +202,8 @@ namespace gnsstk ic.param[1] = neqiPtr->ai[1]; ic.param[2] = neqiPtr->ai[2]; ic.type = IonoCorr::GAL; - h.mapIonoCorr[ic.asString()] = ic; - h.valid |= Rinex3NavHeader::validIonoCorrGal; + h.mapIonoCorr[ic.type] = ic; + h.valid |= Rinex3NavHeader::validIonoCorr; rv = true; } } diff --git a/core/lib/NewNav/RinexNavDataFactory.cpp b/core/lib/NewNav/RinexNavDataFactory.cpp index cc586c673..6ce96effb 100644 --- a/core/lib/NewNav/RinexNavDataFactory.cpp +++ b/core/lib/NewNav/RinexNavDataFactory.cpp @@ -861,9 +861,9 @@ namespace gnsstk convertToIono(const CommonTime& when, const Rinex3NavHeader& navIn, NavDataPtrList& navOut) { - std::map::const_iterator ai, bi; - if (((ai = navIn.mapIonoCorr.find("GPSA")) != navIn.mapIonoCorr.end()) && - ((bi = navIn.mapIonoCorr.find("GPSB")) != navIn.mapIonoCorr.end())) + std::map::const_iterator ai, bi; + if (((ai = navIn.mapIonoCorr.find(IonoCorr::CorrType::GPSA)) != navIn.mapIonoCorr.end()) && + ((bi = navIn.mapIonoCorr.find(IonoCorr::CorrType::GPSB)) != navIn.mapIonoCorr.end())) { // we have the GPS alpha and beta terms. std::shared_ptr iono(std::make_shared()); @@ -916,7 +916,7 @@ namespace gnsstk health->svHealth = 0; // force "PRN 0" to be healthy navOut.push_back(health); } - if ((ai = navIn.mapIonoCorr.find("GAL")) != navIn.mapIonoCorr.end()) + if ((ai = navIn.mapIonoCorr.find(IonoCorr::CorrType::GAL)) != navIn.mapIonoCorr.end()) { // we have the Galileo (NeQuickG) ai terms. /** @todo We don't know whether the iono data came from @@ -968,8 +968,8 @@ namespace gnsstk health->sisaIndex = 0; navOut.push_back(health); } - if (((ai = navIn.mapIonoCorr.find("BDSA")) != navIn.mapIonoCorr.end()) && - ((bi = navIn.mapIonoCorr.find("BDSB")) != navIn.mapIonoCorr.end())) + if (((ai = navIn.mapIonoCorr.find(IonoCorr::CorrType::BDSA)) != navIn.mapIonoCorr.end()) && + ((bi = navIn.mapIonoCorr.find(IonoCorr::CorrType::BDSB)) != navIn.mapIonoCorr.end())) { // we have the BDS alpha and beta terms. // we *don't* have any idea if these came from D1 or D2, so assume.