diff --git a/.gitmodules b/.gitmodules index 7828c19a..a0fe596c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,3 +31,6 @@ [submodule "external/date"] path = external/date url = https://github.com/HowardHinnant/date.git +[submodule "external/units"] + path = external/units + url = https://github.com/nholthaus/units.git diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 65b2ef20..806b603b 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -10,7 +10,8 @@ set_property(DIRECTORY hsluv-c.cmake imgui.cmake mapbox-gl-native.cmake - stb.cmake) + stb.cmake + units.cmake) include(aws-sdk-cpp.cmake) include(date.cmake) @@ -19,3 +20,4 @@ include(hsluv-c.cmake) include(imgui.cmake) include(mapbox-gl-native.cmake) include(stb.cmake) +include(units.cmake) diff --git a/external/units b/external/units new file mode 160000 index 00000000..da6dd917 --- /dev/null +++ b/external/units @@ -0,0 +1 @@ +Subproject commit da6dd9176e8515323c75030d5e51ee19cf6c9afd diff --git a/external/units.cmake b/external/units.cmake new file mode 100644 index 00000000..d037ae54 --- /dev/null +++ b/external/units.cmake @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.20) +set(PROJECT_NAME scwx-units) + +add_subdirectory(units) diff --git a/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp b/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp index dbbc2308..5b8c876c 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp @@ -232,11 +232,9 @@ void PlacefileIcons::Render( if (p->thresholded_) { // If thresholding is enabled, set the map distance - // TODO: nautical miles - auto mapDistance = - util::maplibre::GetMapDistance(params).value() / 1852.0f; - gl.glUniform1f(p->uMapDistanceLocation_, - static_cast(mapDistance)); + units::length::nautical_miles mapDistance = + util::maplibre::GetMapDistance(params); + gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); } else { @@ -328,9 +326,10 @@ void PlacefileIcons::Impl::Update() continue; } - // TODO: nautical miles - GLint threshold = - static_cast(std::roundf(di->threshold_.value() / 1852.0f)); + // Threshold value + units::length::nautical_miles threshold = di->threshold_; + GLint thresholdValue = + static_cast(std::round(threshold.value())); // Latitude and longitude coordinates in degrees const float lat = static_cast(di->latitude_); @@ -355,8 +354,8 @@ void PlacefileIcons::Impl::Update() const float by = std::roundf(ty - ih); // Angle in degrees - // TODO: Properly convert - const float a = static_cast(di->angle_.value()); + units::angle::degrees angle = di->angle_; + const float a = angle.value(); // Texture coordinates const std::size_t iconRow = (di->iconNumber_ - 1) / icon.columns_; @@ -387,12 +386,12 @@ void PlacefileIcons::Impl::Update() lat, lon, lx, ty, ls, tt, mc0, mc1, mc2, mc3, a // TL }); thresholds.insert(thresholds.end(), - {threshold, // - threshold, - threshold, - threshold, - threshold, - threshold}); + {thresholdValue, // + thresholdValue, + thresholdValue, + thresholdValue, + thresholdValue, + thresholdValue}); numVertices_ += 6; } diff --git a/scwx-qt/source/scwx/qt/gl/draw/placefile_polygons.cpp b/scwx-qt/source/scwx/qt/gl/draw/placefile_polygons.cpp index 202a5c0e..7bb54027 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/placefile_polygons.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/placefile_polygons.cpp @@ -6,7 +6,6 @@ #include #include -#include #if defined(_WIN32) typedef void (*_GLUfuncptr)(void); @@ -216,11 +215,9 @@ void PlacefilePolygons::Render( if (p->thresholded_) { // If thresholding is enabled, set the map distance - // TODO: nautical miles - auto mapDistance = - util::maplibre::GetMapDistance(params).value() / 1852.0f; - gl.glUniform1f(p->uMapDistanceLocation_, - static_cast(mapDistance)); + units::length::nautical_miles mapDistance = + util::maplibre::GetMapDistance(params); + gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value()); } else { @@ -311,9 +308,9 @@ void PlacefilePolygons::Impl::Tessellate( // Default color to "Color" statement boost::gil::rgba8_pixel_t lastColor = di->color_; - // TODO: nautical miles - currentThreshold_ = - static_cast(std::roundf(di->threshold_.value() / 1852.0f)); + // Current threshold + units::length::nautical_miles threshold = di->threshold_; + currentThreshold_ = static_cast(std::round(threshold.value())); gluTessBeginPolygon(tessellator_, this); diff --git a/scwx-qt/source/scwx/qt/map/placefile_layer.cpp b/scwx-qt/source/scwx/qt/map/placefile_layer.cpp index 70db64a5..ca98bdfa 100644 --- a/scwx-qt/source/scwx/qt/map/placefile_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/placefile_layer.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -69,7 +68,7 @@ public: bool thresholded_ {true}; ImFont* monospaceFont_ {}; - boost::units::quantity mapDistance_ {}; + units::length::nautical_miles mapDistance_ {}; std::shared_ptr placefileIcons_; std::shared_ptr placefilePolygons_; diff --git a/scwx-qt/source/scwx/qt/model/alert_model.cpp b/scwx-qt/source/scwx/qt/model/alert_model.cpp index 4cadff42..e44e2a17 100644 --- a/scwx-qt/source/scwx/qt/model/alert_model.cpp +++ b/scwx-qt/source/scwx/qt/model/alert_model.cpp @@ -1,3 +1,5 @@ +#define NOMINMAX + #include #include #include diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp index 84ae9e66..0496d88a 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.cpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.cpp @@ -18,15 +18,14 @@ const ::GeographicLib::Geodesic& DefaultGeodesic() return geodesic_; } -boost::units::quantity +units::length::meters GetDistance(double lat1, double lon1, double lat2, double lon2) { double distance; util::GeographicLib::DefaultGeodesic().Inverse( lat1, lon1, lat2, lon2, distance); - return static_cast>( - distance * boost::units::si::meter_base_unit::unit_type()); + return units::length::meters {distance}; } } // namespace GeographicLib diff --git a/scwx-qt/source/scwx/qt/util/geographic_lib.hpp b/scwx-qt/source/scwx/qt/util/geographic_lib.hpp index c3e74ef9..d93dce2b 100644 --- a/scwx-qt/source/scwx/qt/util/geographic_lib.hpp +++ b/scwx-qt/source/scwx/qt/util/geographic_lib.hpp @@ -1,8 +1,7 @@ #pragma once #include -#include -#include +#include namespace scwx { @@ -30,7 +29,7 @@ const ::GeographicLib::Geodesic& DefaultGeodesic(); * * @return distance between point 1 and point 2 */ -boost::units::quantity +units::length::meters GetDistance(double lat1, double lon1, double lat2, double lon2); } // namespace GeographicLib diff --git a/scwx-qt/source/scwx/qt/util/maplibre.cpp b/scwx-qt/source/scwx/qt/util/maplibre.cpp index 5b3f331e..8cde77ca 100644 --- a/scwx-qt/source/scwx/qt/util/maplibre.cpp +++ b/scwx-qt/source/scwx/qt/util/maplibre.cpp @@ -12,11 +12,12 @@ namespace util namespace maplibre { -boost::units::quantity +units::length::meters GetMapDistance(const QMapLibreGL::CustomLayerRenderParameters& params) { - return QMapLibreGL::metersPerPixelAtLatitude(params.latitude, params.zoom) * - (params.width + params.height) / 2.0 * boost::units::si::meters; + return units::length::meters( + QMapLibreGL::metersPerPixelAtLatitude(params.latitude, params.zoom) * + (params.width + params.height) / 2.0); } glm::vec2 LatLongToScreenCoordinate(const QMapLibreGL::Coordinate& coordinate) diff --git a/scwx-qt/source/scwx/qt/util/maplibre.hpp b/scwx-qt/source/scwx/qt/util/maplibre.hpp index 65aa4409..37d205eb 100644 --- a/scwx-qt/source/scwx/qt/util/maplibre.hpp +++ b/scwx-qt/source/scwx/qt/util/maplibre.hpp @@ -1,9 +1,8 @@ #pragma once #include -#include -#include #include +#include namespace scwx { @@ -14,7 +13,7 @@ namespace util namespace maplibre { -boost::units::quantity +units::length::meters GetMapDistance(const QMapLibreGL::CustomLayerRenderParameters& params); glm::vec2 LatLongToScreenCoordinate(const QMapLibreGL::Coordinate& coordinate); diff --git a/wxdata/include/scwx/gr/placefile.hpp b/wxdata/include/scwx/gr/placefile.hpp index 8330aa4f..10ea2802 100644 --- a/wxdata/include/scwx/gr/placefile.hpp +++ b/wxdata/include/scwx/gr/placefile.hpp @@ -9,9 +9,8 @@ #include #include -#include -#include -#include +#include +#include namespace scwx { @@ -71,22 +70,22 @@ public: struct DrawItem { - ItemType itemType_ {ItemType::Unknown}; - boost::units::quantity threshold_ {}; + ItemType itemType_ {ItemType::Unknown}; + units::length::nautical_miles threshold_ {}; }; struct IconDrawItem : DrawItem { IconDrawItem() { itemType_ = ItemType::Icon; } - double latitude_ {}; - double longitude_ {}; - double x_ {}; - double y_ {}; - boost::units::quantity angle_ {}; - std::size_t fileNumber_ {0u}; - std::size_t iconNumber_ {0u}; - std::string hoverText_ {}; + double latitude_ {}; + double longitude_ {}; + double x_ {}; + double y_ {}; + units::degrees angle_ {}; + std::size_t fileNumber_ {0u}; + std::size_t iconNumber_ {0u}; + std::string hoverText_ {}; }; struct TextDrawItem : DrawItem diff --git a/wxdata/source/scwx/gr/placefile.cpp b/wxdata/source/scwx/gr/placefile.cpp index 1725dd64..5c86f319 100644 --- a/wxdata/source/scwx/gr/placefile.cpp +++ b/wxdata/source/scwx/gr/placefile.cpp @@ -9,7 +9,8 @@ #include #include -#include + +using namespace units::literals; namespace scwx { @@ -58,11 +59,10 @@ public: std::chrono::seconds refresh_ {-1}; // Parsing state - boost::units::quantity threshold_ { - 999.0 * boost::units::metric::nautical_mile_base_unit::unit_type()}; - boost::gil::rgba8_pixel_t color_ {255, 255, 255, 255}; - ColorMode colorMode_ {ColorMode::RGBA}; - std::vector objectStack_ {}; + units::length::nautical_miles threshold_ {999.0_nmi}; + boost::gil::rgba8_pixel_t color_ {255, 255, 255, 255}; + ColorMode colorMode_ {ColorMode::RGBA}; + std::vector objectStack_ {}; DrawingStatement currentStatement_ {DrawingStatement::Standard}; std::shared_ptr currentDrawItem_ {nullptr}; std::vector currentPolygonContour_ {}; @@ -245,9 +245,7 @@ void Placefile::Impl::ProcessLine(const std::string& line) if (tokenList.size() >= 1) { threshold_ = - static_cast>( - std::stod(tokenList[0]) * - boost::units::metric::nautical_mile_base_unit::unit_type()); + units::length::nautical_miles(std::stod(tokenList[0])); } } else if (boost::istarts_with(line, timeRangeKey_)) @@ -384,10 +382,7 @@ void Placefile::Impl::ProcessLine(const std::string& line) di->x_, di->y_); - di->angle_ = static_cast< - boost::units::quantity>( - std::stod(tokenList[2]) * - boost::units::angle::degree_base_unit::unit_type()); + di->angle_ = units::angle::degrees(std::stod(tokenList[2])); di->fileNumber_ = std::stoul(tokenList[3]); di->iconNumber_ = std::stoul(tokenList[4]); diff --git a/wxdata/wxdata.cmake b/wxdata/wxdata.cmake index a9a8dce7..38ffd1b0 100644 --- a/wxdata/wxdata.cmake +++ b/wxdata/wxdata.cmake @@ -259,7 +259,8 @@ target_link_libraries(wxdata PUBLIC aws-cpp-sdk-core aws-cpp-sdk-s3 cpr::cpr LibXml2::LibXml2 - spdlog::spdlog) + spdlog::spdlog + units::units) target_link_libraries(wxdata INTERFACE Boost::iostreams BZip2::BZip2 hsluv-c)