2025-02-09 16:34:06 +01:00
|
|
|
#include "projection_handler.h"
|
2025-07-18 14:06:26 +02:00
|
|
|
#include "core/config.h"
|
2025-06-01 22:05:25 +02:00
|
|
|
#include "core/style.h"
|
2025-07-18 17:01:45 +02:00
|
|
|
#include "handlers/vector/addmenu.h"
|
2025-05-25 14:30:24 +02:00
|
|
|
#include "image/image.h"
|
|
|
|
|
#include "image/meta.h"
|
2025-04-14 19:03:42 +01:00
|
|
|
#include "logger.h"
|
2025-02-09 16:34:06 +01:00
|
|
|
|
|
|
|
|
#include "../image/image_handler.h"
|
2025-04-14 19:03:42 +01:00
|
|
|
#include "../vector/shapefile_handler.h"
|
2025-02-09 16:34:06 +01:00
|
|
|
|
2025-02-14 15:55:03 +01:00
|
|
|
// TODOREWORK
|
2025-06-01 22:05:25 +02:00
|
|
|
#include "projection/raytrace/gcp_compute.h"
|
2025-05-12 23:14:50 +02:00
|
|
|
#include "projection/reproject_img.h"
|
2025-02-14 15:55:03 +01:00
|
|
|
#include "projection/reprojector.h"
|
|
|
|
|
|
2025-06-01 22:05:25 +02:00
|
|
|
#include "projection/standard/proj_json.h"
|
2025-06-22 23:31:29 +02:00
|
|
|
#include <exception>
|
2025-06-01 22:05:25 +02:00
|
|
|
|
2025-02-09 16:34:06 +01:00
|
|
|
namespace satdump
|
|
|
|
|
{
|
2025-05-19 22:26:32 +02:00
|
|
|
namespace handlers
|
2025-02-09 16:34:06 +01:00
|
|
|
{
|
2025-05-12 23:14:50 +02:00
|
|
|
ProjectionHandler::ProjectionHandler()
|
|
|
|
|
{
|
|
|
|
|
handler_tree_icon = u8"\uf6e6";
|
|
|
|
|
setCanSubBeReorgTo(true);
|
2025-07-18 14:06:26 +02:00
|
|
|
|
|
|
|
|
if (!satdump_cfg.main_cfg["user"]["projection_defaults"].is_null())
|
|
|
|
|
setConfig(satdump_cfg.main_cfg["user"]["projection_defaults"]);
|
2025-05-12 23:14:50 +02:00
|
|
|
}
|
2025-02-09 16:34:06 +01:00
|
|
|
|
2025-07-18 14:06:26 +02:00
|
|
|
ProjectionHandler::~ProjectionHandler()
|
|
|
|
|
{
|
|
|
|
|
satdump_cfg.main_cfg["user"]["projection_defaults"] = getConfig();
|
|
|
|
|
satdump_cfg.saveUser();
|
|
|
|
|
}
|
2025-02-09 16:34:06 +01:00
|
|
|
|
|
|
|
|
void ProjectionHandler::drawMenu()
|
|
|
|
|
{
|
|
|
|
|
bool needs_to_be_disabled = is_processing;
|
|
|
|
|
|
2025-07-18 11:42:18 +02:00
|
|
|
if (ImGui::CollapsingHeader("Projection", ImGuiTreeNodeFlags_DefaultOpen))
|
2025-02-09 16:34:06 +01:00
|
|
|
{
|
|
|
|
|
if (needs_to_be_disabled)
|
|
|
|
|
style::beginDisabled();
|
|
|
|
|
|
2025-02-14 15:55:03 +01:00
|
|
|
projui.drawUI();
|
|
|
|
|
|
|
|
|
|
// needs_to_update |= TODO; // TODOREWORK move in top drawMenu?
|
2025-06-22 21:36:18 +02:00
|
|
|
if (ImGui::Button("Project"))
|
2025-02-14 15:55:03 +01:00
|
|
|
needs_to_update = true;
|
|
|
|
|
|
2025-02-09 16:34:06 +01:00
|
|
|
if (needs_to_be_disabled)
|
|
|
|
|
style::endDisabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// TODOREWORK UPDATE
|
|
|
|
|
if (needs_to_update)
|
|
|
|
|
{
|
|
|
|
|
asyncProcess();
|
|
|
|
|
needs_to_update = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
img_handler.drawMenu();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectionHandler::setConfig(nlohmann::json p)
|
|
|
|
|
{
|
|
|
|
|
if (p.contains("image"))
|
|
|
|
|
img_handler.setConfig(p["image"]);
|
2025-07-18 14:06:26 +02:00
|
|
|
if (p.contains("proj"))
|
|
|
|
|
projui = p["proj"];
|
2025-02-09 16:34:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nlohmann::json ProjectionHandler::getConfig()
|
|
|
|
|
{
|
|
|
|
|
nlohmann::json p;
|
|
|
|
|
|
|
|
|
|
p["image"] = img_handler.getConfig();
|
2025-07-18 14:06:26 +02:00
|
|
|
p["proj"] = projui;
|
2025-02-09 16:34:06 +01:00
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-01 22:05:25 +02:00
|
|
|
// TODOREWORK
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
struct ProjBounds
|
|
|
|
|
{
|
|
|
|
|
double min_lon;
|
|
|
|
|
double max_lon;
|
|
|
|
|
double min_lat;
|
|
|
|
|
double max_lat;
|
|
|
|
|
bool valid = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ProjBounds determineProjectionBounds(image::Image &img)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
auto cfg = image::get_metadata_proj_cfg(img);
|
|
|
|
|
cfg["width"] = img.width();
|
|
|
|
|
cfg["height"] = img.height();
|
|
|
|
|
image::set_metadata_proj_cfg(img, cfg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!image::has_metadata(img))
|
|
|
|
|
return {0, 0, 0, 0, false};
|
|
|
|
|
|
|
|
|
|
if (!image::get_metadata(img).contains("proj_cfg"))
|
|
|
|
|
return {0, 0, 0, 0, false};
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
nlohmann::json params = image::get_metadata(img)["proj_cfg"];
|
|
|
|
|
|
|
|
|
|
::proj::projection_t proj;
|
|
|
|
|
bool proj_err = false;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
proj = params;
|
|
|
|
|
}
|
|
|
|
|
catch (std::exception &)
|
|
|
|
|
{
|
|
|
|
|
proj_err = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProjBounds bounds;
|
|
|
|
|
if (!::proj::projection_setup(&proj) && !proj_err)
|
|
|
|
|
{
|
|
|
|
|
if (proj.type == ::proj::ProjType_Geos)
|
|
|
|
|
{
|
|
|
|
|
bounds.min_lat = -90;
|
|
|
|
|
bounds.max_lat = 90;
|
|
|
|
|
bounds.min_lon = proj.lam0 * RAD2DEG - 90;
|
|
|
|
|
bounds.max_lon = proj.lam0 * RAD2DEG + 90;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
::proj::projection_perform_inv(&proj, 0, 0, &bounds.min_lon, &bounds.max_lat);
|
|
|
|
|
::proj::projection_perform_inv(&proj, img.width(), img.height(), &bounds.max_lon, &bounds.min_lat);
|
|
|
|
|
}
|
|
|
|
|
bounds.valid = true;
|
|
|
|
|
::proj::projection_free(&proj);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
auto gcps = satdump::projection::compute_gcps(params);
|
|
|
|
|
|
|
|
|
|
bounds.min_lon = 180;
|
|
|
|
|
bounds.max_lon = -180;
|
|
|
|
|
bounds.min_lat = 90;
|
|
|
|
|
bounds.max_lat = -90;
|
|
|
|
|
for (auto &gcp : gcps)
|
|
|
|
|
{
|
|
|
|
|
if (bounds.min_lon > gcp.lon)
|
|
|
|
|
bounds.min_lon = gcp.lon;
|
|
|
|
|
if (bounds.max_lon < gcp.lon)
|
|
|
|
|
bounds.max_lon = gcp.lon;
|
|
|
|
|
if (bounds.min_lat > gcp.lat)
|
|
|
|
|
bounds.min_lat = gcp.lat;
|
|
|
|
|
if (bounds.max_lat < gcp.lat)
|
|
|
|
|
bounds.max_lat = gcp.lat;
|
|
|
|
|
}
|
|
|
|
|
if (gcps.size() > 2)
|
|
|
|
|
bounds.valid = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bounds.min_lon -= 1;
|
|
|
|
|
bounds.max_lon += 1;
|
|
|
|
|
bounds.min_lat -= 1;
|
|
|
|
|
bounds.max_lat += 1;
|
|
|
|
|
|
|
|
|
|
if (bounds.min_lon < -180)
|
|
|
|
|
bounds.min_lon = -180;
|
|
|
|
|
if (bounds.max_lon > 180)
|
|
|
|
|
bounds.max_lon = 180;
|
|
|
|
|
if (bounds.min_lat < -90)
|
|
|
|
|
bounds.min_lat = -90;
|
|
|
|
|
if (bounds.max_lat > 90)
|
|
|
|
|
bounds.max_lat = 90;
|
|
|
|
|
|
|
|
|
|
return bounds;
|
|
|
|
|
}
|
|
|
|
|
catch (std::exception &e)
|
|
|
|
|
{
|
|
|
|
|
logger->info("Could not get Bounds! %s", e.what());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {0, 0, 0, 0, false};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct Pos
|
|
|
|
|
{
|
|
|
|
|
double lon;
|
|
|
|
|
double lat;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void computePositionCenter(std::vector<Pos> &gcps, double &lon, double &lat)
|
|
|
|
|
{
|
|
|
|
|
double x_total = 0;
|
|
|
|
|
double y_total = 0;
|
|
|
|
|
double z_total = 0;
|
|
|
|
|
|
|
|
|
|
for (auto &pt : gcps)
|
|
|
|
|
{
|
|
|
|
|
x_total += cos(pt.lat * DEG_TO_RAD) * cos(pt.lon * DEG_TO_RAD);
|
|
|
|
|
y_total += cos(pt.lat * DEG_TO_RAD) * sin(pt.lon * DEG_TO_RAD);
|
|
|
|
|
z_total += sin(pt.lat * DEG_TO_RAD);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
x_total /= gcps.size();
|
|
|
|
|
y_total /= gcps.size();
|
|
|
|
|
z_total /= gcps.size();
|
|
|
|
|
|
|
|
|
|
lon = atan2(y_total, x_total) * RAD_TO_DEG;
|
|
|
|
|
double hyp = sqrt(x_total * x_total + y_total * y_total);
|
|
|
|
|
lat = atan2(z_total, hyp) * RAD_TO_DEG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tryAutoTuneProjection(ProjBounds bounds, nlohmann::json ¶ms)
|
|
|
|
|
{
|
|
|
|
|
::proj::projection_t p_main = params;
|
|
|
|
|
if (p_main.type == ::proj::ProjType_Equirectangular)
|
|
|
|
|
{
|
|
|
|
|
params["offset_x"] = bounds.min_lon;
|
|
|
|
|
params["offset_y"] = bounds.max_lat;
|
|
|
|
|
if (!params.contains("width") || !params.contains("height"))
|
|
|
|
|
{
|
|
|
|
|
double scale_x = params.contains("scale_x") ? params["scale_x"].get<double>() : 0.016;
|
|
|
|
|
double scale_y = params.contains("scale_y") ? params["scale_y"].get<double>() : 0.016;
|
|
|
|
|
params["scalar_x"] = scale_x;
|
|
|
|
|
params["scalar_y"] = -scale_y;
|
|
|
|
|
params["width"] = (bounds.max_lon - bounds.min_lon) / scale_x;
|
|
|
|
|
params["height"] = (bounds.max_lat - bounds.min_lat) / scale_y;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
double width = params["width"];
|
|
|
|
|
double height = params["height"];
|
|
|
|
|
params["scalar_x"] = (bounds.max_lon - bounds.min_lon) / width;
|
|
|
|
|
params["scalar_y"] = -(bounds.max_lat - bounds.min_lat) / height;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (p_main.type == ::proj::ProjType_Stereographic)
|
|
|
|
|
{
|
|
|
|
|
std::vector<Pos> posi;
|
|
|
|
|
posi.push_back({bounds.max_lon, bounds.max_lat});
|
|
|
|
|
posi.push_back({bounds.min_lon, bounds.min_lat});
|
|
|
|
|
posi.push_back({bounds.min_lon, bounds.max_lat});
|
|
|
|
|
posi.push_back({bounds.max_lon, bounds.min_lat});
|
|
|
|
|
double center_lon = 0, center_lat = 0;
|
|
|
|
|
computePositionCenter(posi, center_lon, center_lat);
|
|
|
|
|
|
|
|
|
|
params["lon0"] = center_lon;
|
|
|
|
|
params["lat0"] = center_lat;
|
|
|
|
|
params["offset_x"] = 0.0;
|
|
|
|
|
params["offset_y"] = 0.0;
|
|
|
|
|
params["scalar_x"] = 1.0;
|
|
|
|
|
params["scalar_y"] = 1.0;
|
|
|
|
|
::proj::projection_t proj = params;
|
|
|
|
|
if (!::proj::projection_setup(&proj))
|
|
|
|
|
{
|
|
|
|
|
double x1, x2;
|
|
|
|
|
double y1, y2;
|
|
|
|
|
::proj::projection_perform_fwd(&proj, bounds.max_lon, bounds.max_lat, &x1, &y1);
|
|
|
|
|
::proj::projection_perform_fwd(&proj, bounds.min_lon, bounds.min_lat, &x2, &y2);
|
|
|
|
|
|
|
|
|
|
double dist1 = sqrt(x1 * x1 + y1 * y1);
|
|
|
|
|
double dist2 = sqrt(x2 * x2 + y2 * y2);
|
|
|
|
|
double max_dist = std::max(dist1, dist2);
|
|
|
|
|
|
|
|
|
|
if (!params.contains("width") || !params.contains("height"))
|
|
|
|
|
{
|
|
|
|
|
double scale_x = params.contains("scale_x") ? params["scale_x"].get<double>() : 0.016;
|
|
|
|
|
double scale_y = params.contains("scale_y") ? params["scale_y"].get<double>() : 0.016;
|
|
|
|
|
params["scalar_x"] = scale_x;
|
|
|
|
|
params["scalar_y"] = -scale_y;
|
|
|
|
|
params["width"] = (max_dist * 2) / scale_x;
|
|
|
|
|
params["height"] = (max_dist * 2) / scale_y;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
double width = params["width"];
|
|
|
|
|
double height = params["height"];
|
|
|
|
|
double scale_x = params["scalar_x"] = (max_dist * 2) / width;
|
|
|
|
|
double scale_y = params["scalar_y"] = -(max_dist * 2) / height;
|
|
|
|
|
params["offset_x"] = -width * 0.5 * scale_x;
|
|
|
|
|
params["offset_y"] = height * 0.5 * -scale_y;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/*else if (p_main.type == proj::ProjType_UniversalTransverseMercator)
|
|
|
|
|
{
|
|
|
|
|
params["offset_x"] = 0.0;
|
|
|
|
|
params["offset_y"] = 0.0;
|
|
|
|
|
params["scalar_x"] = 1.0;
|
|
|
|
|
params["scalar_y"] = 1.0;
|
|
|
|
|
proj::projection_t proj = params;
|
|
|
|
|
if (!proj::projection_setup(&proj))
|
|
|
|
|
{
|
|
|
|
|
double dummy;
|
|
|
|
|
double tl_x, tl_y;
|
|
|
|
|
double br_x, br_y;
|
|
|
|
|
if (!proj::projection_perform_fwd(&proj, bounds.max_lon, bounds.max_lat, &dummy, &tl_y) &&
|
|
|
|
|
!proj::projection_perform_fwd(&proj, bounds.max_lon, bounds.min_lat, &br_x, &dummy) &&
|
|
|
|
|
!proj::projection_perform_fwd(&proj, bounds.min_lon, bounds.min_lat, &tl_x, &dummy) &&
|
|
|
|
|
!proj::projection_perform_fwd(&proj, (bounds.min_lon + bounds.max_lon) / 2.0, bounds.min_lat, &dummy, &br_y))
|
|
|
|
|
{
|
|
|
|
|
logger->trace("Final Bounds are : %f, %f - %f, %f", tl_x, tl_y, br_x, br_y);
|
|
|
|
|
params["offset_x"] = tl_x;
|
|
|
|
|
params["offset_y"] = tl_y;
|
|
|
|
|
params["scalar_x"] = -(tl_x - br_x) / vx;
|
|
|
|
|
params["scalar_y"] = -(tl_y - br_y) / vy;
|
|
|
|
|
}
|
|
|
|
|
proj::projection_free(&proj);
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
}
|
|
|
|
|
} // namespace
|
|
|
|
|
|
2025-02-09 16:34:06 +01:00
|
|
|
void ProjectionHandler::do_process()
|
|
|
|
|
{
|
2025-06-22 23:31:29 +02:00
|
|
|
try
|
2025-06-01 22:05:25 +02:00
|
|
|
{
|
2025-06-22 23:31:29 +02:00
|
|
|
image::Image img;
|
|
|
|
|
|
|
|
|
|
// TODOREWORK
|
|
|
|
|
auto proj = projui.get_proj();
|
|
|
|
|
proj["width"] = projui.projections_image_width;
|
|
|
|
|
proj["height"] = projui.projections_image_height;
|
2025-06-01 22:05:25 +02:00
|
|
|
|
|
|
|
|
{
|
2025-06-22 23:31:29 +02:00
|
|
|
auto &target_cfg = proj;
|
2025-06-01 22:05:25 +02:00
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
// Automatic projection settings!
|
|
|
|
|
if (projui.projection_auto_mode && (target_cfg["type"] == "equirec" || target_cfg["type"] == "stereo"))
|
2025-06-01 22:05:25 +02:00
|
|
|
{
|
2025-06-22 23:31:29 +02:00
|
|
|
ProjBounds bounds;
|
|
|
|
|
bounds.min_lon = 180;
|
|
|
|
|
bounds.max_lon = -180;
|
|
|
|
|
bounds.min_lat = 90;
|
|
|
|
|
bounds.max_lat = -90;
|
2025-06-01 22:05:25 +02:00
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
for (int i = subhandlers.size() - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
auto &h = subhandlers[i];
|
|
|
|
|
if (h->getID() == "image_handler")
|
2025-06-01 22:05:25 +02:00
|
|
|
{
|
2025-06-22 23:31:29 +02:00
|
|
|
ImageHandler *im_h = (ImageHandler *)h.get();
|
|
|
|
|
|
|
|
|
|
auto boundshere = determineProjectionBounds(im_h->getImage());
|
|
|
|
|
if (boundshere.valid)
|
|
|
|
|
{
|
|
|
|
|
if (boundshere.min_lon < bounds.min_lon)
|
|
|
|
|
bounds.min_lon = boundshere.min_lon;
|
|
|
|
|
if (boundshere.max_lon > bounds.max_lon)
|
|
|
|
|
bounds.max_lon = boundshere.max_lon;
|
|
|
|
|
if (boundshere.min_lat < bounds.min_lat)
|
|
|
|
|
bounds.min_lat = boundshere.min_lat;
|
|
|
|
|
if (boundshere.max_lat > bounds.max_lat)
|
|
|
|
|
bounds.max_lat = boundshere.max_lat;
|
|
|
|
|
}
|
2025-06-01 22:05:25 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
logger->trace("Final Bounds are : %f, %f - %f, %f", bounds.min_lon, bounds.min_lat, bounds.max_lon, bounds.max_lat);
|
2025-06-01 22:05:25 +02:00
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
if (projui.projection_auto_scale_mode)
|
|
|
|
|
{
|
|
|
|
|
if (target_cfg.contains("width"))
|
|
|
|
|
target_cfg.erase("width");
|
|
|
|
|
if (target_cfg.contains("height"))
|
|
|
|
|
target_cfg.erase("height");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (target_cfg.contains("scale_x"))
|
|
|
|
|
target_cfg.erase("scale_x");
|
|
|
|
|
if (target_cfg.contains("scale_y"))
|
|
|
|
|
target_cfg.erase("scale_y");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tryAutoTuneProjection(bounds, target_cfg);
|
2025-06-01 22:05:25 +02:00
|
|
|
if (target_cfg.contains("width"))
|
2025-06-22 23:31:29 +02:00
|
|
|
projui.projections_image_width = target_cfg["width"];
|
2025-06-01 22:05:25 +02:00
|
|
|
if (target_cfg.contains("height"))
|
2025-06-22 23:31:29 +02:00
|
|
|
projui.projections_image_height = target_cfg["height"];
|
2025-06-01 22:05:25 +02:00
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
logger->debug("\n%s", target_cfg.dump(4).c_str());
|
|
|
|
|
}
|
2025-06-01 22:05:25 +02:00
|
|
|
}
|
|
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
// TODOREWORK
|
2025-06-01 22:05:25 +02:00
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
std::vector<image::Image> all_imgs;
|
|
|
|
|
for (int i = subhandlers.size() - 1; i >= 0; i--)
|
2025-02-09 16:34:06 +01:00
|
|
|
{
|
2025-06-22 23:31:29 +02:00
|
|
|
auto &h = subhandlers[i];
|
|
|
|
|
if (h->getID() == "image_handler")
|
|
|
|
|
{
|
|
|
|
|
ImageHandler *im_h = (ImageHandler *)h.get();
|
|
|
|
|
logger->critical("Drawing IMAGE!");
|
|
|
|
|
// sh_h->draw_to_image(curr_image, pfunc);
|
|
|
|
|
|
|
|
|
|
// TODOREWORK!!!!
|
|
|
|
|
logger->trace("Proj : \n%s\n", proj.dump(4).c_str());
|
|
|
|
|
auto im = projection::reprojectImage(im_h->getImage(), proj);
|
|
|
|
|
all_imgs.push_back(im);
|
|
|
|
|
logger->critical("DONE REPROJECTING!");
|
|
|
|
|
}
|
2025-02-09 16:34:06 +01:00
|
|
|
}
|
|
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
if (all_imgs.size() > 0)
|
|
|
|
|
{
|
2025-08-13 15:12:36 +02:00
|
|
|
img.init(all_imgs[0].depth(), all_imgs[0].width(), all_imgs[0].height(), 4);
|
2025-06-22 23:31:29 +02:00
|
|
|
image::set_metadata_proj_cfg(img, image::get_metadata_proj_cfg(all_imgs[0]));
|
|
|
|
|
}
|
2025-05-13 19:54:55 +02:00
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
for (int i = 0; i < all_imgs.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
logger->trace("Draw %d", i);
|
|
|
|
|
img.draw_image_alpha(all_imgs[i]);
|
|
|
|
|
}
|
2025-05-13 19:54:55 +02:00
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
for (int i = subhandlers.size() - 1; i >= 0; i--)
|
2025-05-12 23:14:50 +02:00
|
|
|
{
|
2025-06-22 23:31:29 +02:00
|
|
|
auto &h = subhandlers[i];
|
|
|
|
|
if (h->getID() == "shapefile_handler")
|
|
|
|
|
{
|
|
|
|
|
ShapefileHandler *sh_h = (ShapefileHandler *)h.get();
|
|
|
|
|
logger->critical("Drawing OVERLAY!");
|
2025-05-12 23:14:50 +02:00
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
nlohmann::json cfg = image::get_metadata_proj_cfg(img);
|
|
|
|
|
cfg["width"] = img.width();
|
|
|
|
|
cfg["height"] = img.height();
|
|
|
|
|
std::unique_ptr<projection::Projection> p = std::make_unique<projection::Projection>();
|
|
|
|
|
*p = cfg;
|
|
|
|
|
p->init(1, 0);
|
2025-05-12 23:14:50 +02:00
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
auto pfunc = [&p](double lat, double lon, double h, double w) mutable -> std::pair<double, double>
|
|
|
|
|
{
|
|
|
|
|
double x, y;
|
|
|
|
|
if (p->forward(geodetic::geodetic_coords_t(lat, lon, 0, false), x, y) || x < 0 || x >= w || y < 0 || y >= h)
|
|
|
|
|
return {-1, -1};
|
|
|
|
|
else
|
|
|
|
|
return {x, y};
|
|
|
|
|
};
|
|
|
|
|
sh_h->draw_to_image(img, pfunc);
|
|
|
|
|
}
|
2025-05-12 23:14:50 +02:00
|
|
|
}
|
|
|
|
|
|
2025-06-22 23:31:29 +02:00
|
|
|
img_handler.setImage(img);
|
|
|
|
|
}
|
|
|
|
|
catch (std::exception &e)
|
|
|
|
|
{
|
|
|
|
|
logger->error("Error projecting %s", e.what());
|
|
|
|
|
}
|
2025-02-09 16:34:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectionHandler::drawMenuBar()
|
|
|
|
|
{
|
2025-05-20 21:35:04 +02:00
|
|
|
img_handler.drawSaveMenu(); // TODOREWORK remove this
|
2025-07-18 17:01:45 +02:00
|
|
|
/*if (ImGui::MenuItem("Image To Handler"))
|
|
|
|
|
{
|
|
|
|
|
std::shared_ptr<ImageHandler> a = std::make_shared<ImageHandler>();
|
|
|
|
|
a->setConfig(img_handler.getConfig());
|
|
|
|
|
a->updateImage(img_handler.image);
|
|
|
|
|
addSubHandler(a);
|
|
|
|
|
}*/
|
|
|
|
|
// TODOREWORK
|
|
|
|
|
|
|
|
|
|
renderVectorOverlayMenu(this);
|
2025-02-09 16:34:06 +01:00
|
|
|
}
|
|
|
|
|
|
2025-04-14 19:03:42 +01:00
|
|
|
void ProjectionHandler::drawContents(ImVec2 win_size) { img_handler.drawContents(win_size); }
|
2025-05-19 22:26:32 +02:00
|
|
|
} // namespace handlers
|
2025-04-14 19:03:42 +01:00
|
|
|
} // namespace satdump
|