satdump/src-interface/viewer/scatterometer_handler.cpp

223 lines
8.4 KiB
C++
Raw Normal View History

2022-09-29 00:46:17 +02:00
#include "scatterometer_handler.h"
#include "core/config.h"
#include "resources.h"
#include "common/projection/reprojector.h"
#include "core/style.h"
#include "common/map/map_drawer.h"
namespace satdump
{
void ScatterometerViewerHandler::init()
{
products = (ScatterometerProducts *)ViewerHandler::products;
if (products->get_scatterometer_type() == products->SCAT_TYPE_ASCAT)
current_scat_type = SCAT_ASCAT;
if (current_scat_type == SCAT_ASCAT)
{
select_channel_image_str += std::string("Channel 1 (Back Right)") + '\0';
select_channel_image_str += std::string("Channel 2 (Down Left)") + '\0';
select_channel_image_str += std::string("Channel 3 (Back Left)") + '\0';
select_channel_image_str += std::string("Channel 4 (Front Right)") + '\0';
select_channel_image_str += std::string("Channel 5 (Back Left)") + '\0';
select_channel_image_str += std::string("Channel 6 (Front Left)") + '\0';
ascat_select_channel_image_str += std::string("Back") + '\0';
ascat_select_channel_image_str += std::string("Down") + '\0';
ascat_select_channel_image_str += std::string("Front") + '\0';
}
else
{
for (int c = 0; c < (int)products->get_channel_cnt(); c++)
select_channel_image_str += "Channel " + std::to_string(c + 1) + '\0';
}
update();
}
void ScatterometerViewerHandler::update()
{
if (selected_visualization_id == 0)
{
GrayScaleScatCfg cfg;
cfg.channel = select_channel_image_id;
cfg.min = scat_grayscale_min;
cfg.max = scat_grayscale_max;
auto img = make_scatterometer_grayscale(*products, cfg);
image_view.update(img);
}
else if (selected_visualization_id == 1)
{
GrayScaleScatCfg cfg;
if (current_scat_type == SCAT_ASCAT)
cfg.channel = ascat_select_channel_id;
else
cfg.channel = select_channel_image_id;
cfg.min = scat_grayscale_min;
cfg.max = scat_grayscale_max;
current_image_proj.clear();
current_img = make_scatterometer_grayscale_projs(*products, cfg, nullptr, &current_image_proj);
if (map_overlay)
{
2022-12-15 21:43:39 +01:00
auto proj_func = satdump::reprojection::setupProjectionFunction(current_img.width(), current_img.height(), current_image_proj, {});
2022-09-29 00:46:17 +02:00
logger->info("Drawing map overlay...");
unsigned short color[3] = {(unsigned short)(color_borders.x * 65535.0f), (unsigned short)(color_borders.y * 65535.0f), (unsigned short)(color_borders.z * 65535.0f)};
map::drawProjectedMapShapefile({resources::getResourcePath("maps/ne_10m_admin_0_countries.shp")},
current_img,
color,
proj_func);
}
image_view.update(current_img);
}
}
void ScatterometerViewerHandler::drawMenu()
{
if (ImGui::CollapsingHeader("Images"))
{
if (ImGui::RadioButton(u8"Raw Image", &selected_visualization_id, 0))
update();
if (ImGui::RadioButton(u8"Projected", &selected_visualization_id, 1))
update();
if (selected_visualization_id == 0 || selected_visualization_id == 1)
{
if (current_scat_type == SCAT_ASCAT && selected_visualization_id == 1)
{
if (ImGui::Combo("###scatchannelcomboid", &ascat_select_channel_id, ascat_select_channel_image_str.c_str()))
update();
}
else
{
if (ImGui::Combo("###scatchannelcomboid", &select_channel_image_id, select_channel_image_str.c_str()))
update();
}
ImGui::SetNextItemWidth(ImGui::GetWindowWidth() / 2);
if (ImGui::SliderInt("##MinScat", &scat_grayscale_min, 0, 1e7, "Min: %d", ImGuiSliderFlags_AlwaysClamp))
update();
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetWindowWidth() / 2);
if (ImGui::SliderInt("##MaxScat", &scat_grayscale_max, 0, 1e7, "Max: %d", ImGuiSliderFlags_AlwaysClamp))
update();
}
if (ImGui::Button("Save"))
{
std::string ch_normal = std::to_string(select_channel_image_id);
std::string ch_ascatp = std::to_string(ascat_select_channel_id);
std::string default_name = products->instrument_name + "_" + ((selected_visualization_id == 1 && current_scat_type == SCAT_ASCAT) ? ch_ascatp : ch_normal) + ".png";
#ifndef __ANDROID__
auto result = pfd::save_file("Save Image", default_name, {"*.png"});
while (!result.ready(1000))
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if (result.result().size() > 0)
{
std::string path = result.result();
2023-05-08 23:08:34 +02:00
logger->info("Saving current image at %s", path.c_str());
2022-09-29 00:46:17 +02:00
current_img.save_img(path);
}
#else
std::string path = "/storage/emulated/0/" + default_name;
2023-05-08 23:08:34 +02:00
logger->info("Saving current image at %s", path.c_str());
2022-09-29 00:46:17 +02:00
current_img.save_img("" + path);
#endif
}
}
if (ImGui::CollapsingHeader("Map Overlay"))
{
if (selected_visualization_id != 1)
style::beginDisabled();
if (ImGui::Checkbox("Borders", &map_overlay))
update();
ImGui::SameLine();
ImGui::ColorEdit3("##borders", (float *)&color_borders, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel);
if (selected_visualization_id != 1)
style::endDisabled();
}
if (ImGui::CollapsingHeader("Projection"))
{
ImGui::BeginGroup();
if (!canBeProjected())
style::beginDisabled();
ImGui::Checkbox("Project", &should_project);
if (!canBeProjected())
style::endDisabled();
ImGui::EndGroup();
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
{
ImGui::BeginTooltip();
if (selected_visualization_id != 1)
2022-12-10 12:54:33 +01:00
ImGui::TextColored(ImColor(255, 0, 0), "Select projection view first!");
2022-09-29 00:46:17 +02:00
ImGui::EndTooltip();
}
}
}
void ScatterometerViewerHandler::drawContents(ImVec2 win_size)
{
if (selected_visualization_id == 0 || selected_visualization_id == 1)
{
image_view.draw(win_size);
}
}
float ScatterometerViewerHandler::drawTreeMenu()
{
return 0;
}
bool ScatterometerViewerHandler::canBeProjected()
{
return products->has_proj_cfg() &&
products->has_tle() &&
products->has_proj_cfg() &&
products->has_timestamps &&
selected_visualization_id == 1;
}
bool ScatterometerViewerHandler::hasProjection()
{
return projection_ready && should_project;
}
bool ScatterometerViewerHandler::shouldProject()
{
return should_project;
}
void ScatterometerViewerHandler::updateProjection(int width, int height, nlohmann::json settings, float *progess)
{
if (canBeProjected())
{
reprojection::ReprojectionOperation op;
op.source_prj_info = current_image_proj;
op.target_prj_info = settings;
op.img = current_img;
op.output_width = width;
op.output_height = height;
// op.use_draw_algorithm = use_draw_proj_algo;
// op.img_tle = products->get_tle();
// op.img_tim = current_timestamps;
reprojection::ProjectionResult res = reprojection::reproject(op, progess);
projected_img = res.img;
projection_ready = true;
}
else
{
logger->error("Current image can't be projected!");
}
}
image::Image<uint16_t> &ScatterometerViewerHandler::getProjection()
{
return projected_img;
}
}