mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:10:06 +00:00
Merge pull request #32 from dpaulat/feature/linux
Add support for Linux
This commit is contained in:
commit
331fc84794
76 changed files with 653 additions and 305 deletions
36
.github/workflows/ci.yml
vendored
36
.github/workflows/ci.yml
vendored
|
|
@ -4,11 +4,9 @@ on:
|
|||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'develop'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'develop'
|
||||
|
||||
concurrency:
|
||||
|
|
@ -24,6 +22,8 @@ jobs:
|
|||
- name: win64_msvc2022
|
||||
os: windows-2022
|
||||
build_type: Release
|
||||
env_cc: ''
|
||||
env_cxx: ''
|
||||
compiler: msvc
|
||||
msvc_arch: x64
|
||||
msvc_toolset: 14.34
|
||||
|
|
@ -34,8 +34,28 @@ jobs:
|
|||
conan_arch: x86_64
|
||||
conan_compiler: Visual Studio
|
||||
conan_compiler_version: 17
|
||||
conan_compiler_runtime: MD
|
||||
conan_compiler_runtime: --settings compiler.runtime=MD
|
||||
conan_package_manager: ''
|
||||
artifact_suffix: windows-x64
|
||||
- name: linux64_gcc
|
||||
os: ubuntu-22.04
|
||||
build_type: Release
|
||||
env_cc: gcc-11
|
||||
env_cxx: g++-11
|
||||
compiler: gcc
|
||||
qt_version: 6.4.2
|
||||
qt_arch: gcc_64
|
||||
qt_tools: ''
|
||||
conan_arch: x86_64
|
||||
conan_compiler: gcc
|
||||
conan_compiler_version: 11
|
||||
conan_compiler_runtime: ''
|
||||
conan_package_manager: --conf tools.system.package_manager:mode=install --conf tools.system.package_manager:sudo=True
|
||||
artifact_suffix: linux-x64
|
||||
name: ${{ matrix.name }}
|
||||
env:
|
||||
CC: ${{ matrix.env_cc }}
|
||||
CXX: ${{ matrix.env_cxx }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
|
|
@ -63,6 +83,13 @@ jobs:
|
|||
toolset: ${{ matrix.msvc_toolset }}
|
||||
vsversion: ${{ matrix.msvc_version }}
|
||||
|
||||
- name: Setup Ubuntu Environment
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get install doxygen \
|
||||
ninja-build
|
||||
|
||||
- name: Setup Python Environment
|
||||
shell: pwsh
|
||||
run: |
|
||||
|
|
@ -81,7 +108,8 @@ jobs:
|
|||
--settings build_type=${{ matrix.build_type }} `
|
||||
--settings compiler="${{ matrix.conan_compiler }}" `
|
||||
--settings compiler.version=${{ matrix.conan_compiler_version }} `
|
||||
--settings compiler.runtime=${{ matrix.conan_compiler_runtime }}
|
||||
${{ matrix.conan_compiler_runtime }} `
|
||||
${{ matrix.conan_package_manager }}
|
||||
|
||||
- name: Build Supercell Wx
|
||||
shell: pwsh
|
||||
|
|
|
|||
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -28,3 +28,6 @@
|
|||
[submodule "external/aws-sdk-cpp"]
|
||||
path = external/aws-sdk-cpp
|
||||
url = https://github.com/aws/aws-sdk-cpp.git
|
||||
[submodule "external/date"]
|
||||
path = external/date
|
||||
url = https://github.com/HowardHinnant/date.git
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ Supercell Wx uses code from the following dependencies:
|
|||
| [cmake-conan](https://github.com/conan-io/cmake-conan) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [cpr](https://github.com/libcpr/cpr) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [CSS Color Parser](https://github.com/deanm/css-color-parser-js) | [MIT License](https://spdx.org/licenses/MIT.html) | Ported to C++ for MapLibre GL Native |
|
||||
| [Date](https://github.com/HowardHinnant/date) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [Dear ImGui](https://github.com/ocornut/imgui) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [FreeType](https://freetype.org/) | [Freetype Project License](https://spdx.org/licenses/FTL.html) |
|
||||
| [FreeType GL](https://github.com/rougier/freetype-gl) | [BSD 2-Clause with views sentence](https://spdx.org/licenses/BSD-2-Clause-Views.html) |
|
||||
|
|
|
|||
15
README.md
15
README.md
|
|
@ -1,12 +1,23 @@
|
|||
# Supercell Wx
|
||||
|
||||
[](https://github.com/dpaulat/supercell-wx/actions/workflows/ci.yml)
|
||||
[](https://github.com/dpaulat/supercell-wx/actions/workflows/ci.yml)
|
||||
[](https://supercell-wx.readthedocs.io/en/latest/?badge=latest)
|
||||
[](https://discord.gg/snH4tNav7g)
|
||||
|
||||
Supercell Wx is a free, open source application to visualize live NEXRAD Level 2
|
||||
and Level 3 data, and severe weather alerts. It displays continously updating
|
||||
and Level 3 data, and severe weather alerts. It displays continuously updating
|
||||
weather data on top of a responsive map, providing the capability to monitor
|
||||
weather events using reflectivity, velocity, and other products.
|
||||
|
||||

|
||||
|
||||
## Supported Platforms
|
||||
|
||||
Supercell Wx supports the following 64-bit operating systems:
|
||||
|
||||
- Windows 10 (1809 or later)
|
||||
- Windows 11
|
||||
- Linux
|
||||
- Ubuntu 22.04+
|
||||
- Fedora Linux 34+
|
||||
- Most distributions supporting the GCC Standard C++ Library 11+
|
||||
|
|
|
|||
2
external/CMakeLists.txt
vendored
2
external/CMakeLists.txt
vendored
|
|
@ -5,6 +5,7 @@ set_property(DIRECTORY
|
|||
APPEND
|
||||
PROPERTY CMAKE_CONFIGURE_DEPENDS
|
||||
aws-sdk-cpp.cmake
|
||||
date.cmake
|
||||
freetype-gl.cmake
|
||||
hsluv-c.cmake
|
||||
imgui.cmake
|
||||
|
|
@ -12,6 +13,7 @@ set_property(DIRECTORY
|
|||
stb.cmake)
|
||||
|
||||
include(aws-sdk-cpp.cmake)
|
||||
include(date.cmake)
|
||||
include(freetype-gl.cmake)
|
||||
include(hsluv-c.cmake)
|
||||
include(imgui.cmake)
|
||||
|
|
|
|||
1
external/date
vendored
Submodule
1
external/date
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 50acf3ffd8b09deeec6980be824f2ac54a50b095
|
||||
7
external/date.cmake
vendored
Normal file
7
external/date.cmake
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
set(PROJECT_NAME scwx-date)
|
||||
|
||||
set(USE_SYSTEM_TZ_DB ON)
|
||||
set(BUILD_TZ_LIB ON)
|
||||
|
||||
add_subdirectory(date)
|
||||
1
external/mapbox-gl-native.cmake
vendored
1
external/mapbox-gl-native.cmake
vendored
|
|
@ -3,6 +3,7 @@ set(PROJECT_NAME scwx-mbgl)
|
|||
|
||||
set(gtest_disable_pthreads ON)
|
||||
set(MBGL_WITH_QT ON)
|
||||
set(MBGL_QT_WITH_INTERNAL_ICU ON)
|
||||
add_subdirectory(mapbox-gl-native)
|
||||
|
||||
find_package(ZLIB)
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ target_link_libraries(scwx-qt PUBLIC Qt${QT_VERSION_MAJOR}::Widgets
|
|||
Boost::json
|
||||
Boost::timer
|
||||
qmaplibregl
|
||||
opengl32
|
||||
$<$<CXX_COMPILER_ID:MSVC>:opengl32>
|
||||
freetype-gl
|
||||
GeographicLib::GeographicLib
|
||||
glm::glm
|
||||
|
|
@ -389,8 +389,12 @@ install(TARGETS supercell-wx
|
|||
RUNTIME_DEPENDENCIES
|
||||
PRE_EXCLUDE_REGEXES "api-ms-" "ext-ms-" "qt6"
|
||||
POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
|
||||
"^(/usr)?/lib/.*\\.so(\\..*)?"
|
||||
RUNTIME
|
||||
COMPONENT supercell-wx)
|
||||
COMPONENT supercell-wx
|
||||
LIBRARY
|
||||
COMPONENT supercell-wx
|
||||
OPTIONAL)
|
||||
|
||||
qt_generate_deploy_app_script(TARGET qmaplibregl
|
||||
FILENAME_VARIABLE deploy_script_qmaplibregl
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ static bool initialized_ {false};
|
|||
static std::unordered_map<std::string, std::string> countyMap_;
|
||||
static std::shared_mutex countyMutex_;
|
||||
|
||||
void CountyDatabase::Initialize()
|
||||
void Initialize()
|
||||
{
|
||||
if (initialized_)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include <scwx/common/sites.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <format>
|
||||
#include <shared_mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
|
|
@ -118,18 +117,18 @@ std::string RadarSite::location_name() const
|
|||
|
||||
if (p->country_ == "USA")
|
||||
{
|
||||
locationName = std::format("{}, {}", p->place_, p->state_);
|
||||
locationName = fmt::format("{}, {}", p->place_, p->state_);
|
||||
}
|
||||
else if (std::all_of(p->state_.cbegin(),
|
||||
p->state_.cend(),
|
||||
[](char c) { return std::isdigit(c); }))
|
||||
{
|
||||
locationName = std::format("{}, {}", p->place_, p->country_);
|
||||
locationName = fmt::format("{}, {}", p->place_, p->country_);
|
||||
}
|
||||
else
|
||||
{
|
||||
locationName =
|
||||
std::format("{}, {}, {}", p->place_, p->state_, p->country_);
|
||||
fmt::format("{}, {}, {}", p->place_, p->state_, p->country_);
|
||||
}
|
||||
|
||||
return locationName;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,18 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
|
|||
|
|
@ -255,8 +255,8 @@ void GeoLine::Impl::Update()
|
|||
const float ty = points_[1].longitude_;
|
||||
|
||||
// Offset x/y in pixels
|
||||
const float ox = width_ * 0.5f * std::cosf(angle_);
|
||||
const float oy = width_ * 0.5f * std::sinf(angle_);
|
||||
const float ox = width_ * 0.5f * cosf(angle_);
|
||||
const float oy = width_ * 0.5f * sinf(angle_);
|
||||
|
||||
// Texture coordinates
|
||||
const float ls = texture_.sLeft_;
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ public:
|
|||
z_ {0.0f},
|
||||
width_ {0.0f},
|
||||
height_ {0.0f},
|
||||
borderColor_ {0, 0, 0, 0},
|
||||
borderWidth_ {0.0f},
|
||||
borderColor_ {0, 0, 0, 0},
|
||||
fillColor_ {std::nullopt},
|
||||
shaderProgram_ {nullptr},
|
||||
uMVPMatrixLocation_(GL_INVALID_INDEX),
|
||||
|
|
|
|||
|
|
@ -2,9 +2,15 @@
|
|||
#include <scwx/qt/gl/shader_program.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#include <scwx/qt/main/application.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <condition_variable>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@
|
|||
#include <QStandardPaths>
|
||||
#include <QToolButton>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <date/date.h>
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
|
|
@ -265,14 +269,14 @@ void MainWindow::on_actionOpenNexrad_triggered()
|
|||
dialog,
|
||||
&QFileDialog::finished,
|
||||
this,
|
||||
[=]() { update(); },
|
||||
[this]() { update(); },
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(
|
||||
dialog,
|
||||
&QFileDialog::fileSelected,
|
||||
this,
|
||||
[=](const QString& file)
|
||||
[=, this](const QString& file)
|
||||
{
|
||||
logger_->info("Selected: {}", file.toStdString());
|
||||
|
||||
|
|
@ -283,7 +287,7 @@ void MainWindow::on_actionOpenNexrad_triggered()
|
|||
request.get(),
|
||||
&request::NexradFileRequest::RequestComplete,
|
||||
this,
|
||||
[=](std::shared_ptr<request::NexradFileRequest> request)
|
||||
[=, this](std::shared_ptr<request::NexradFileRequest> request)
|
||||
{
|
||||
std::shared_ptr<types::RadarProductRecord> record =
|
||||
request->radar_product_record();
|
||||
|
|
@ -327,13 +331,13 @@ void MainWindow::on_actionOpenTextEvent_triggered()
|
|||
dialog,
|
||||
&QFileDialog::finished,
|
||||
this,
|
||||
[=]() { update(); },
|
||||
[this]() { update(); },
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(dialog,
|
||||
&QFileDialog::fileSelected,
|
||||
this,
|
||||
[=](const QString& file)
|
||||
[this](const QString& file)
|
||||
{
|
||||
logger_->info("Selected: {}", file.toStdString());
|
||||
p->textEventManager_->LoadFile(file.toStdString());
|
||||
|
|
@ -407,8 +411,14 @@ void MainWindow::on_resourceTreeView_doubleClicked(const QModelIndex& index)
|
|||
|
||||
static const std::string timeFormat {"%Y-%m-%d %H:%M:%S"};
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
using namespace date;
|
||||
#endif
|
||||
|
||||
std::istringstream in {selectedString};
|
||||
in >> std::chrono::parse(timeFormat, time);
|
||||
in >> parse(timeFormat, time);
|
||||
|
||||
if (in.fail())
|
||||
{
|
||||
|
|
@ -473,7 +483,7 @@ void MainWindowImpl::ConfigureMapLayout()
|
|||
|
||||
maps_.resize(mapCount);
|
||||
|
||||
auto MoveSplitter = [=](int /*pos*/, int /*index*/)
|
||||
auto MoveSplitter = [=, this](int /*pos*/, int /*index*/)
|
||||
{
|
||||
QSplitter* s = static_cast<QSplitter*>(sender());
|
||||
|
||||
|
|
@ -565,7 +575,7 @@ void MainWindowImpl::ConnectOtherSignals()
|
|||
connect(qApp,
|
||||
&QApplication::focusChanged,
|
||||
mainWindow_,
|
||||
[=](QWidget* /*old*/, QWidget* now) { HandleFocusChange(now); });
|
||||
[this](QWidget* /*old*/, QWidget* now) { HandleFocusChange(now); });
|
||||
connect(level2ProductsWidget_,
|
||||
&ui::Level2ProductsWidget::RadarProductSelected,
|
||||
mainWindow_,
|
||||
|
|
@ -595,7 +605,7 @@ void MainWindowImpl::ConnectOtherSignals()
|
|||
alertDockWidget_,
|
||||
&ui::AlertDockWidget::MoveMap,
|
||||
this,
|
||||
[=](double latitude, double longitude)
|
||||
[this](double latitude, double longitude)
|
||||
{
|
||||
for (map::MapWidget* map : maps_)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,14 +14,20 @@
|
|||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/range/irange.hpp>
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include <fmt/chrono.h>
|
||||
#include <QMapLibreGL/QMapLibreGL>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -254,14 +260,14 @@ std::string ProviderManager::name() const
|
|||
|
||||
if (group_ == common::RadarProductGroup::Level3)
|
||||
{
|
||||
name = std::format("{}, {}, {}",
|
||||
name = fmt::format("{}, {}, {}",
|
||||
radarId_,
|
||||
common::GetRadarProductGroupName(group_),
|
||||
product_);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = std::format(
|
||||
name = fmt::format(
|
||||
"{}, {}", radarId_, common::GetRadarProductGroupName(group_));
|
||||
}
|
||||
|
||||
|
|
@ -356,7 +362,7 @@ RadarProductManager::coordinates(common::RadialSize radialSize) const
|
|||
return p->coordinates1Degree_;
|
||||
}
|
||||
|
||||
throw std::exception("Invalid radial size");
|
||||
throw std::invalid_argument("Invalid radial size");
|
||||
}
|
||||
|
||||
float RadarProductManager::gate_size() const
|
||||
|
|
@ -506,7 +512,7 @@ void RadarProductManager::EnableRefresh(common::RadarProductGroup group,
|
|||
|
||||
// Only enable refresh on available products
|
||||
scwx::util::async(
|
||||
[=]()
|
||||
[=, this]()
|
||||
{
|
||||
providerManager->provider_->RequestAvailableProducts();
|
||||
auto availableProducts =
|
||||
|
|
@ -597,7 +603,7 @@ void RadarProductManagerImpl::RefreshData(
|
|||
}
|
||||
|
||||
scwx::util::async(
|
||||
[=]()
|
||||
[=, this]()
|
||||
{
|
||||
auto [newObjects, totalObjects] =
|
||||
providerManager->provider_->Refresh();
|
||||
|
|
@ -647,7 +653,7 @@ void RadarProductManagerImpl::RefreshData(
|
|||
{
|
||||
providerManager->refreshTimer_.expires_after(interval);
|
||||
providerManager->refreshTimer_.async_wait(
|
||||
[=](const boost::system::error_code& e)
|
||||
[=, this](const boost::system::error_code& e)
|
||||
{
|
||||
if (e == boost::system::errc::success)
|
||||
{
|
||||
|
|
@ -1151,7 +1157,7 @@ void RadarProductManager::UpdateAvailableProducts()
|
|||
logger_->debug("UpdateAvailableProducts()");
|
||||
|
||||
scwx::util::async(
|
||||
[=]()
|
||||
[this]()
|
||||
{
|
||||
auto level3ProviderManager =
|
||||
p->GetLevel3ProviderManager(kDefaultLevel3Product_);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public:
|
|||
warningsProvider_ {kDefaultWarningsProviderUrl}
|
||||
{
|
||||
util::async(
|
||||
[=]()
|
||||
[this]()
|
||||
{
|
||||
main::Application::WaitForInitialization();
|
||||
logger_->debug("Start Refresh");
|
||||
|
|
@ -105,7 +105,7 @@ void TextEventManager::LoadFile(const std::string& filename)
|
|||
logger_->debug("LoadFile: {}", filename);
|
||||
|
||||
util::async(
|
||||
[=]()
|
||||
[=, this]()
|
||||
{
|
||||
awips::TextProductFile file;
|
||||
|
||||
|
|
@ -217,7 +217,7 @@ void TextEventManager::Impl::Refresh()
|
|||
using namespace std::chrono;
|
||||
refreshTimer_.expires_after(15s);
|
||||
refreshTimer_.async_wait(
|
||||
[=](const boost::system::error_code& e)
|
||||
[this](const boost::system::error_code& e)
|
||||
{
|
||||
if (e == boost::asio::error::operation_aborted)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ void AlertLayerHandler::UpdateAlerts()
|
|||
using namespace std::chrono;
|
||||
alertUpdateTimer_.expires_after(15s);
|
||||
alertUpdateTimer_.async_wait(
|
||||
[=](const boost::system::error_code& e)
|
||||
[this](const boost::system::error_code& e)
|
||||
{
|
||||
if (e == boost::asio::error::operation_aborted)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,10 +2,16 @@
|
|||
#include <scwx/qt/gl/shader_program.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -20,12 +26,13 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
|||
class ColorTableLayerImpl
|
||||
{
|
||||
public:
|
||||
explicit ColorTableLayerImpl(std::shared_ptr<MapContext> context) :
|
||||
explicit ColorTableLayerImpl() :
|
||||
shaderProgram_(nullptr),
|
||||
uMVPMatrixLocation_(GL_INVALID_INDEX),
|
||||
vbo_ {GL_INVALID_INDEX},
|
||||
vao_ {GL_INVALID_INDEX},
|
||||
texture_ {GL_INVALID_INDEX},
|
||||
colorTable_ {},
|
||||
colorTableNeedsUpdate_ {true}
|
||||
{
|
||||
}
|
||||
|
|
@ -44,7 +51,7 @@ public:
|
|||
};
|
||||
|
||||
ColorTableLayer::ColorTableLayer(std::shared_ptr<MapContext> context) :
|
||||
GenericLayer(context), p(std::make_unique<ColorTableLayerImpl>(context))
|
||||
GenericLayer(context), p(std::make_unique<ColorTableLayerImpl>())
|
||||
{
|
||||
}
|
||||
ColorTableLayer::~ColorTableLayer() = default;
|
||||
|
|
@ -104,7 +111,7 @@ void ColorTableLayer::Initialize()
|
|||
connect(context()->radar_product_view().get(),
|
||||
&view::RadarProductView::ColorTableUpdated,
|
||||
this,
|
||||
[=]() { p->colorTableNeedsUpdate_ = true; });
|
||||
[this]() { p->colorTableNeedsUpdate_ = true; });
|
||||
}
|
||||
|
||||
void ColorTableLayer::Render(
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <backends/imgui_impl_opengl3.h>
|
||||
#include <backends/imgui_impl_qt.hpp>
|
||||
#include <boost/uuid/random_generator.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <imgui.h>
|
||||
#include <QApplication>
|
||||
#include <QColor>
|
||||
|
|
@ -89,7 +90,7 @@ public:
|
|||
|
||||
// Create ImGui Context
|
||||
static size_t currentMapId_ {0u};
|
||||
imGuiContextName_ = std::format("Map {}", ++currentMapId_);
|
||||
imGuiContextName_ = fmt::format("Map {}", ++currentMapId_);
|
||||
imGuiContext_ =
|
||||
model::ImGuiContextModel::Instance().CreateContext(imGuiContextName_);
|
||||
|
||||
|
|
@ -501,8 +502,8 @@ void MapWidget::SetMapLocation(double latitude,
|
|||
double longitude,
|
||||
bool updateRadarSite)
|
||||
{
|
||||
if (p->map_ != nullptr && p->prevLatitude_ != latitude ||
|
||||
p->prevLongitude_ != longitude)
|
||||
if (p->map_ != nullptr &&
|
||||
(p->prevLatitude_ != latitude || p->prevLongitude_ != longitude))
|
||||
{
|
||||
// Update the map location
|
||||
p->map_->setCoordinate({latitude, longitude});
|
||||
|
|
@ -786,6 +787,9 @@ void MapWidget::mapChanged(QMapLibreGL::Map::MapChange mapChange)
|
|||
case QMapLibreGL::Map::MapChangeDidFinishLoadingStyle:
|
||||
AddLayers();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -796,15 +800,15 @@ void MapWidgetImpl::RadarProductManagerConnect()
|
|||
connect(radarProductManager_.get(),
|
||||
&manager::RadarProductManager::Level3ProductsChanged,
|
||||
this,
|
||||
[&]() { emit widget_->Level3ProductsChanged(); });
|
||||
[this]() { emit widget_->Level3ProductsChanged(); });
|
||||
|
||||
connect(
|
||||
radarProductManager_.get(),
|
||||
&manager::RadarProductManager::NewDataAvailable,
|
||||
this,
|
||||
[&](common::RadarProductGroup group,
|
||||
const std::string& product,
|
||||
std::chrono::system_clock::time_point latestTime)
|
||||
[this](common::RadarProductGroup group,
|
||||
const std::string& product,
|
||||
std::chrono::system_clock::time_point latestTime)
|
||||
{
|
||||
if (autoRefreshEnabled_ &&
|
||||
context_->radar_product_group() == group &&
|
||||
|
|
@ -816,23 +820,24 @@ void MapWidgetImpl::RadarProductManagerConnect()
|
|||
std::make_shared<request::NexradFileRequest>();
|
||||
|
||||
// File request callback
|
||||
connect(request.get(),
|
||||
&request::NexradFileRequest::RequestComplete,
|
||||
this,
|
||||
[&](std::shared_ptr<request::NexradFileRequest> request)
|
||||
{
|
||||
// Select loaded record
|
||||
auto record = request->radar_product_record();
|
||||
connect(
|
||||
request.get(),
|
||||
&request::NexradFileRequest::RequestComplete,
|
||||
this,
|
||||
[this](std::shared_ptr<request::NexradFileRequest> request)
|
||||
{
|
||||
// Select loaded record
|
||||
auto record = request->radar_product_record();
|
||||
|
||||
if (record != nullptr)
|
||||
{
|
||||
widget_->SelectRadarProduct(record);
|
||||
}
|
||||
});
|
||||
if (record != nullptr)
|
||||
{
|
||||
widget_->SelectRadarProduct(record);
|
||||
}
|
||||
});
|
||||
|
||||
// Load file
|
||||
scwx::util::async(
|
||||
[=]()
|
||||
[=, this]()
|
||||
{
|
||||
if (group == common::RadarProductGroup::Level2)
|
||||
{
|
||||
|
|
@ -866,7 +871,7 @@ void MapWidgetImpl::InitializeNewRadarProductView(
|
|||
const std::string& colorPalette)
|
||||
{
|
||||
scwx::util::async(
|
||||
[=]()
|
||||
[=, this]()
|
||||
{
|
||||
auto radarProductView = context_->radar_product_view();
|
||||
|
||||
|
|
@ -902,13 +907,13 @@ void MapWidgetImpl::RadarProductViewConnect()
|
|||
radarProductView.get(),
|
||||
&view::RadarProductView::ColorTableUpdated,
|
||||
this,
|
||||
[&]() { widget_->update(); },
|
||||
[this]() { widget_->update(); },
|
||||
Qt::QueuedConnection);
|
||||
connect(
|
||||
radarProductView.get(),
|
||||
&view::RadarProductView::SweepComputed,
|
||||
this,
|
||||
[=]()
|
||||
[=, this]()
|
||||
{
|
||||
std::shared_ptr<config::RadarSite> radarSite =
|
||||
radarProductManager_->radar_site();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@
|
|||
#include <chrono>
|
||||
#include <execution>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include <boost/date_time.hpp>
|
||||
#include <boost/date_time/local_time/local_time.hpp>
|
||||
#include <boost/timer/timer.hpp>
|
||||
|
|
@ -18,7 +21,14 @@
|
|||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <imgui.h>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <date/date.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -89,16 +99,19 @@ void OverlayLayer::Render(
|
|||
|
||||
if (p->sweepTimeNeedsUpdate_ && radarProductView != nullptr)
|
||||
{
|
||||
const scwx::util::time_zone* currentZone;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
currentZone = std::chrono::current_zone();
|
||||
#else
|
||||
currentZone = date::current_zone();
|
||||
#endif
|
||||
|
||||
p->sweepTimeString_ = scwx::util::TimeString(
|
||||
radarProductView->sweep_time(), std::chrono::current_zone(), false);
|
||||
radarProductView->sweep_time(), currentZone, false);
|
||||
p->sweepTimeNeedsUpdate_ = false;
|
||||
}
|
||||
|
||||
glm::mat4 projection = glm::ortho(0.0f,
|
||||
static_cast<float>(params.width),
|
||||
0.0f,
|
||||
static_cast<float>(params.height));
|
||||
|
||||
// Active Box
|
||||
p->activeBoxOuter_->SetVisible(settings.isActive_);
|
||||
p->activeBoxInner_->SetVisible(settings.isActive_);
|
||||
|
|
@ -121,7 +134,7 @@ void OverlayLayer::Render(
|
|||
nullptr,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_AlwaysAutoResize);
|
||||
ImGui::Text(productName.c_str());
|
||||
ImGui::TextUnformatted(productName.c_str());
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
|
@ -136,7 +149,7 @@ void OverlayLayer::Render(
|
|||
nullptr,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_AlwaysAutoResize);
|
||||
ImGui::Text(p->sweepTimeString_.c_str());
|
||||
ImGui::TextUnformatted(p->sweepTimeString_.c_str());
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,19 @@
|
|||
|
||||
#include <execution>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -31,7 +37,7 @@ LatLongToScreenCoordinate(const QMapLibreGL::Coordinate& coordinate);
|
|||
class RadarProductLayerImpl
|
||||
{
|
||||
public:
|
||||
explicit RadarProductLayerImpl(std::shared_ptr<MapContext> context) :
|
||||
explicit RadarProductLayerImpl() :
|
||||
shaderProgram_(nullptr),
|
||||
uMVPMatrixLocation_(GL_INVALID_INDEX),
|
||||
uMapScreenCoordLocation_(GL_INVALID_INDEX),
|
||||
|
|
@ -69,7 +75,7 @@ public:
|
|||
};
|
||||
|
||||
RadarProductLayer::RadarProductLayer(std::shared_ptr<MapContext> context) :
|
||||
GenericLayer(context), p(std::make_unique<RadarProductLayerImpl>(context))
|
||||
GenericLayer(context), p(std::make_unique<RadarProductLayerImpl>())
|
||||
{
|
||||
}
|
||||
RadarProductLayer::~RadarProductLayer() = default;
|
||||
|
|
@ -143,11 +149,11 @@ void RadarProductLayer::Initialize()
|
|||
connect(radarProductView.get(),
|
||||
&view::RadarProductView::ColorTableUpdated,
|
||||
this,
|
||||
[=]() { p->colorTableNeedsUpdate_ = true; });
|
||||
[this]() { p->colorTableNeedsUpdate_ = true; });
|
||||
connect(radarProductView.get(),
|
||||
&view::RadarProductView::SweepComputed,
|
||||
this,
|
||||
[=]() { p->sweepNeedsUpdate_ = true; });
|
||||
[this]() { p->sweepNeedsUpdate_ = true; });
|
||||
}
|
||||
|
||||
void RadarProductLayer::UpdateSweep()
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void AlertProxyModelImpl::UpdateAlerts()
|
|||
using namespace std::chrono;
|
||||
alertUpdateTimer_.expires_after(15s);
|
||||
alertUpdateTimer_.async_wait(
|
||||
[=](const boost::system::error_code& e)
|
||||
[this](const boost::system::error_code& e)
|
||||
{
|
||||
if (e == boost::asio::error::operation_aborted)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ QVariant ImGuiContextModel::data(const QModelIndex& index, int role) const
|
|||
}
|
||||
|
||||
const int row = index.row();
|
||||
if (row >= p->contexts_.size() || row < 0)
|
||||
if (row >= static_cast<int>(p->contexts_.size()) || row < 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ RadarProductModelImpl::RadarProductModelImpl(RadarProductModel* self) :
|
|||
&manager::RadarProductManagerNotifier::Instance(),
|
||||
&manager::RadarProductManagerNotifier::RadarProductManagerCreated,
|
||||
this,
|
||||
[=](const std::string& radarSite)
|
||||
[this](const std::string& radarSite)
|
||||
{
|
||||
logger_->debug("Adding radar site: {}", radarSite);
|
||||
|
||||
|
|
@ -67,9 +67,9 @@ RadarProductModelImpl::RadarProductModelImpl(RadarProductModel* self) :
|
|||
manager::RadarProductManager::Instance(radarSite).get(),
|
||||
&manager::RadarProductManager::NewDataAvailable,
|
||||
this,
|
||||
[=](common::RadarProductGroup group,
|
||||
const std::string& product,
|
||||
std::chrono::system_clock::time_point latestTime)
|
||||
[=, this](common::RadarProductGroup group,
|
||||
const std::string& product,
|
||||
std::chrono::system_clock::time_point latestTime)
|
||||
{
|
||||
const QString groupName {QString::fromStdString(
|
||||
common::GetRadarProductGroupName(group))};
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
#include <scwx/common/geographic.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <format>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ int TreeItem::column_count() const
|
|||
|
||||
QVariant TreeItem::data(int column) const
|
||||
{
|
||||
if (0 <= column && column < p->itemData_.size())
|
||||
if (0 <= column && column < static_cast<int>(p->itemData_.size()))
|
||||
{
|
||||
return p->itemData_[column];
|
||||
}
|
||||
|
|
@ -152,7 +152,7 @@ bool TreeItem::InsertChildren(int position, int count, int columns)
|
|||
|
||||
bool TreeItem::SetData(int column, const QVariant& value)
|
||||
{
|
||||
if (column < 0 || column >= p->itemData_.size())
|
||||
if (column < 0 || column >= static_cast<int>(p->itemData_.size()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
#include <scwx/qt/settings/settings_variable.hpp>
|
||||
#include <scwx/qt/util/color.hpp>
|
||||
|
||||
#include <format>
|
||||
#include <regex>
|
||||
|
||||
#include <boost/gil.hpp>
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -16,6 +16,27 @@ namespace settings
|
|||
|
||||
static const std::string logPrefix_ = "scwx::qt::settings::palette_settings";
|
||||
|
||||
static const std::array<std::string, 17> kPaletteKeys_ {
|
||||
// Level 2 / Common Products
|
||||
"BR",
|
||||
"BV",
|
||||
"SW",
|
||||
"CC",
|
||||
"ZDR",
|
||||
"PHI2",
|
||||
// Level 3 Products
|
||||
"DOD",
|
||||
"DSD",
|
||||
"ET",
|
||||
"STP",
|
||||
"OHP",
|
||||
"STPIN",
|
||||
"OHPIN",
|
||||
"PHI3",
|
||||
"SRV",
|
||||
"VIL",
|
||||
"???"};
|
||||
|
||||
static const std::unordered_map<std::string, std::string> kDefaultPalettes_ {
|
||||
// Level 2 / Common Products
|
||||
{"BR", ":/res/palettes/wct/DR.pal"},
|
||||
|
|
@ -56,10 +77,9 @@ class PaletteSettingsImpl
|
|||
public:
|
||||
explicit PaletteSettingsImpl()
|
||||
{
|
||||
for (const auto& palette : kDefaultPalettes_)
|
||||
for (const auto& name : kPaletteKeys_)
|
||||
{
|
||||
const std::string& name = palette.first;
|
||||
const std::string& defaultValue = palette.second;
|
||||
const std::string& defaultValue = kDefaultPalettes_.at(name);
|
||||
|
||||
auto result =
|
||||
palette_.emplace(name, SettingsVariable<std::string> {name});
|
||||
|
|
@ -74,8 +94,8 @@ public:
|
|||
for (auto& alert : kAlertColors_)
|
||||
{
|
||||
std::string phenomenonCode = awips::GetPhenomenonCode(alert.first);
|
||||
std::string activeName = std::format("{}-active", phenomenonCode);
|
||||
std::string inactiveName = std::format("{}-inactive", phenomenonCode);
|
||||
std::string activeName = fmt::format("{}-active", phenomenonCode);
|
||||
std::string inactiveName = fmt::format("{}-inactive", phenomenonCode);
|
||||
|
||||
auto activeResult = activeAlertColor_.emplace(
|
||||
alert.first, SettingsVariable<std::string> {activeName});
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ void SettingsInterface<T>::SetEditWidget(QWidget* widget)
|
|||
{
|
||||
// Error value
|
||||
value.push_back(
|
||||
std::numeric_limits<T::value_type>::min());
|
||||
std::numeric_limits<typename T::value_type>::min());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
#include <scwx/qt/types/text_event_key.hpp>
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -15,7 +14,7 @@ static const std::string logPrefix_ = "scwx::qt::types::text_event_key";
|
|||
|
||||
std::string TextEventKey::ToFullString() const
|
||||
{
|
||||
return std::format("{} {} {} {:04}",
|
||||
return fmt::format("{} {} {} {:04}",
|
||||
officeId_,
|
||||
awips::GetPhenomenonText(phenomenon_),
|
||||
awips::GetSignificanceText(significance_),
|
||||
|
|
@ -24,7 +23,7 @@ std::string TextEventKey::ToFullString() const
|
|||
|
||||
std::string TextEventKey::ToString() const
|
||||
{
|
||||
return std::format("{}.{}.{}.{:04}",
|
||||
return fmt::format("{}.{}.{}.{:04}",
|
||||
officeId_,
|
||||
awips::GetPhenomenonCode(phenomenon_),
|
||||
awips::GetSignificanceCode(significance_),
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ void AlertDialogImpl::ConnectSignals()
|
|||
textEventManager_.get(),
|
||||
&manager::TextEventManager::AlertUpdated,
|
||||
this,
|
||||
[=](const types::TextEventKey& key)
|
||||
[this](const types::TextEventKey& key)
|
||||
{
|
||||
if (key == key_)
|
||||
{
|
||||
|
|
@ -85,7 +85,7 @@ void AlertDialogImpl::ConnectSignals()
|
|||
connect(goButton_,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
[=]()
|
||||
[this]()
|
||||
{
|
||||
emit self_->MoveMap(centroid_.latitude_, centroid_.longitude_);
|
||||
self_->close();
|
||||
|
|
|
|||
|
|
@ -127,48 +127,48 @@ void AlertDockWidgetImpl::ConnectSignals()
|
|||
alertModel_.get(),
|
||||
&model::AlertModel::HandleAlert,
|
||||
Qt::QueuedConnection);
|
||||
connect(self_->ui->alertView->selectionModel(),
|
||||
&QItemSelectionModel::selectionChanged,
|
||||
this,
|
||||
[=](const QItemSelection& selected, const QItemSelection& deselected)
|
||||
{
|
||||
if (selected.size() == 0 && deselected.size() == 0)
|
||||
{
|
||||
// Items which stay selected but change their index are not
|
||||
// included in selected and deselected. Thus, this signal might
|
||||
// be emitted with both selected and deselected empty, if only
|
||||
// the indices of selected items change.
|
||||
return;
|
||||
}
|
||||
connect(
|
||||
self_->ui->alertView->selectionModel(),
|
||||
&QItemSelectionModel::selectionChanged,
|
||||
this,
|
||||
[this](const QItemSelection& selected, const QItemSelection& deselected)
|
||||
{
|
||||
if (selected.size() == 0 && deselected.size() == 0)
|
||||
{
|
||||
// Items which stay selected but change their index are not
|
||||
// included in selected and deselected. Thus, this signal might
|
||||
// be emitted with both selected and deselected empty, if only
|
||||
// the indices of selected items change.
|
||||
return;
|
||||
}
|
||||
|
||||
bool itemSelected = selected.size() > 0;
|
||||
bool itemHasCoordinates = false;
|
||||
bool itemSelected = selected.size() > 0;
|
||||
bool itemHasCoordinates = false;
|
||||
|
||||
if (itemSelected)
|
||||
{
|
||||
QModelIndex selectedIndex =
|
||||
proxyModel_->mapToSource(selected[0].indexes()[0]);
|
||||
selectedAlertKey_ = alertModel_->key(selectedIndex);
|
||||
selectedAlertCentroid_ =
|
||||
alertModel_->centroid(selectedAlertKey_);
|
||||
itemHasCoordinates =
|
||||
selectedAlertCentroid_ != common::Coordinate {};
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedAlertKey_ = {};
|
||||
selectedAlertCentroid_ = {};
|
||||
}
|
||||
if (itemSelected)
|
||||
{
|
||||
QModelIndex selectedIndex =
|
||||
proxyModel_->mapToSource(selected[0].indexes()[0]);
|
||||
selectedAlertKey_ = alertModel_->key(selectedIndex);
|
||||
selectedAlertCentroid_ = alertModel_->centroid(selectedAlertKey_);
|
||||
itemHasCoordinates =
|
||||
selectedAlertCentroid_ != common::Coordinate {};
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedAlertKey_ = {};
|
||||
selectedAlertCentroid_ = {};
|
||||
}
|
||||
|
||||
self_->ui->alertViewButton->setEnabled(itemSelected);
|
||||
self_->ui->alertGoButton->setEnabled(itemHasCoordinates);
|
||||
self_->ui->alertViewButton->setEnabled(itemSelected);
|
||||
self_->ui->alertGoButton->setEnabled(itemHasCoordinates);
|
||||
|
||||
logger_->debug("Selected: {}", selectedAlertKey_.ToString());
|
||||
});
|
||||
logger_->debug("Selected: {}", selectedAlertKey_.ToString());
|
||||
});
|
||||
connect(self_->ui->alertViewButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
[=]()
|
||||
[this]()
|
||||
{
|
||||
// View alert
|
||||
alertDialog_->SelectAlert(selectedAlertKey_);
|
||||
|
|
@ -177,7 +177,7 @@ void AlertDockWidgetImpl::ConnectSignals()
|
|||
connect(self_->ui->alertGoButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
[=]()
|
||||
[this]()
|
||||
{
|
||||
emit self_->MoveMap(selectedAlertCentroid_.latitude_,
|
||||
selectedAlertCentroid_.longitude_);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ ImGuiDebugDialog::ImGuiDebugDialog(QWidget* parent) :
|
|||
connect(
|
||||
ui->contextComboBox,
|
||||
&QComboBox::currentIndexChanged,
|
||||
[=](int row)
|
||||
[this](int row)
|
||||
{
|
||||
auto& contextModel = model::ImGuiContextModel::Instance();
|
||||
auto index = contextModel.index(row, 0);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <imgui.h>
|
||||
#include <backends/imgui_impl_opengl3.h>
|
||||
#include <backends/imgui_impl_qt.hpp>
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -23,7 +24,7 @@ public:
|
|||
{
|
||||
// Create ImGui Context
|
||||
static size_t currentIndex_ {0u};
|
||||
contextName_ = std::format("ImGui Debug {}", ++currentIndex_);
|
||||
contextName_ = fmt::format("ImGui Debug {}", ++currentIndex_);
|
||||
context_ =
|
||||
model::ImGuiContextModel::Instance().CreateContext(contextName_);
|
||||
currentContext_ = context_;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
QObject::connect(toolButton,
|
||||
&QToolButton::clicked,
|
||||
this,
|
||||
[=]() { SelectProduct(product); });
|
||||
[=, this]() { SelectProduct(product); });
|
||||
}
|
||||
}
|
||||
~Level2ProductsWidgetImpl() = default;
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ void Level2SettingsWidget::UpdateSettings(map::MapWidget* activeMap)
|
|||
connect(toolButton,
|
||||
&QToolButton::clicked,
|
||||
this,
|
||||
[=]() { p->SelectElevation(elevationCut); });
|
||||
[=, this]() { p->SelectElevation(elevationCut); });
|
||||
}
|
||||
|
||||
p->elevationCuts_ = elevationCuts;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public:
|
|||
QObject::connect(toolButton,
|
||||
&QToolButton::clicked,
|
||||
this,
|
||||
[=]() { SelectProductCategory(category); });
|
||||
[=, this]() { SelectProductCategory(category); });
|
||||
|
||||
QMenu* categoryMenu = new QMenu();
|
||||
toolButton->setMenu(categoryMenu);
|
||||
|
|
@ -79,7 +79,7 @@ public:
|
|||
action,
|
||||
&QAction::triggered,
|
||||
this,
|
||||
[=]()
|
||||
[=, this]()
|
||||
{
|
||||
std::shared_lock lock {awipsProductMutex_};
|
||||
std::string awipsProductName {awipsProductMap_.at(action)};
|
||||
|
|
|
|||
|
|
@ -72,47 +72,47 @@ RadarSiteDialog::RadarSiteDialog(QWidget* parent) :
|
|||
connect(ui->radarSiteView,
|
||||
&QTreeView::doubleClicked,
|
||||
this,
|
||||
[=]() { emit accept(); });
|
||||
connect(ui->radarSiteView->selectionModel(),
|
||||
&QItemSelectionModel::selectionChanged,
|
||||
this,
|
||||
[=](const QItemSelection& selected, const QItemSelection& deselected)
|
||||
{
|
||||
if (selected.size() == 0 && deselected.size() == 0)
|
||||
{
|
||||
// Items which stay selected but change their index are not
|
||||
// included in selected and deselected. Thus, this signal might
|
||||
// be emitted with both selected and deselected empty, if only
|
||||
// the indices of selected items change.
|
||||
return;
|
||||
}
|
||||
[this]() { emit accept(); });
|
||||
connect(
|
||||
ui->radarSiteView->selectionModel(),
|
||||
&QItemSelectionModel::selectionChanged,
|
||||
this,
|
||||
[this](const QItemSelection& selected, const QItemSelection& deselected)
|
||||
{
|
||||
if (selected.size() == 0 && deselected.size() == 0)
|
||||
{
|
||||
// Items which stay selected but change their index are not
|
||||
// included in selected and deselected. Thus, this signal might
|
||||
// be emitted with both selected and deselected empty, if only
|
||||
// the indices of selected items change.
|
||||
return;
|
||||
}
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)
|
||||
->setEnabled(selected.size() > 0);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)
|
||||
->setEnabled(selected.size() > 0);
|
||||
|
||||
if (selected.size() > 0)
|
||||
{
|
||||
QModelIndex selectedIndex =
|
||||
p->proxyModel_->mapToSource(selected[0].indexes()[0]);
|
||||
QVariant variantData = p->radarSiteModel_->data(selectedIndex);
|
||||
if (variantData.typeId() == QMetaType::QString)
|
||||
{
|
||||
p->selectedRadarSite_ =
|
||||
variantData.toString().toStdString();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger_->warn("Unexpected selection data type");
|
||||
p->selectedRadarSite_ = "?";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p->selectedRadarSite_ = "?";
|
||||
}
|
||||
if (selected.size() > 0)
|
||||
{
|
||||
QModelIndex selectedIndex =
|
||||
p->proxyModel_->mapToSource(selected[0].indexes()[0]);
|
||||
QVariant variantData = p->radarSiteModel_->data(selectedIndex);
|
||||
if (variantData.typeId() == QMetaType::QString)
|
||||
{
|
||||
p->selectedRadarSite_ = variantData.toString().toStdString();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger_->warn("Unexpected selection data type");
|
||||
p->selectedRadarSite_ = std::string {"?"};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p->selectedRadarSite_ = std::string {"?"};
|
||||
}
|
||||
|
||||
logger_->debug("Selected: {}", p->selectedRadarSite_);
|
||||
});
|
||||
logger_->debug("Selected: {}", p->selectedRadarSite_);
|
||||
});
|
||||
}
|
||||
|
||||
RadarSiteDialog::~RadarSiteDialog()
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@
|
|||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/threads.hpp>
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <QColorDialog>
|
||||
#include <QFileDialog>
|
||||
#include <QToolButton>
|
||||
|
|
@ -236,6 +235,9 @@ void SettingsDialogImpl::ConnectSignals()
|
|||
case QDialogButtonBox::ButtonRole::ResetRole: // Restore Defaults
|
||||
ResetToDefault();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -515,11 +517,13 @@ void SettingsDialogImpl::SetupPalettesAlertsTab()
|
|||
QObject::connect(activeButton,
|
||||
&QAbstractButton::clicked,
|
||||
self_,
|
||||
[=]() { ShowColorDialog(activeEdit, activeFrame); });
|
||||
[=, this]()
|
||||
{ ShowColorDialog(activeEdit, activeFrame); });
|
||||
QObject::connect(inactiveButton,
|
||||
&QAbstractButton::clicked,
|
||||
self_,
|
||||
[=]() { ShowColorDialog(inactiveEdit, inactiveFrame); });
|
||||
[=, this]()
|
||||
{ ShowColorDialog(inactiveEdit, inactiveFrame); });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -622,7 +626,7 @@ void SettingsDialogImpl::SetBackgroundColor(const std::string& value,
|
|||
QFrame* frame)
|
||||
{
|
||||
frame->setStyleSheet(
|
||||
QString::fromStdString(std::format("background-color: {}", value)));
|
||||
QString::fromStdString(fmt::format("background-color: {}", value)));
|
||||
}
|
||||
|
||||
void SettingsDialogImpl::UpdateRadarDialogLocation(const std::string& id)
|
||||
|
|
@ -676,7 +680,7 @@ void SettingsDialogImpl::ResetToDefault()
|
|||
std::string SettingsDialogImpl::RadarSiteLabel(
|
||||
std::shared_ptr<config::RadarSite>& radarSite)
|
||||
{
|
||||
return std::format("{} ({})", radarSite->id(), radarSite->location_name());
|
||||
return fmt::format("{} ({})", radarSite->id(), radarSite->location_name());
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include <scwx/qt/util/color.hpp>
|
||||
|
||||
#include <format>
|
||||
#include <fmt/format.h>
|
||||
#include <QColor>
|
||||
|
||||
namespace scwx
|
||||
|
|
@ -16,7 +16,7 @@ static const std::string logPrefix_ = "scwx::qt::util::color";
|
|||
|
||||
std::string ToArgbString(const boost::gil::rgba8_pixel_t& color)
|
||||
{
|
||||
return std::format(
|
||||
return fmt::format(
|
||||
"#{:02x}{:02x}{:02x}{:02x}", color[3], color[0], color[1], color[2]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <unordered_map>
|
||||
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <imgui.h>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
|
|
@ -22,7 +23,15 @@
|
|||
#include FT_SFNT_NAMES_H
|
||||
#include FT_TRUETYPE_IDS_H
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wpedantic"
|
||||
#endif
|
||||
|
||||
// #include <freetype-gl.h> (exclude opengl.h)
|
||||
#include <platform.h>
|
||||
#include <vec234.h>
|
||||
|
|
@ -30,7 +39,14 @@
|
|||
#include <texture-atlas.h>
|
||||
#include <texture-font.h>
|
||||
#include <ftgl-utils.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# include <WinSock2.h>
|
||||
|
|
@ -267,9 +283,9 @@ void FontImpl::CreateImGuiFont(QFile& fontFile,
|
|||
|
||||
// Assign name to font
|
||||
strncpy(fontConfig.Name,
|
||||
std::format("{}:{}", fileInfo.fileName().toStdString(), fontSize)
|
||||
fmt::format("{}:{}", fileInfo.fileName().toStdString(), fontSize)
|
||||
.c_str(),
|
||||
sizeof(fontConfig.Name));
|
||||
sizeof(fontConfig.Name) - 1);
|
||||
fontConfig.Name[sizeof(fontConfig.Name) - 1] = 0;
|
||||
|
||||
// Add font to atlas
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <streambuf>
|
||||
|
||||
namespace scwx
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,13 +5,19 @@
|
|||
#include <shared_mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#pragma warning(disable : 4714)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
# pragma warning(disable : 4714)
|
||||
#endif
|
||||
|
||||
#include <boost/gil/extension/io/png.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <stb_rect_pack.h>
|
||||
#include <QFile>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ void Level2ProductViewImpl::SetProduct(common::Level2Product product)
|
|||
|
||||
void Level2ProductView::Update()
|
||||
{
|
||||
util::async([=]() { ComputeSweep(); });
|
||||
util::async([this]() { ComputeSweep(); });
|
||||
}
|
||||
|
||||
void Level2ProductView::UpdateColorTable()
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ void Level3ProductView::LoadColorTable(
|
|||
|
||||
void Level3ProductView::Update()
|
||||
{
|
||||
util::async([=]() { ComputeSweep(); });
|
||||
util::async([this]() { ComputeSweep(); });
|
||||
}
|
||||
|
||||
void Level3ProductView::UpdateColorTable()
|
||||
|
|
|
|||
5
setup-debug.sh
Executable file
5
setup-debug.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
./tools/setup-common.sh
|
||||
mkdir -p build-debug
|
||||
cd build-debug
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CONFIGURATION_TYPES=Debug -DCMAKE_PREFIX_PATH=/opt/Qt/6.4.2/gcc_64 ..
|
||||
5
setup-release.sh
Executable file
5
setup-release.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
./tools/setup-common.sh
|
||||
mkdir -p build-release
|
||||
cd build-release
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CONFIGURATION_TYPES=Release -DCMAKE_PREFIX_PATH=/opt/Qt/6.4.2/gcc_64 ..
|
||||
5
tools/setup-common.sh
Executable file
5
tools/setup-common.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
pip install "conan<2.0"
|
||||
pip install geopandas
|
||||
pip install GitPython
|
||||
conan profile new default --detect
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <execution>
|
||||
#include <istream>
|
||||
#include <map>
|
||||
|
|
@ -24,18 +25,18 @@ class Message
|
|||
protected:
|
||||
explicit Message();
|
||||
|
||||
Message(const Message&) = delete;
|
||||
Message(const Message&) = delete;
|
||||
Message& operator=(const Message&) = delete;
|
||||
|
||||
Message(Message&&) noexcept;
|
||||
Message& operator=(Message&&) noexcept;
|
||||
|
||||
virtual bool ValidateMessage(std::istream& is, size_t bytesRead) const;
|
||||
virtual bool ValidateMessage(std::istream& is, std::size_t bytesRead) const;
|
||||
|
||||
public:
|
||||
virtual ~Message();
|
||||
|
||||
virtual size_t data_size() const = 0;
|
||||
virtual std::size_t data_size() const = 0;
|
||||
|
||||
virtual bool Parse(std::istream& is) = 0;
|
||||
|
||||
|
|
@ -55,11 +56,16 @@ public:
|
|||
|
||||
static float SwapFloat(float f)
|
||||
{
|
||||
return ntohf(*reinterpret_cast<uint32_t*>(&f));
|
||||
std::uint32_t temp;
|
||||
std::memcpy(&temp, &f, sizeof(std::uint32_t));
|
||||
temp = ntohl(temp);
|
||||
std::memcpy(&f, &temp, sizeof(float));
|
||||
return f;
|
||||
}
|
||||
|
||||
template<size_t _Size>
|
||||
static void SwapArray(std::array<float, _Size>& arr, size_t size = _Size)
|
||||
template<std::size_t _Size>
|
||||
static void SwapArray(std::array<float, _Size>& arr,
|
||||
std::size_t size = _Size)
|
||||
{
|
||||
std::transform(std::execution::par_unseq,
|
||||
arr.begin(),
|
||||
|
|
@ -68,34 +74,37 @@ public:
|
|||
[](float f) { return SwapFloat(f); });
|
||||
}
|
||||
|
||||
template<size_t _Size>
|
||||
static void SwapArray(std::array<int16_t, _Size>& arr, size_t size = _Size)
|
||||
template<std::size_t _Size>
|
||||
static void SwapArray(std::array<std::int16_t, _Size>& arr,
|
||||
std::size_t size = _Size)
|
||||
{
|
||||
std::transform(std::execution::par_unseq,
|
||||
arr.begin(),
|
||||
arr.begin() + size,
|
||||
arr.begin(),
|
||||
[](int16_t u) { return ntohs(u); });
|
||||
[](std::int16_t u) { return ntohs(u); });
|
||||
}
|
||||
|
||||
template<size_t _Size>
|
||||
static void SwapArray(std::array<uint16_t, _Size>& arr, size_t size = _Size)
|
||||
template<std::size_t _Size>
|
||||
static void SwapArray(std::array<std::uint16_t, _Size>& arr,
|
||||
std::size_t size = _Size)
|
||||
{
|
||||
std::transform(std::execution::par_unseq,
|
||||
arr.begin(),
|
||||
arr.begin() + size,
|
||||
arr.begin(),
|
||||
[](uint16_t u) { return ntohs(u); });
|
||||
[](std::uint16_t u) { return ntohs(u); });
|
||||
}
|
||||
|
||||
template<size_t _Size>
|
||||
static void SwapArray(std::array<uint32_t, _Size>& arr, size_t size = _Size)
|
||||
template<std::size_t _Size>
|
||||
static void SwapArray(std::array<std::uint32_t, _Size>& arr,
|
||||
std::size_t size = _Size)
|
||||
{
|
||||
std::transform(std::execution::par_unseq,
|
||||
arr.begin(),
|
||||
arr.begin() + size,
|
||||
arr.begin(),
|
||||
[](uint32_t u) { return ntohl(u); });
|
||||
[](std::uint32_t u) { return ntohl(u); });
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
@ -107,13 +116,13 @@ public:
|
|||
[](auto& p) { p.second = SwapFloat(p.second); });
|
||||
}
|
||||
|
||||
static void SwapVector(std::vector<uint16_t>& v)
|
||||
static void SwapVector(std::vector<std::uint16_t>& v)
|
||||
{
|
||||
std::transform(std::execution::par_unseq,
|
||||
v.begin(),
|
||||
v.end(),
|
||||
v.begin(),
|
||||
[](uint16_t u) { return ntohs(u); });
|
||||
[](std::uint16_t u) { return ntohs(u); });
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,9 +3,15 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include <spdlog/logger.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,16 +2,26 @@
|
|||
|
||||
#include <chrono>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <date/tz.h>
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef std::chrono::time_zone time_zone;
|
||||
#else
|
||||
typedef date::time_zone time_zone;
|
||||
#endif
|
||||
|
||||
std::chrono::system_clock::time_point TimePoint(uint32_t modifiedJulianDate,
|
||||
uint32_t milliseconds);
|
||||
|
||||
std::string TimeString(std::chrono::system_clock::time_point time,
|
||||
const std::chrono::time_zone* timeZone = nullptr,
|
||||
const time_zone* timeZone = nullptr,
|
||||
bool epochValid = true);
|
||||
|
||||
} // namespace util
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <date/date.h>
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace awips
|
||||
|
|
@ -98,6 +102,10 @@ bool CodedTimeMotionLocation::Parse(const StringRange& lines,
|
|||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
using namespace date;
|
||||
#endif
|
||||
|
||||
static const std::string timeFormat {"%H%MZ"};
|
||||
|
||||
std::istringstream in {time};
|
||||
|
|
@ -106,12 +114,12 @@ bool CodedTimeMotionLocation::Parse(const StringRange& lines,
|
|||
|
||||
if (time.size() == 5 && !in.fail())
|
||||
{
|
||||
p->time_ = hh_mm_ss {tp};
|
||||
p->time_ = std::chrono::hh_mm_ss {tp};
|
||||
}
|
||||
else
|
||||
{
|
||||
logger_->warn("Invalid time: \"{}\"", time);
|
||||
p->time_ = hh_mm_ss<minutes> {};
|
||||
p->time_ = std::chrono::hh_mm_ss<minutes> {};
|
||||
dataValid = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
#include <boost/bimap.hpp>
|
||||
#include <boost/bimap/unordered_set_of.hpp>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <date/date.h>
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace awips
|
||||
|
|
@ -87,7 +91,7 @@ public:
|
|||
PVtec::PVtec() : p(std::make_unique<PVtecImpl>()) {}
|
||||
PVtec::~PVtec() = default;
|
||||
|
||||
PVtec::PVtec(PVtec&&) noexcept = default;
|
||||
PVtec::PVtec(PVtec&&) noexcept = default;
|
||||
PVtec& PVtec::operator=(PVtec&&) noexcept = default;
|
||||
|
||||
PVtec::ProductType PVtec::fixed_identifier() const
|
||||
|
|
@ -134,6 +138,10 @@ bool PVtec::Parse(const std::string& s)
|
|||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
using namespace date;
|
||||
#endif
|
||||
|
||||
// P-VTEC takes the form:
|
||||
// /k.aaa.cccc.pp.s.####.yymmddThhnnZ-yymmddThhnnZ/
|
||||
// 012345678901234567890123456789012345678901234567
|
||||
|
|
@ -187,8 +195,8 @@ bool PVtec::Parse(const std::string& s)
|
|||
std::istringstream ssEventBegin {sEventBegin};
|
||||
std::istringstream ssEventEnd {sEventEnd};
|
||||
|
||||
sys_time<minutes> eventBegin;
|
||||
sys_time<minutes> eventEnd;
|
||||
std::chrono::sys_time<minutes> eventBegin;
|
||||
std::chrono::sys_time<minutes> eventEnd;
|
||||
|
||||
ssEventBegin >> parse(dateTimeFormat, eventBegin);
|
||||
ssEventEnd >> parse(dateTimeFormat, eventEnd);
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ std::vector<std::string> Ugc::fips_ids() const
|
|||
{
|
||||
for (auto& id : fipsIdList.second)
|
||||
{
|
||||
fipsIds.push_back(std::format("{}{}{:03}",
|
||||
fipsIds.push_back(fmt::format("{}{}{:03}",
|
||||
fipsIdList.first,
|
||||
ugcFormatMap_.left.at(p->format_),
|
||||
id));
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
#include <scwx/common/geographic.hpp>
|
||||
#include <scwx/common/characters.hpp>
|
||||
|
||||
#include <format>
|
||||
#include <numbers>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace common
|
||||
|
|
@ -95,7 +96,7 @@ static std::string GetDegreeString(double degrees,
|
|||
{
|
||||
case DegreeStringType::Decimal:
|
||||
degreeString =
|
||||
std::format("{:.6f}{}{}", degrees, Unicode::kDegree, suffix);
|
||||
fmt::format("{:.6f}{}{}", degrees, Unicode::kDegree, suffix);
|
||||
break;
|
||||
case DegreeStringType::DegreesMinutesSeconds:
|
||||
{
|
||||
|
|
@ -103,7 +104,7 @@ static std::string GetDegreeString(double degrees,
|
|||
degrees = (degrees - dd) * 60.0;
|
||||
uint32_t mm = static_cast<uint32_t>(degrees);
|
||||
double ss = (degrees - mm) * 60.0;
|
||||
degreeString = std::format(
|
||||
degreeString = fmt::format(
|
||||
"{}{} {}' {:.2f}\"{}", dd, Unicode::kDegree, mm, ss, suffix);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,21 @@
|
|||
#include <scwx/network/dir_list.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <cpr/cpr.h>
|
||||
#include <libxml/HTMLparser.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <date/date.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -53,6 +63,12 @@ struct DirListSAXData
|
|||
std::vector<DirListRecord> records_;
|
||||
};
|
||||
|
||||
// Unspecified fields are initialized to zero, ignore warning
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
|
||||
static htmlSAXHandler saxHandler_ //
|
||||
{.startElement = &DirListSAXHandler::StartElement,
|
||||
.endElement = &DirListSAXHandler::EndElement,
|
||||
|
|
@ -61,6 +77,10 @@ static htmlSAXHandler saxHandler_ //
|
|||
.error = &DirListSAXHandler::Error,
|
||||
.fatalError = &DirListSAXHandler::Critical};
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
std::vector<DirListRecord> DirList(const std::string& baseUrl)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
|
@ -171,13 +191,16 @@ void DirListSAXHandler::Characters(void* userData, const xmlChar* ch, int len)
|
|||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
using namespace date;
|
||||
#endif
|
||||
|
||||
// Date time format: yyyy-mm-dd hh:mm
|
||||
static const std::string kDateTimeFormat {"%Y-%m-%d %H:%M"};
|
||||
static constexpr size_t kDateTimeSize {16u};
|
||||
|
||||
// Attempt to parse the date time
|
||||
std::istringstream ssCharacters {characters};
|
||||
sys_time<minutes> mtime;
|
||||
std::istringstream ssCharacters {characters};
|
||||
std::chrono::sys_time<minutes> mtime;
|
||||
ssCharacters >> parse(kDateTimeFormat, mtime);
|
||||
|
||||
if (!ssCharacters.fail())
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
#include <fmt/chrono.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <date/date.h>
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace provider
|
||||
|
|
@ -67,12 +71,16 @@ AwsLevel2DataProvider::GetTimePointFromKey(const std::string& key)
|
|||
(lastSeparator == std::string::npos) ? 0 : lastSeparator + 5;
|
||||
|
||||
// Filename format is GGGGYYYYMMDD_TTTTTT(_V##).gz
|
||||
static constexpr size_t formatSize = std::string("YYYYMMDD_TTTTTT").size();
|
||||
static const size_t formatSize = std::string("YYYYMMDD_TTTTTT").size();
|
||||
|
||||
if (key.size() >= offset + formatSize)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
using namespace date;
|
||||
#endif
|
||||
|
||||
static const std::string timeFormat {"%Y%m%d_%H%M%S"};
|
||||
|
||||
std::string timeStr {key.substr(offset, formatSize)};
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@
|
|||
#include <fmt/chrono.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <date/date.h>
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace provider
|
||||
|
|
@ -92,13 +96,16 @@ AwsLevel3DataProvider::GetTimePointFromKey(const std::string& key)
|
|||
constexpr size_t offset = 8;
|
||||
|
||||
// Filename format is GGG_PPP_YYYY_MM_DD_HH_MM_SS
|
||||
static constexpr size_t formatSize =
|
||||
std::string("YYYY_MM_DD_HH_MM_SS").size();
|
||||
static const size_t formatSize = std::string("YYYY_MM_DD_HH_MM_SS").size();
|
||||
|
||||
if (key.size() >= offset + formatSize)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
using namespace date;
|
||||
#endif
|
||||
|
||||
static const std::string timeFormat {"%Y_%m_%d_%H_%M_%S"};
|
||||
|
||||
std::string timeStr {key.substr(offset, formatSize)};
|
||||
|
|
@ -150,13 +157,15 @@ void AwsLevel3DataProvider::Impl::ListProducts()
|
|||
|
||||
logger_->debug("ListProducts()");
|
||||
|
||||
static const std::string delimiter {"_"};
|
||||
|
||||
// Prefix format: GGG_
|
||||
const std::string prefix = fmt::format("{0}_", siteId_);
|
||||
|
||||
Aws::S3::Model::ListObjectsV2Request request;
|
||||
request.SetBucket(bucketName_);
|
||||
request.SetPrefix(prefix);
|
||||
request.SetDelimiter("_");
|
||||
request.SetDelimiter(delimiter);
|
||||
|
||||
auto outcome = self_->client()->ListObjectsV2(request);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,21 @@
|
|||
#include <regex>
|
||||
#include <shared_mutex>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#define LIBXML_HTML_ENABLED
|
||||
#include <cpr/cpr.h>
|
||||
#include <libxml/HTMLparser.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <date/date.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -63,6 +73,10 @@ WarningsProvider::ListFiles(std::chrono::system_clock::time_point newerThan)
|
|||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
using namespace date;
|
||||
#endif
|
||||
|
||||
static const std::regex reWarningsFilename {
|
||||
"warnings_[0-9]{8}_[0-9]{2}.txt"};
|
||||
static const std::string dateTimeFormat {"warnings_%Y%m%d_%H.txt"};
|
||||
|
|
@ -98,8 +112,8 @@ WarningsProvider::ListFiles(std::chrono::system_clock::time_point newerThan)
|
|||
for (auto& record : warningRecords)
|
||||
{
|
||||
// Determine start time
|
||||
sys_time<hours> startTime;
|
||||
std::istringstream ssFilename {record.filename_};
|
||||
std::chrono::sys_time<hours> startTime;
|
||||
std::istringstream ssFilename {record.filename_};
|
||||
|
||||
ssFilename >> parse(dateTimeFormat, startTime);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <scwx/util/float.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
# include <WinSock2.h>
|
||||
|
|
@ -13,21 +14,21 @@ namespace scwx
|
|||
namespace util
|
||||
{
|
||||
|
||||
float DecodeFloat16(uint16_t hex)
|
||||
float DecodeFloat16(std::uint16_t hex)
|
||||
{
|
||||
static constexpr uint16_t S_MASK = 0x8000;
|
||||
static constexpr uint16_t S_LSB = 0;
|
||||
static constexpr uint16_t S_SHIFT = 15 - S_LSB;
|
||||
static constexpr uint16_t E_MASK = 0x7a00;
|
||||
static constexpr uint16_t E_LSB = 5;
|
||||
static constexpr uint16_t E_SHIFT = 15 - E_LSB;
|
||||
static constexpr uint16_t F_MASK = 0x03ff;
|
||||
static constexpr uint16_t F_LSB = 15;
|
||||
static constexpr uint16_t F_SHIFT = 15 - F_LSB;
|
||||
static constexpr std::uint16_t S_MASK = 0x8000;
|
||||
static constexpr std::uint16_t S_LSB = 0;
|
||||
static constexpr std::uint16_t S_SHIFT = 15 - S_LSB;
|
||||
static constexpr std::uint16_t E_MASK = 0x7a00;
|
||||
static constexpr std::uint16_t E_LSB = 5;
|
||||
static constexpr std::uint16_t E_SHIFT = 15 - E_LSB;
|
||||
static constexpr std::uint16_t F_MASK = 0x03ff;
|
||||
static constexpr std::uint16_t F_LSB = 15;
|
||||
static constexpr std::uint16_t F_SHIFT = 15 - F_LSB;
|
||||
|
||||
uint16_t sHex = (hex & S_MASK) >> S_SHIFT;
|
||||
uint16_t eHex = (hex & E_MASK) >> E_SHIFT;
|
||||
uint16_t fHex = (hex & F_MASK) >> F_SHIFT;
|
||||
std::uint16_t sHex = (hex & S_MASK) >> S_SHIFT;
|
||||
std::uint16_t eHex = (hex & E_MASK) >> E_SHIFT;
|
||||
std::uint16_t fHex = (hex & F_MASK) >> F_SHIFT;
|
||||
|
||||
float value;
|
||||
|
||||
|
|
@ -51,11 +52,14 @@ float DecodeFloat16(uint16_t hex)
|
|||
return value;
|
||||
}
|
||||
|
||||
float DecodeFloat32(uint16_t msw, uint16_t lsw)
|
||||
float DecodeFloat32(std::uint16_t msw, std::uint16_t lsw)
|
||||
{
|
||||
uint32_t value = msw << 16 | lsw;
|
||||
std::uint32_t value = msw << 16 | lsw;
|
||||
float floatValue;
|
||||
|
||||
return reinterpret_cast<float&>(value);
|
||||
std::memcpy(&floatValue, &value, sizeof(float));
|
||||
|
||||
return floatValue;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
|
|
|||
|
|
@ -22,10 +22,15 @@ std::chrono::system_clock::time_point TimePoint(uint32_t modifiedJulianDate,
|
|||
}
|
||||
|
||||
std::string TimeString(std::chrono::system_clock::time_point time,
|
||||
const std::chrono::time_zone* timeZone,
|
||||
const time_zone* timeZone,
|
||||
bool epochValid)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
using namespace date;
|
||||
#endif
|
||||
|
||||
auto timeInSeconds = time_point_cast<seconds>(time);
|
||||
std::ostringstream os;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,12 @@ vectorbuf::pos_type vectorbuf::seekoff(std::streamoff off,
|
|||
off_type newOffset;
|
||||
switch (way)
|
||||
{
|
||||
case std::ios_base::beg: newOffset = 0; break;
|
||||
case std::ios_base::end: newOffset = seekDist; break;
|
||||
case std::ios_base::beg:
|
||||
newOffset = 0;
|
||||
break;
|
||||
case std::ios_base::end:
|
||||
newOffset = seekDist;
|
||||
break;
|
||||
case std::ios_base::cur:
|
||||
{
|
||||
constexpr auto BOTH = std::ios_base::in | std::ios_base::out;
|
||||
|
|
@ -54,9 +58,11 @@ vectorbuf::pos_type vectorbuf::seekoff(std::streamoff off,
|
|||
break;
|
||||
}
|
||||
}
|
||||
return pos_type(off_type(-1));
|
||||
}
|
||||
|
||||
default: return pos_type(off_type(-1));
|
||||
default:
|
||||
return pos_type(off_type(-1));
|
||||
}
|
||||
|
||||
if (static_cast<unsigned long long>(off) + newOffset >
|
||||
|
|
@ -80,7 +86,9 @@ vectorbuf::pos_type vectorbuf::seekoff(std::streamoff off,
|
|||
|
||||
if ((which & std::ios_base::out) && pptrOld)
|
||||
{
|
||||
setp(seekLow, next, epptr());
|
||||
setp(seekLow, epptr());
|
||||
// If offset is > 4 GB, this won't properly position the put pointer
|
||||
pbump(static_cast<int>(off));
|
||||
}
|
||||
|
||||
return pos_type(off);
|
||||
|
|
|
|||
|
|
@ -8,10 +8,19 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||
#endif
|
||||
|
||||
#include <boost/iostreams/copy.hpp>
|
||||
#include <boost/iostreams/filtering_streambuf.hpp>
|
||||
#include <boost/iostreams/filter/bzip2.hpp>
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace wsr88d
|
||||
|
|
@ -24,35 +33,35 @@ class Ar2vFileImpl
|
|||
{
|
||||
public:
|
||||
explicit Ar2vFileImpl() :
|
||||
tapeFilename_(),
|
||||
extensionNumber_(),
|
||||
tapeFilename_ {},
|
||||
extensionNumber_ {},
|
||||
julianDate_ {0},
|
||||
milliseconds_ {0},
|
||||
icao_(),
|
||||
rawRecords_(),
|
||||
icao_ {},
|
||||
vcpData_ {nullptr},
|
||||
radarData_ {},
|
||||
index_ {} {};
|
||||
index_ {},
|
||||
rawRecords_ {} {};
|
||||
~Ar2vFileImpl() = default;
|
||||
|
||||
size_t DecompressLDMRecords(std::istream& is);
|
||||
void HandleMessage(std::shared_ptr<rda::Level2Message>& message);
|
||||
void IndexFile();
|
||||
void ParseLDMRecords();
|
||||
void ParseLDMRecord(std::istream& is);
|
||||
void ProcessRadarData(std::shared_ptr<rda::DigitalRadarData> message);
|
||||
std::size_t DecompressLDMRecords(std::istream& is);
|
||||
void HandleMessage(std::shared_ptr<rda::Level2Message>& message);
|
||||
void IndexFile();
|
||||
void ParseLDMRecords();
|
||||
void ParseLDMRecord(std::istream& is);
|
||||
void ProcessRadarData(std::shared_ptr<rda::DigitalRadarData> message);
|
||||
|
||||
std::string tapeFilename_;
|
||||
std::string extensionNumber_;
|
||||
uint32_t julianDate_;
|
||||
uint32_t milliseconds_;
|
||||
std::string icao_;
|
||||
std::string tapeFilename_;
|
||||
std::string extensionNumber_;
|
||||
std::uint32_t julianDate_;
|
||||
std::uint32_t milliseconds_;
|
||||
std::string icao_;
|
||||
|
||||
std::shared_ptr<rda::VolumeCoveragePatternData> vcpData_;
|
||||
std::map<uint16_t, std::shared_ptr<rda::ElevationScan>> radarData_;
|
||||
std::shared_ptr<rda::VolumeCoveragePatternData> vcpData_;
|
||||
std::map<std::uint16_t, std::shared_ptr<rda::ElevationScan>> radarData_;
|
||||
|
||||
std::map<rda::DataBlockType,
|
||||
std::map<uint16_t, std::shared_ptr<rda::ElevationScan>>>
|
||||
std::map<std::uint16_t, std::shared_ptr<rda::ElevationScan>>>
|
||||
index_;
|
||||
|
||||
std::list<std::stringstream> rawRecords_;
|
||||
|
|
@ -61,7 +70,7 @@ public:
|
|||
Ar2vFile::Ar2vFile() : p(std::make_unique<Ar2vFileImpl>()) {}
|
||||
Ar2vFile::~Ar2vFile() = default;
|
||||
|
||||
Ar2vFile::Ar2vFile(Ar2vFile&&) noexcept = default;
|
||||
Ar2vFile::Ar2vFile(Ar2vFile&&) noexcept = default;
|
||||
Ar2vFile& Ar2vFile::operator=(Ar2vFile&&) noexcept = default;
|
||||
|
||||
uint32_t Ar2vFile::julian_date() const
|
||||
|
|
|
|||
|
|
@ -4,13 +4,29 @@
|
|||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4706)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||
#endif
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4706)
|
||||
#include <boost/iostreams/copy.hpp>
|
||||
#include <boost/iostreams/filtering_streambuf.hpp>
|
||||
#include <boost/iostreams/filter/zlib.hpp>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -39,7 +55,7 @@ public:
|
|||
Level3File::Level3File() : p(std::make_unique<Level3FileImpl>()) {}
|
||||
Level3File::~Level3File() = default;
|
||||
|
||||
Level3File::Level3File(Level3File&&) noexcept = default;
|
||||
Level3File::Level3File(Level3File&&) noexcept = default;
|
||||
Level3File& Level3File::operator=(Level3File&&) noexcept = default;
|
||||
|
||||
std::shared_ptr<awips::WmoHeader> Level3File::wmo_header() const
|
||||
|
|
|
|||
|
|
@ -6,12 +6,27 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4706)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4706)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||
#endif
|
||||
|
||||
#include <boost/iostreams/copy.hpp>
|
||||
#include <boost/iostreams/filtering_streambuf.hpp>
|
||||
#include <boost/iostreams/filter/gzip.hpp>
|
||||
#pragma warning(pop)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ DataBlock::DataBlock(const std::string& dataBlockType,
|
|||
}
|
||||
DataBlock::~DataBlock() = default;
|
||||
|
||||
DataBlock::DataBlock(DataBlock&&) noexcept = default;
|
||||
DataBlock::DataBlock(DataBlock&&) noexcept = default;
|
||||
DataBlock& DataBlock::operator=(DataBlock&&) noexcept = default;
|
||||
|
||||
class MomentDataBlockImpl
|
||||
|
|
@ -198,7 +198,7 @@ bool MomentDataBlock::Parse(std::istream& is)
|
|||
p->scale_ = awips::Message::SwapFloat(p->scale_);
|
||||
p->offset_ = awips::Message::SwapFloat(p->offset_);
|
||||
|
||||
if (p->numberOfDataMomentGates_ >= 0 && p->numberOfDataMomentGates_ <= 1840)
|
||||
if (p->numberOfDataMomentGates_ <= 1840)
|
||||
{
|
||||
if (p->dataWordSize_ == 8)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ DigitalRadialDataArrayPacket::DigitalRadialDataArrayPacket() :
|
|||
DigitalRadialDataArrayPacket::~DigitalRadialDataArrayPacket() = default;
|
||||
|
||||
DigitalRadialDataArrayPacket::DigitalRadialDataArrayPacket(
|
||||
DigitalRadialDataArrayPacket&&) noexcept = default;
|
||||
DigitalRadialDataArrayPacket&&) noexcept = default;
|
||||
DigitalRadialDataArrayPacket& DigitalRadialDataArrayPacket::operator=(
|
||||
DigitalRadialDataArrayPacket&&) noexcept = default;
|
||||
|
||||
|
|
@ -158,13 +158,13 @@ bool DigitalRadialDataArrayPacket::Parse(std::istream& is)
|
|||
logger_->warn("Invalid packet code: {}", p->packetCode_);
|
||||
blockValid = false;
|
||||
}
|
||||
if (p->indexOfFirstRangeBin_ < 0 || p->indexOfFirstRangeBin_ > 230)
|
||||
if (p->indexOfFirstRangeBin_ > 230)
|
||||
{
|
||||
logger_->warn("Invalid index of first range bin: {}",
|
||||
p->indexOfFirstRangeBin_);
|
||||
blockValid = false;
|
||||
}
|
||||
if (p->numberOfRangeBins_ < 0 || p->numberOfRangeBins_ > 1840)
|
||||
if (p->numberOfRangeBins_ > 1840)
|
||||
{
|
||||
logger_->warn("Invalid number of range bins: {}",
|
||||
p->numberOfRangeBins_);
|
||||
|
|
|
|||
|
|
@ -3,12 +3,22 @@
|
|||
#include <scwx/util/rangebuf.hpp>
|
||||
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||
#endif
|
||||
|
||||
#include <boost/iostreams/copy.hpp>
|
||||
#include <boost/iostreams/filtering_streambuf.hpp>
|
||||
#include <boost/iostreams/filter/bzip2.hpp>
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace wsr88d
|
||||
|
|
|
|||
|
|
@ -102,11 +102,11 @@ bool VectorArrowDataPacket::Parse(std::istream& is)
|
|||
|
||||
// The number of vectors is equal to the size divided by the number of bytes
|
||||
// in a vector
|
||||
size_t vectorCount = p->lengthOfBlock_ / 10;
|
||||
std::size_t vectorCount = p->lengthOfBlock_ / 10;
|
||||
|
||||
p->arrow_.resize(vectorCount);
|
||||
|
||||
for (int v = 0; v < vectorCount && !is.eof(); v++)
|
||||
for (std::size_t v = 0; v < vectorCount && !is.eof(); v++)
|
||||
{
|
||||
VectorArrow& arrow = p->arrow_[v];
|
||||
|
||||
|
|
|
|||
|
|
@ -101,11 +101,11 @@ bool WindBarbDataPacket::Parse(std::istream& is)
|
|||
|
||||
// The number of vectors is equal to the size divided by the number of bytes
|
||||
// in a vector
|
||||
size_t vectorCount = p->lengthOfBlock_ / 10;
|
||||
std::size_t vectorCount = p->lengthOfBlock_ / 10;
|
||||
|
||||
p->windBarb_.resize(vectorCount);
|
||||
|
||||
for (int v = 0; v < vectorCount && !is.eof(); v++)
|
||||
for (std::size_t v = 0; v < vectorCount && !is.eof(); v++)
|
||||
{
|
||||
WindBarb& windBarb = p->windBarb_[v];
|
||||
|
||||
|
|
|
|||
|
|
@ -246,6 +246,10 @@ if (WIN32)
|
|||
target_link_libraries(wxdata INTERFACE Ws2_32)
|
||||
endif()
|
||||
|
||||
if (NOT MSVC)
|
||||
target_link_libraries(wxdata PUBLIC date::date-tz)
|
||||
endif()
|
||||
|
||||
set_target_properties(wxdata PROPERTIES CXX_STANDARD 20
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS OFF)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue