mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 13:20:04 +00:00
Load color tables from settings
This commit is contained in:
parent
bcae7d9825
commit
b241703b40
16 changed files with 324 additions and 17 deletions
|
|
@ -74,8 +74,10 @@ set(SRC_MAP source/scwx/qt/map/map_widget.cpp
|
|||
source/scwx/qt/map/radar_product_layer.cpp
|
||||
source/scwx/qt/map/radar_range_layer.cpp
|
||||
source/scwx/qt/map/triangle_layer.cpp)
|
||||
set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp)
|
||||
set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp)
|
||||
set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp
|
||||
source/scwx/qt/settings/palette_settings.hpp)
|
||||
set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp
|
||||
source/scwx/qt/settings/palette_settings.cpp)
|
||||
set(HDR_UI source/scwx/qt/ui/flow_layout.hpp)
|
||||
set(SRC_UI source/scwx/qt/ui/flow_layout.cpp)
|
||||
set(HDR_UTIL source/scwx/qt/util/font.hpp
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ namespace SettingsManager
|
|||
static const std::string logPrefix_ = "[scwx::qt::manager::settings_manager] ";
|
||||
|
||||
static std::shared_ptr<settings::GeneralSettings> generalSettings_ = nullptr;
|
||||
static std::shared_ptr<settings::PaletteSettings> paletteSettings_ = nullptr;
|
||||
|
||||
static boost::json::value ConvertSettingsToJson();
|
||||
static void GenerateDefaultSettings();
|
||||
|
|
@ -79,11 +80,17 @@ std::shared_ptr<settings::GeneralSettings> general_settings()
|
|||
return generalSettings_;
|
||||
}
|
||||
|
||||
std::shared_ptr<settings::PaletteSettings> palette_settings()
|
||||
{
|
||||
return paletteSettings_;
|
||||
}
|
||||
|
||||
static boost::json::value ConvertSettingsToJson()
|
||||
{
|
||||
boost::json::object settingsJson;
|
||||
|
||||
settingsJson["general"] = generalSettings_->ToJson();
|
||||
settingsJson["palette"] = paletteSettings_->ToJson();
|
||||
|
||||
return settingsJson;
|
||||
}
|
||||
|
|
@ -93,6 +100,7 @@ static void GenerateDefaultSettings()
|
|||
BOOST_LOG_TRIVIAL(info) << logPrefix_ << "Generating default settings";
|
||||
|
||||
generalSettings_ = settings::GeneralSettings::Create();
|
||||
paletteSettings_ = settings::PaletteSettings::Create();
|
||||
}
|
||||
|
||||
static bool LoadSettings(const boost::json::object& settingsJson)
|
||||
|
|
@ -103,6 +111,8 @@ static bool LoadSettings(const boost::json::object& settingsJson)
|
|||
|
||||
generalSettings_ = settings::GeneralSettings::Load(
|
||||
settingsJson.if_contains("general"), jsonDirty);
|
||||
paletteSettings_ = settings::PaletteSettings::Load(
|
||||
settingsJson.if_contains("palette"), jsonDirty);
|
||||
|
||||
return jsonDirty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <scwx/qt/settings/general_settings.hpp>
|
||||
#include <scwx/qt/settings/palette_settings.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -15,6 +16,7 @@ void Initialize();
|
|||
void ReadSettings(const std::string& settingsPath);
|
||||
|
||||
std::shared_ptr<settings::GeneralSettings> general_settings();
|
||||
std::shared_ptr<settings::PaletteSettings> palette_settings();
|
||||
|
||||
} // namespace SettingsManager
|
||||
} // namespace manager
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <scwx/qt/map/map_widget.hpp>
|
||||
#include <scwx/qt/gl/gl.hpp>
|
||||
#include <scwx/qt/manager/radar_product_manager.hpp>
|
||||
#include <scwx/qt/manager/settings_manager.hpp>
|
||||
#include <scwx/qt/map/overlay_layer.hpp>
|
||||
#include <scwx/qt/map/radar_product_layer.hpp>
|
||||
#include <scwx/qt/map/radar_range_layer.hpp>
|
||||
|
|
@ -99,11 +100,13 @@ void MapWidget::SelectRadarProduct(common::Level2Product product)
|
|||
|
||||
p->radarProductView_->Initialize();
|
||||
|
||||
QString colorTableFile = qgetenv("COLOR_TABLE");
|
||||
if (!colorTableFile.isEmpty())
|
||||
std::string colorTableFile =
|
||||
manager::SettingsManager::palette_settings()->palette(
|
||||
common::GetLevel2Palette(product));
|
||||
if (!colorTableFile.empty())
|
||||
{
|
||||
std::shared_ptr<common::ColorTable> colorTable =
|
||||
common::ColorTable::Load(colorTableFile.toUtf8().constData());
|
||||
common::ColorTable::Load(colorTableFile);
|
||||
p->radarProductView_->LoadColorTable(colorTable);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace settings
|
|||
|
||||
static const std::string logPrefix_ = "[scwx::qt::settings::general_settings] ";
|
||||
|
||||
static const std::string& DEFAULT_DEFAULT_RADAR_SITE = "KLSX";
|
||||
static const std::string DEFAULT_DEFAULT_RADAR_SITE = "KLSX";
|
||||
|
||||
class GeneralSettingsImpl
|
||||
{
|
||||
|
|
@ -35,12 +35,12 @@ GeneralSettings::GeneralSettings(GeneralSettings&&) noexcept = default;
|
|||
GeneralSettings&
|
||||
GeneralSettings::operator=(GeneralSettings&&) noexcept = default;
|
||||
|
||||
const std::string& GeneralSettings::default_radar_site()
|
||||
const std::string& GeneralSettings::default_radar_site() const
|
||||
{
|
||||
return p->defaultRadarSite_;
|
||||
}
|
||||
|
||||
boost::json::value GeneralSettings::ToJson()
|
||||
boost::json::value GeneralSettings::ToJson() const
|
||||
{
|
||||
boost::json::object json;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ public:
|
|||
GeneralSettings(GeneralSettings&&) noexcept;
|
||||
GeneralSettings& operator=(GeneralSettings&&) noexcept;
|
||||
|
||||
const std::string& default_radar_site();
|
||||
const std::string& default_radar_site() const;
|
||||
|
||||
boost::json::value ToJson();
|
||||
boost::json::value ToJson() const;
|
||||
|
||||
static std::shared_ptr<GeneralSettings> Create();
|
||||
static std::shared_ptr<GeneralSettings> Load(const boost::json::value* json,
|
||||
|
|
|
|||
132
scwx-qt/source/scwx/qt/settings/palette_settings.cpp
Normal file
132
scwx-qt/source/scwx/qt/settings/palette_settings.cpp
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#include <scwx/qt/settings/palette_settings.hpp>
|
||||
#include <scwx/qt/util/json.hpp>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace settings
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "[scwx::qt::settings::palette_settings] ";
|
||||
|
||||
static const std::vector<std::string> paletteNames_ = {
|
||||
"BR", "BV", "SW", "ZDR", "PHI", "CC", "???"};
|
||||
|
||||
static const std::string DEFAULT_KEY = "Default";
|
||||
static const std::string DEFAULT_PALETTE = "";
|
||||
|
||||
class PaletteSettingsImpl
|
||||
{
|
||||
public:
|
||||
explicit PaletteSettingsImpl() {}
|
||||
|
||||
~PaletteSettingsImpl() {}
|
||||
|
||||
void SetDefaults()
|
||||
{
|
||||
std::for_each(
|
||||
paletteNames_.cbegin(),
|
||||
paletteNames_.cend(),
|
||||
[&](const std::string& name) { palette_[name] = DEFAULT_PALETTE; });
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> palette_;
|
||||
};
|
||||
|
||||
PaletteSettings::PaletteSettings() : p(std::make_unique<PaletteSettingsImpl>())
|
||||
{
|
||||
}
|
||||
PaletteSettings::~PaletteSettings() = default;
|
||||
|
||||
PaletteSettings::PaletteSettings(PaletteSettings&&) noexcept = default;
|
||||
PaletteSettings&
|
||||
PaletteSettings::operator=(PaletteSettings&&) noexcept = default;
|
||||
|
||||
const std::string& PaletteSettings::palette(const std::string& name) const
|
||||
{
|
||||
auto palette = p->palette_.find(name);
|
||||
|
||||
if (palette == p->palette_.cend())
|
||||
{
|
||||
palette = p->palette_.find("Default");
|
||||
}
|
||||
|
||||
if (palette == p->palette_.cend())
|
||||
{
|
||||
return DEFAULT_PALETTE;
|
||||
}
|
||||
|
||||
return palette->second;
|
||||
}
|
||||
|
||||
boost::json::value PaletteSettings::ToJson() const
|
||||
{
|
||||
boost::json::object json;
|
||||
|
||||
std::for_each(
|
||||
paletteNames_.cbegin(),
|
||||
paletteNames_.cend(),
|
||||
[&](const std::string& name) { json[name] = p->palette_[name]; });
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
std::shared_ptr<PaletteSettings> PaletteSettings::Create()
|
||||
{
|
||||
std::shared_ptr<PaletteSettings> generalSettings =
|
||||
std::make_shared<PaletteSettings>();
|
||||
|
||||
generalSettings->p->SetDefaults();
|
||||
|
||||
return generalSettings;
|
||||
}
|
||||
|
||||
std::shared_ptr<PaletteSettings>
|
||||
PaletteSettings::Load(const boost::json::value* json, bool& jsonDirty)
|
||||
{
|
||||
std::shared_ptr<PaletteSettings> generalSettings =
|
||||
std::make_shared<PaletteSettings>();
|
||||
|
||||
if (json != nullptr && json->is_object())
|
||||
{
|
||||
std::for_each(paletteNames_.cbegin(),
|
||||
paletteNames_.cend(),
|
||||
[&](const std::string& name) {
|
||||
jsonDirty |= !util::json::FromJsonString(
|
||||
json->as_object(),
|
||||
name,
|
||||
generalSettings->p->palette_[name],
|
||||
DEFAULT_PALETTE);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (json == nullptr)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(warning)
|
||||
<< logPrefix_ << "Key is not present, resetting to defaults";
|
||||
}
|
||||
else if (!json->is_object())
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(warning)
|
||||
<< logPrefix_ << "Invalid json, resetting to defaults";
|
||||
}
|
||||
|
||||
generalSettings->p->SetDefaults();
|
||||
jsonDirty = true;
|
||||
}
|
||||
|
||||
return generalSettings;
|
||||
}
|
||||
|
||||
bool operator==(const PaletteSettings& lhs, const PaletteSettings& rhs)
|
||||
{
|
||||
return lhs.p->palette_ == rhs.p->palette_;
|
||||
}
|
||||
|
||||
} // namespace settings
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
46
scwx-qt/source/scwx/qt/settings/palette_settings.hpp
Normal file
46
scwx-qt/source/scwx/qt/settings/palette_settings.hpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <boost/json.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace settings
|
||||
{
|
||||
|
||||
class PaletteSettingsImpl;
|
||||
|
||||
class PaletteSettings
|
||||
{
|
||||
public:
|
||||
explicit PaletteSettings();
|
||||
~PaletteSettings();
|
||||
|
||||
PaletteSettings(const PaletteSettings&) = delete;
|
||||
PaletteSettings& operator=(const PaletteSettings&) = delete;
|
||||
|
||||
PaletteSettings(PaletteSettings&&) noexcept;
|
||||
PaletteSettings& operator=(PaletteSettings&&) noexcept;
|
||||
|
||||
const std::string& palette(const std::string& name) const;
|
||||
|
||||
boost::json::value ToJson() const;
|
||||
|
||||
static std::shared_ptr<PaletteSettings> Create();
|
||||
static std::shared_ptr<PaletteSettings> Load(const boost::json::value* json,
|
||||
bool& jsonDirty);
|
||||
|
||||
friend bool operator==(const PaletteSettings& lhs,
|
||||
const PaletteSettings& rhs);
|
||||
|
||||
private:
|
||||
std::unique_ptr<PaletteSettingsImpl> p;
|
||||
};
|
||||
|
||||
} // namespace settings
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
|
|
@ -156,14 +156,15 @@ void Level2ProductView::LoadColorTable(
|
|||
void Level2ProductView::UpdateColorTable()
|
||||
{
|
||||
if (p->momentDataBlock0_ == nullptr || //
|
||||
p->colorTable_ == nullptr)
|
||||
p->colorTable_ == nullptr || //
|
||||
!p->colorTable_->IsValid())
|
||||
{
|
||||
// Nothing to update
|
||||
return;
|
||||
}
|
||||
|
||||
const float offset = p->momentDataBlock0_->offset();
|
||||
const float scale = p->momentDataBlock0_->scale();
|
||||
float offset = p->momentDataBlock0_->offset();
|
||||
float scale = p->momentDataBlock0_->scale();
|
||||
|
||||
if (p->savedColorTable_ == p->colorTable_ && //
|
||||
p->savedOffset_ == offset && //
|
||||
|
|
@ -173,10 +174,41 @@ void Level2ProductView::UpdateColorTable()
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector<boost::gil::rgba8_pixel_t>& lut = p->colorTableLut_;
|
||||
lut.resize(254);
|
||||
uint16_t rangeMin;
|
||||
uint16_t rangeMax;
|
||||
|
||||
auto dataRange = boost::irange<uint16_t>(2, 255);
|
||||
switch (p->product_)
|
||||
{
|
||||
case common::Level2Product::Reflectivity:
|
||||
case common::Level2Product::Velocity:
|
||||
case common::Level2Product::SpectrumWidth:
|
||||
case common::Level2Product::CorrelationCoefficient:
|
||||
default:
|
||||
rangeMin = 2;
|
||||
rangeMax = 255;
|
||||
break;
|
||||
|
||||
case common::Level2Product::DifferentialReflectivity:
|
||||
rangeMin = 2;
|
||||
rangeMax = 1058;
|
||||
break;
|
||||
|
||||
case common::Level2Product::DifferentialPhase:
|
||||
rangeMin = 2;
|
||||
rangeMax = 1023;
|
||||
break;
|
||||
|
||||
case common::Level2Product::ClutterFilterPowerRemoved:
|
||||
rangeMin = 8;
|
||||
rangeMax = 81;
|
||||
break;
|
||||
}
|
||||
|
||||
boost::integer_range<uint16_t> dataRange =
|
||||
boost::irange<uint16_t>(rangeMin, rangeMax);
|
||||
|
||||
std::vector<boost::gil::rgba8_pixel_t>& lut = p->colorTableLut_;
|
||||
lut.resize(rangeMax - rangeMin + 1);
|
||||
|
||||
std::for_each(std::execution::par_unseq,
|
||||
dataRange.begin(),
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ public:
|
|||
ColorTable& operator=(ColorTable&&) noexcept;
|
||||
|
||||
boost::gil::rgba8_pixel_t Color(float value) const;
|
||||
bool IsValid() const;
|
||||
|
||||
static std::shared_ptr<ColorTable> Load(const std::string& filename);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ typedef util::Iterator<Level2Product,
|
|||
|
||||
const std::string& GetLevel2Name(Level2Product product);
|
||||
const std::string& GetLevel2Description(Level2Product product);
|
||||
const std::string& GetLevel2Palette(Level2Product product);
|
||||
const Level2Product GetLevel2Product(const std::string& id);
|
||||
|
||||
} // namespace common
|
||||
|
|
|
|||
13
wxdata/include/scwx/util/streams.hpp
Normal file
13
wxdata/include/scwx/util/streams.hpp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <istream>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
|
||||
std::istream& getline(std::istream& is, std::string& t);
|
||||
|
||||
} // namespace util
|
||||
} // namespace scwx
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include <scwx/common/color_table.hpp>
|
||||
#include <scwx/util/streams.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
|
|
@ -122,6 +123,11 @@ boost::gil::rgba8_pixel_t ColorTable::Color(float value) const
|
|||
return color;
|
||||
}
|
||||
|
||||
bool ColorTable::IsValid() const
|
||||
{
|
||||
return p->colorMap_.size() > 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<ColorTable> ColorTable::Load(const std::string& filename)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug)
|
||||
|
|
@ -132,7 +138,7 @@ std::shared_ptr<ColorTable> ColorTable::Load(const std::string& filename)
|
|||
std::ifstream f(filename, std::ios_base::in);
|
||||
|
||||
std::string line;
|
||||
while (std::getline(f, line))
|
||||
while (scwx::util::getline(f, line))
|
||||
{
|
||||
std::string token;
|
||||
std::istringstream tokens(line);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,16 @@ static const std::unordered_map<Level2Product, std::string> level2Description_ {
|
|||
{Level2Product::ClutterFilterPowerRemoved, "Clutter Filter Power Removed"},
|
||||
{Level2Product::Unknown, "?"}};
|
||||
|
||||
static const std::unordered_map<Level2Product, std::string> level2Palette_ {
|
||||
{Level2Product::Reflectivity, "BR"},
|
||||
{Level2Product::Velocity, "BV"},
|
||||
{Level2Product::SpectrumWidth, "SW"},
|
||||
{Level2Product::DifferentialReflectivity, "ZDR"},
|
||||
{Level2Product::DifferentialPhase, "PHI"},
|
||||
{Level2Product::CorrelationCoefficient, "CC"},
|
||||
{Level2Product::ClutterFilterPowerRemoved, "???"},
|
||||
{Level2Product::Unknown, "???"}};
|
||||
|
||||
const std::string& GetLevel2Name(Level2Product product)
|
||||
{
|
||||
return level2Name_.at(product);
|
||||
|
|
@ -37,6 +47,11 @@ const std::string& GetLevel2Description(Level2Product product)
|
|||
return level2Description_.at(product);
|
||||
}
|
||||
|
||||
const std::string& GetLevel2Palette(Level2Product product)
|
||||
{
|
||||
return level2Palette_.at(product);
|
||||
}
|
||||
|
||||
const Level2Product GetLevel2Product(const std::string& name)
|
||||
{
|
||||
auto result = std::find_if(
|
||||
|
|
|
|||
42
wxdata/source/scwx/util/streams.cpp
Normal file
42
wxdata/source/scwx/util/streams.cpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#include <scwx/util/streams.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
|
||||
std::istream& getline(std::istream& is, std::string& t)
|
||||
{
|
||||
t.clear();
|
||||
|
||||
std::istream::sentry sentry(is, true);
|
||||
std::streambuf* sb = is.rdbuf();
|
||||
|
||||
while (true)
|
||||
{
|
||||
int c = sb->sbumpc();
|
||||
switch (c)
|
||||
{
|
||||
case '\n': return is;
|
||||
|
||||
case '\r':
|
||||
if (sb->sgetc() == '\n')
|
||||
{
|
||||
sb->sbumpc();
|
||||
}
|
||||
return is;
|
||||
|
||||
case std::streambuf::traits_type::eof():
|
||||
if (t.empty())
|
||||
{
|
||||
is.setstate(std::ios::eofbit);
|
||||
}
|
||||
return is;
|
||||
|
||||
default: t += static_cast<char>(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace scwx
|
||||
|
|
@ -10,8 +10,10 @@ set(SRC_COMMON source/scwx/common/color_table.cpp
|
|||
source/scwx/common/products.cpp)
|
||||
set(HDR_UTIL include/scwx/util/iterator.hpp
|
||||
include/scwx/util/rangebuf.hpp
|
||||
include/scwx/util/streams.hpp
|
||||
include/scwx/util/vectorbuf.hpp)
|
||||
set(SRC_UTIL source/scwx/util/rangebuf.cpp
|
||||
source/scwx/util/streams.cpp
|
||||
source/scwx/util/vectorbuf.cpp)
|
||||
set(HDR_WSR88D include/scwx/wsr88d/ar2v_file.hpp)
|
||||
set(SRC_WSR88D source/scwx/wsr88d/ar2v_file.cpp)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue