2021-11-12 19:50:05 +01:00
|
|
|
#include "tps_transform.h"
|
|
|
|
|
#include <map>
|
|
|
|
|
#include "logger.h"
|
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
This file is originally from https://github.com/OSGeo/gdal
|
|
|
|
|
It was modified for the purposes required here.
|
|
|
|
|
|
|
|
|
|
All credits go to the GDAL Project
|
|
|
|
|
*/
|
|
|
|
|
|
2022-04-21 13:18:43 +02:00
|
|
|
namespace satdump
|
2021-11-12 19:50:05 +01:00
|
|
|
{
|
|
|
|
|
namespace projection
|
|
|
|
|
{
|
|
|
|
|
TPSTransform::TPSTransform()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TPSTransform::TPSTransform(std::vector<GCP> gcps)
|
|
|
|
|
{
|
|
|
|
|
init(gcps);
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-05 22:00:04 +02:00
|
|
|
int TPSTransform::init(std::vector<GCP> gcps, bool forward, bool reverse)
|
2021-11-12 19:50:05 +01:00
|
|
|
{
|
|
|
|
|
// Allocate transform info.
|
|
|
|
|
if (has_been_init)
|
|
|
|
|
{
|
|
|
|
|
delete spline_reverse;
|
|
|
|
|
delete spline_forward;
|
|
|
|
|
}
|
|
|
|
|
spline_reverse = new VizGeorefSpline2D(2);
|
|
|
|
|
spline_forward = new VizGeorefSpline2D(2);
|
|
|
|
|
has_been_init = true;
|
|
|
|
|
|
|
|
|
|
// Attach (non-redundant) points to the transformation.
|
|
|
|
|
std::map<std::pair<double, double>, int> oMapPixelLineToIdx;
|
|
|
|
|
std::map<std::pair<double, double>, int> oMapXYToIdx;
|
|
|
|
|
for (int iGCP = 0; iGCP < (int)gcps.size(); iGCP++)
|
|
|
|
|
{
|
|
|
|
|
const double afPL[2] = {gcps[iGCP].x, gcps[iGCP].y};
|
|
|
|
|
const double afXY[2] = {gcps[iGCP].lon, gcps[iGCP].lat};
|
|
|
|
|
|
2023-11-27 18:28:28 +01:00
|
|
|
auto oIter(oMapPixelLineToIdx.find(std::pair<double, double>(afPL[0], afPL[1])));
|
2021-11-12 19:50:05 +01:00
|
|
|
|
|
|
|
|
if (oIter != oMapPixelLineToIdx.end())
|
|
|
|
|
{
|
|
|
|
|
if (afXY[0] == gcps[oIter->second].lon && afXY[1] == gcps[oIter->second].lat)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger->warn("2 GCPs have the same X,Y!");
|
2023-10-06 22:20:55 +02:00
|
|
|
continue;
|
2021-11-12 19:50:05 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
oMapPixelLineToIdx[std::pair<double, double>(afPL[0], afPL[1])] = iGCP;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-27 18:28:28 +01:00
|
|
|
auto oIter2 = oMapXYToIdx.find(std::pair<double, double>(afXY[0], afXY[1]));
|
|
|
|
|
if (oIter2 != oMapXYToIdx.end())
|
2021-11-12 19:50:05 +01:00
|
|
|
{
|
|
|
|
|
logger->warn("2 GCPs have the same Lat,Lon!");
|
2023-10-06 22:20:55 +02:00
|
|
|
continue;
|
2021-11-12 19:50:05 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
oMapXYToIdx[std::pair<double, double>(afXY[0], afXY[1])] = iGCP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(spline_reverse->add_point(afPL[0], afPL[1], afXY) && spline_forward->add_point(afXY[0], afXY[1], afPL)))
|
|
|
|
|
{
|
|
|
|
|
logger->error("Error generating transformer!");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Solve forward and reverse
|
|
|
|
|
logger->info("Solving TPS equations...");
|
2022-09-05 22:00:04 +02:00
|
|
|
std::thread solveFwd([this, forward]()
|
2021-11-12 19:50:05 +01:00
|
|
|
{
|
2022-09-05 22:00:04 +02:00
|
|
|
if(forward) {
|
2021-11-12 19:50:05 +01:00
|
|
|
fwd_solved = spline_forward->solve() != 0;
|
2022-09-05 22:00:04 +02:00
|
|
|
logger->info("Forward solved");} });
|
|
|
|
|
if (reverse)
|
|
|
|
|
{
|
|
|
|
|
rev_solved = spline_reverse->solve() != 0;
|
|
|
|
|
logger->info("Reverse solved");
|
|
|
|
|
}
|
2021-11-12 19:50:05 +01:00
|
|
|
if (solveFwd.joinable())
|
|
|
|
|
solveFwd.join();
|
|
|
|
|
|
|
|
|
|
if (!fwd_solved || !rev_solved)
|
|
|
|
|
{
|
|
|
|
|
logger->error("Error generating transformer!");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TPSTransform::~TPSTransform()
|
|
|
|
|
{
|
|
|
|
|
if (has_been_init)
|
|
|
|
|
{
|
|
|
|
|
delete spline_reverse;
|
|
|
|
|
delete spline_forward;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
};
|