2022-04-12 20:18:44 +02:00
|
|
|
#include "viewer.h"
|
|
|
|
|
#include "image_handler.h"
|
2022-04-16 08:10:25 +02:00
|
|
|
#include "radiation_handler.h"
|
2022-04-12 20:18:44 +02:00
|
|
|
#include "core/config.h"
|
2022-04-16 08:10:25 +02:00
|
|
|
#include "products/dataset.h"
|
|
|
|
|
#include "common/utils.h"
|
2022-04-12 20:18:44 +02:00
|
|
|
|
|
|
|
|
namespace satdump
|
|
|
|
|
{
|
|
|
|
|
ViewerApplication::ViewerApplication()
|
|
|
|
|
: Application("viewer")
|
|
|
|
|
{
|
|
|
|
|
// pro.load("/home/alan/Documents/SatDump_ReWork/build/metop_ahrpt_new/AVHRR/product.cbor");
|
|
|
|
|
// pro.load("/home/alan/Documents/SatDump_ReWork/build/aqua_test_new/MODIS/product.cbor");
|
|
|
|
|
|
2022-04-26 15:07:18 +02:00
|
|
|
// loadDatasetInViewer("/home/alan/Documents/SatDump_ReWork/build/metop_ahrpt_new/dataset.json");
|
2022-04-16 08:10:25 +02:00
|
|
|
|
|
|
|
|
// loadProductsInViewer("/home/alan/Documents/SatDump_ReWork/build/noaa_mhs_test/AMSU/product.cbor", "NOAA-19 HRPT");
|
|
|
|
|
// loadProductsInViewer("/home/alan/Documents/SatDump_ReWork/build/metop_ahrpt_new/AVHRR/product.cbor", "MetOp-B AHRPT");
|
|
|
|
|
// loadProductsInViewer("/home/alan/Documents/SatDump_ReWork/build/noaa_mhs_test/MHS/product.cbor", "NOAA-19 HRPT");
|
|
|
|
|
// loadProductsInViewer("/home/alan/Documents/SatDump_ReWork/build/noaa_mhs_test_gac/MHS/product.cbor", "NOAA-19 GAC");
|
|
|
|
|
// loadProductsInViewer("/home/alan/Documents/SatDump_ReWork/build/noaa_mhs_test_gac/HIRS/product.cbor", "NOAA-19 GAC");
|
|
|
|
|
// loadProductsInViewer("/home/alan/Documents/SatDump_ReWork/build/noaa_mhs_test_gac/AVHRR/product.cbor", "NOAA-19 GAC");
|
2022-04-26 15:07:18 +02:00
|
|
|
// loadProductsInViewer("/home/alan/Documents/SatDump_ReWork/build/npp_hrd_new/VIIRS/product.cbor", "JPSS-1 HRD");
|
|
|
|
|
// loadProductsInViewer("/home/alan/Documents/SatDump_ReWork/build/m2_lrpt_test/MSU-MR/product.cbor", "METEOR-M2 LRPT");
|
2022-04-13 17:51:30 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-16 08:10:25 +02:00
|
|
|
void ViewerApplication::loadDatasetInViewer(std::string path)
|
|
|
|
|
{
|
|
|
|
|
ProductDataSet dataset;
|
|
|
|
|
dataset.load(path);
|
|
|
|
|
|
2022-05-02 08:11:47 -07:00
|
|
|
std::string pro_directory = std::filesystem::path(path).parent_path().string();
|
2022-04-16 08:10:25 +02:00
|
|
|
for (std::string pro_path : dataset.products_list)
|
|
|
|
|
loadProductsInViewer(pro_directory + "/" + pro_path, dataset.satellite_name + " " + timestamp_to_string(dataset.timestamp));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ViewerApplication::loadProductsInViewer(std::string path, std::string dataset_name)
|
2022-04-13 17:51:30 +02:00
|
|
|
{
|
|
|
|
|
if (std::filesystem::exists(path))
|
|
|
|
|
{
|
|
|
|
|
std::shared_ptr<Products> products = loadProducts(path);
|
|
|
|
|
|
|
|
|
|
// Get instrument settings
|
|
|
|
|
nlohmann::ordered_json instrument_viewer_settings;
|
|
|
|
|
if (config::main_cfg["viewer"]["instruments"].contains(products->instrument_name))
|
|
|
|
|
instrument_viewer_settings = config::main_cfg["viewer"]["instruments"][products->instrument_name];
|
|
|
|
|
else
|
|
|
|
|
logger->error("Unknown instrument : {:s}!", products->instrument_name);
|
|
|
|
|
|
|
|
|
|
// Init Handler
|
2022-04-29 13:00:28 +02:00
|
|
|
std::string handler_id;
|
|
|
|
|
if (instrument_viewer_settings.contains("handler"))
|
2022-05-07 18:16:24 +02:00
|
|
|
handler_id = instrument_viewer_settings["handler"].get<std::string>();
|
2022-04-29 13:00:28 +02:00
|
|
|
else if (products->contents["type"] == "image")
|
|
|
|
|
handler_id = "image_handler";
|
2022-04-13 17:51:30 +02:00
|
|
|
logger->debug("Using handler {:s} for instrument {:s}", handler_id, products->instrument_name);
|
|
|
|
|
std::shared_ptr<ViewerHandler> handler = viewer_handlers_registry[handler_id]();
|
|
|
|
|
|
|
|
|
|
handler->products = products.get();
|
|
|
|
|
handler->instrument_cfg = instrument_viewer_settings;
|
|
|
|
|
handler->init();
|
|
|
|
|
|
2022-04-16 08:10:25 +02:00
|
|
|
if (dataset_name != "")
|
|
|
|
|
{
|
|
|
|
|
bool dataset_exists = false;
|
|
|
|
|
for (std::string dataset_name2 : opened_datasets)
|
2022-05-12 18:19:01 +02:00
|
|
|
dataset_exists = dataset_exists | (dataset_name2 == dataset_name);
|
2022-04-16 08:10:25 +02:00
|
|
|
|
|
|
|
|
if (!dataset_exists)
|
|
|
|
|
opened_datasets.push_back(dataset_name);
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-13 17:51:30 +02:00
|
|
|
// Push products and handler
|
2022-04-16 08:10:25 +02:00
|
|
|
products_and_handlers.push_back({products, handler, dataset_name});
|
2022-04-13 17:51:30 +02:00
|
|
|
}
|
2022-04-12 20:18:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ViewerApplication::~ViewerApplication()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-16 08:10:25 +02:00
|
|
|
ImRect ViewerApplication::renderHandler(ProductsHandler &ph, int index)
|
|
|
|
|
{
|
|
|
|
|
std::string label = ph.products->instrument_name;
|
|
|
|
|
if (ph.handler->instrument_cfg.contains("name"))
|
|
|
|
|
label = ph.handler->instrument_cfg["name"].get<std::string>();
|
|
|
|
|
|
|
|
|
|
ImGui::TreeNodeEx(label.c_str(), ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | (index == current_handler_id ? ImGuiTreeNodeFlags_Selected : 0));
|
|
|
|
|
if (ImGui::IsItemClicked())
|
|
|
|
|
current_handler_id = index;
|
|
|
|
|
|
|
|
|
|
ImRect rect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
|
|
|
|
|
|
|
|
|
if (index == current_handler_id)
|
|
|
|
|
{
|
|
|
|
|
ImGui::TreePush();
|
|
|
|
|
products_and_handlers[current_handler_id].handler->drawTreeMenu();
|
|
|
|
|
ImGui::TreePop();
|
|
|
|
|
}
|
|
|
|
|
// ImGui::InputInt("Current Product", ¤t_handler_id);
|
|
|
|
|
|
|
|
|
|
return rect;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-12 20:18:44 +02:00
|
|
|
void ViewerApplication::drawPanel()
|
|
|
|
|
{
|
|
|
|
|
if (ImGui::CollapsingHeader("General"))
|
|
|
|
|
{
|
2022-04-16 08:10:25 +02:00
|
|
|
for (std::string dataset_name : opened_datasets)
|
2022-04-13 17:51:30 +02:00
|
|
|
{
|
2022-04-16 08:10:25 +02:00
|
|
|
if (products_cnt_in_dataset(dataset_name))
|
2022-04-13 17:51:30 +02:00
|
|
|
{
|
2022-04-16 08:10:25 +02:00
|
|
|
ImGui::TreeNodeEx(dataset_name.c_str(), ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
2022-04-13 17:51:30 +02:00
|
|
|
ImGui::TreePush();
|
2022-04-16 08:10:25 +02:00
|
|
|
|
|
|
|
|
const ImColor TreeLineColor = ImColor(128, 128, 128, 255); // ImGui::GetColorU32(ImGuiCol_Text);
|
|
|
|
|
const float SmallOffsetX = 11.0f; // for now, a hardcoded value; should take into account tree indent size
|
|
|
|
|
ImDrawList *drawList = ImGui::GetWindowDrawList();
|
|
|
|
|
|
|
|
|
|
ImVec2 verticalLineStart = ImGui::GetCursorScreenPos();
|
|
|
|
|
verticalLineStart.x += SmallOffsetX; // to nicely line up with the arrow symbol
|
|
|
|
|
ImVec2 verticalLineEnd = verticalLineStart;
|
|
|
|
|
|
2022-05-12 18:19:01 +02:00
|
|
|
for (int i = 0; i < (int)products_and_handlers.size(); i++)
|
2022-04-16 08:10:25 +02:00
|
|
|
if (products_and_handlers[i].dataset_name == dataset_name)
|
|
|
|
|
{
|
|
|
|
|
const float HorizontalTreeLineSize = 8.0f; // chosen arbitrarily
|
|
|
|
|
const ImRect childRect = renderHandler(products_and_handlers[i], i); // RenderTree(child);
|
|
|
|
|
const float midpoint = (childRect.Min.y + childRect.Max.y) / 2.0f;
|
|
|
|
|
drawList->AddLine(ImVec2(verticalLineStart.x, midpoint), ImVec2(verticalLineStart.x + HorizontalTreeLineSize, midpoint), TreeLineColor);
|
|
|
|
|
verticalLineEnd.y = midpoint;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
drawList->AddLine(verticalLineStart, verticalLineEnd, TreeLineColor);
|
|
|
|
|
|
2022-04-13 17:51:30 +02:00
|
|
|
ImGui::TreePop();
|
|
|
|
|
}
|
2022-04-16 08:10:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Render unclassified
|
|
|
|
|
if (products_cnt_in_dataset(""))
|
|
|
|
|
{
|
|
|
|
|
ImGui::TreeNodeEx("Others", ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
|
|
|
|
ImGui::TreePush();
|
2022-05-12 18:19:01 +02:00
|
|
|
for (int i = 0; i < (int)products_and_handlers.size(); i++)
|
2022-04-16 08:10:25 +02:00
|
|
|
if (products_and_handlers[i].dataset_name == "")
|
|
|
|
|
renderHandler(products_and_handlers[i], i);
|
|
|
|
|
ImGui::TreePop();
|
2022-04-13 17:51:30 +02:00
|
|
|
}
|
2022-05-09 11:32:01 +02:00
|
|
|
|
|
|
|
|
if (select_dataset_dialog.draw())
|
|
|
|
|
loadDatasetInViewer(select_dataset_dialog.getPath());
|
|
|
|
|
if (select_products_dialog.draw())
|
|
|
|
|
loadProductsInViewer(select_products_dialog.getPath());
|
2022-04-12 20:18:44 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ViewerApplication::drawContent()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ViewerApplication::drawUI()
|
|
|
|
|
{
|
|
|
|
|
ImVec2 viewer_size = ImGui::GetContentRegionAvail();
|
|
|
|
|
ImGui::BeginGroup();
|
2022-04-21 22:42:04 +02:00
|
|
|
ImGui::BeginChild("ViewerChildPanel", {float(viewer_size.x * 0.20), float(viewer_size.y)}, false);
|
2022-04-12 20:18:44 +02:00
|
|
|
{
|
|
|
|
|
drawPanel();
|
2022-05-07 18:16:24 +02:00
|
|
|
if (products_and_handlers.size() > 0)
|
|
|
|
|
products_and_handlers[current_handler_id].handler->drawMenu();
|
2022-04-12 20:18:44 +02:00
|
|
|
}
|
|
|
|
|
ImGui::EndChild();
|
|
|
|
|
ImGui::EndGroup();
|
|
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
|
|
ImGui::BeginGroup();
|
2022-05-07 18:16:24 +02:00
|
|
|
if (products_and_handlers.size() > 0)
|
|
|
|
|
products_and_handlers[current_handler_id].handler->drawContents({float(viewer_size.x * 0.80 - 4), float(viewer_size.y)});
|
2022-04-12 20:18:44 +02:00
|
|
|
ImGui::EndGroup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::map<std::string, std::function<std::shared_ptr<ViewerHandler>()>> viewer_handlers_registry;
|
|
|
|
|
void registerViewerHandlers()
|
|
|
|
|
{
|
|
|
|
|
viewer_handlers_registry.emplace(ImageViewerHandler::getID(), ImageViewerHandler::getInstance);
|
2022-04-16 08:10:25 +02:00
|
|
|
viewer_handlers_registry.emplace(RadiationViewerHandler::getID(), RadiationViewerHandler::getInstance);
|
2022-04-12 20:18:44 +02:00
|
|
|
}
|
|
|
|
|
};
|