SIMOrthoProgram-Orth_GF3-Strip/PSTM_simulation_windows2021.../PSTM_simulation_windows/ParameterInFile.cpp

2101 lines
70 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "ParameterInFile.h"
#include <iostream>
#include <fstream>
#include<string>
#include <memory>
#include <vector>
#include <malloc.h>
#include <exception>
#include <future>
#include <thread>
#include <windows.h>
////gdal
#include "gdal_priv.h"
#include "ogr_geometry.h"
#include "gdalwarper.h"
#include "common.h"
using namespace std;
//
// 参数文件解析
//
//参数文件标准格式
// 文件值 类型 对应的代号
// DEM文件的路径 str dem_path
// 模拟影像输出路径 str sar_sim_path
// 模拟影像的匹配坐标X输出路径 str sar_sim_match_point_x_path
// 模拟影像的匹配坐标Y输出路径 str sar_sim_match_point_y_path
// 模拟影像的匹配坐标Z输出路径 str sar_sim_match_point_z_path
// 采样率 long double sample_f
// 近斜距 long double R0
// 成像起始时间 long double starttime ---UTC 时间
// 光速 long double
// 波长 long double
// 多普勒参考时间 long double TO ---UTC 时间
// 脉冲重复频率 long double PRF
// 斜距采样间隔 long double delta_R
// 多普勒系数个数 int
// 多普勒系数1 long double
// 多普勒系数2 long double
// ....
// 卫星轨道模型是否为多项式模型
// 卫星轨道模型多项式次数 int 4 5
// 卫星轨道模型X值系数1 long double
// ....
// 卫星轨道模型Y值系数1 long double
// ...
// 卫星轨道模型Z值系数1 long double
// ...
// 卫星轨道模型Vx值系数1 long double
// ...
// 卫星轨道模型Vy值系数1 long double
// ...
// 卫星轨道模型Vz值系数1 long double
// ...
//
//
/// <summary>
/// 将地固参心坐标系转换为经纬度
/// </summary>
/// <param name="XYZ">固参心坐标系</param>
/// <returns>经纬度--degree</returns>
point XYZ2LLA(point& XYZ) {
long double tmpX = XYZ.x;
long double temY = XYZ.y;
long double temZ = XYZ.z;
long double curB = 0;
long double N = 0;
long double sqrtTempXY = sqrt(tmpX * tmpX + temY * temY);
long double calB = atan2(temZ, sqrtTempXY);
int counter = 0;
long double sinCurB = 0;
while (abs(curB - calB) * r2d > epsilon && counter < 25)
{
curB = calB;
sinCurB = sin(curB);
N = a / sqrt(1 - eSquare * sinCurB * sinCurB);
calB = atan2(temZ + N * eSquare * sinCurB, sqrtTempXY);
counter++;
}
point result = { 0,0,0 };
result.x = atan2(temY, tmpX) * r2d;
result.y = curB * r2d;
result.z = temZ / sinCurB - N * (1 - eSquare);
return result;
}
ParameterInFile::ParameterInFile(std::string infile_path)
{
// 解析文件
ifstream infile(infile_path, ios::in);
if (!infile.is_open()) {
throw "参数文件未打开";
}
try {
int line_ids = 0;
string buf;
getline(infile, buf); this->dem_path = buf;
getline(infile, buf); this->out_sar_sim_path = buf;
getline(infile, buf); this->out_sar_sim_dem_path = buf;
getline(infile, buf); this->out_sar_sim_resampling_path = buf;
getline(infile, buf); this->out_sar_sim_resampling_rc = buf;
getline(infile, buf); this->sim_height = stoi(buf);
getline(infile, buf); this->sim_width = stoi(buf);
getline(infile, buf); this->sar_sim_match_point_path = buf;
getline(infile, buf); this->sar_sim_match_point_xyz_path = buf;
getline(infile, buf); this->sample_f = stoi(buf);
getline(infile, buf); this->R0 = stod(buf);
getline(infile, buf); this->LightSpeed = stod(buf);
getline(infile, buf); this->lamda = stod(buf);
getline(infile, buf); this->delta_R = stod(buf);
getline(infile, buf); this->imgStartTime = stod(buf);
getline(infile, buf); this->PRF = stod(buf);
getline(infile, buf); this->delta_t = stod(buf);
getline(infile, buf); this->refrange = stod(buf);
getline(infile, buf); this->widthspace = stod(buf);
getline(infile, buf); cout << buf << endl;
getline(infile, buf); this->doppler_paramenter_number = stoi(buf);
// 读取多普勒系数
this->doppler_para = (long double*)calloc(this->doppler_paramenter_number, sizeof(long double));
if (this->doppler_para) {
for (int i = 0; i < this->doppler_paramenter_number; i++) {
getline(infile, buf);
this->doppler_para[i] = stod(buf);
}
}
else {
throw "内存不足";
}
// 读取卫星轨道
getline(infile, buf); this->polySatelliteModel = stoi(buf);
if (this->polySatelliteModel != 1) {
throw "不是多项式轨道模型";
}
getline(infile, buf); this->polynum = stoi(buf) + 1; // 多项式项数
getline(infile, buf); this->SatelliteModelStartTime = stod(buf); // 轨道模型起始时间
this->polySatellitePara = (long double*)calloc(this->polynum * 6, sizeof(long double));
if (this->polySatellitePara) {
for (int i = 0; i < this->polynum * 6; i++) {
getline(infile, buf);
this->polySatellitePara[i] = stod(buf);
}
}
else {
throw "内存不足";
}
}
catch (exception e) {
infile.close();
throw "文件读取错误";
}
infile.close();
}
ParameterInFile::ParameterInFile(const ParameterInFile& paras)
{
//参数组
this->dem_path = paras.dem_path;
this->out_sar_sim_path = paras.out_sar_sim_path;
this->out_sar_sim_dem_path = paras.out_sar_sim_dem_path;
this->out_sar_sim_resampling_path = paras.out_sar_sim_resampling_path;
this->out_sar_sim_resampling_rc = paras.out_sar_sim_resampling_rc;
this->sim_height = paras.sim_height;
this->sim_width = paras.sim_width;
this->sar_sim_match_point_path = paras.sar_sim_match_point_path;
this->sar_sim_match_point_xyz_path = paras.sar_sim_match_point_xyz_path;
this->sample_f = paras.sample_f;
this->R0 = paras.R0;
this->LightSpeed = paras.LightSpeed;
this->lamda = paras.lamda;
this->delta_R = paras.delta_R;
this->imgStartTime = paras.imgStartTime;
this->PRF = paras.PRF;
this->delta_t = paras.delta_t;
this->refrange = paras.refrange;
// 多普勒
this->widthspace = paras.widthspace;
this->doppler_paramenter_number = paras.doppler_paramenter_number;
//卫星轨道模型
this->polySatelliteModel = paras.polySatelliteModel;
this->polynum = paras.polynum;
this->SatelliteModelStartTime = paras.SatelliteModelStartTime;
this->doppler_para = (long double*)calloc(this->doppler_paramenter_number, sizeof(long double));
memcpy(this->doppler_para, paras.doppler_para, paras.doppler_paramenter_number * sizeof(long double));
this->polySatellitePara = (long double*)calloc(paras.polynum * 6, sizeof(long double));
memcpy(this->polySatellitePara, paras.polySatellitePara, paras.polynum * 6 * sizeof(long double));
}
ParameterInFile::~ParameterInFile()
{
// 析构函数
free(this->doppler_para);
free(this->polySatellitePara);
}
/// <summary>
/// 根据卫星轨道模型计算卫星
/// </summary>
/// <param name="satelliteTime">卫星轨道点时间</param>
/// <param name="SatelliteModelStartTime">卫星轨道模型起始时间</param>
/// <param name="polySatelliteParaX">卫星轨道X坐标模型参数</param>
/// <param name="polySatelliteParaY">卫星轨道Y坐标模型参数</param>
/// <param name="polySatelliteParaZ">卫星轨道Z坐标模型参数</param>
/// <param name="polySatelliteParaVx">卫星轨道Vx坐标模型参数</param>
/// <param name="polySatelliteParaVy">卫星轨道Vy坐标模型参数</param>
/// <param name="polySatelliteParaVz">卫星轨道Vz坐标模型参数</param>
/// <param name="polynum">多项式项数</param>
/// <returns></returns>
inline SatelliteSpacePoint getSatellitePostion(long double satelliteTime, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4)
{
satelliteTime = satelliteTime - SatelliteModelStartTime;
SatelliteSpacePoint result_point = { 0,0,0,0,0,0 };
if (polynum <= 0)return result_point;
int ptr_indx = 0;
int yStep = polynum;
int zStep = polynum*2;
int vxStep = polynum*3;
int vyStep = polynum*4;
int vzStep = polynum*5;
//x
result_point.x += polySatellitePara[ptr_indx];
result_point.y += polySatellitePara[ptr_indx + yStep];
result_point.z += polySatellitePara[ptr_indx + zStep];
result_point.vx += polySatellitePara[ptr_indx + vxStep];
result_point.vy += polySatellitePara[ptr_indx + vyStep];
result_point.vz += polySatellitePara[ptr_indx + vzStep];
if (polynum == 1)return result_point;
ptr_indx++;
long double powTime = satelliteTime;
result_point.x += powTime * polySatellitePara[ptr_indx];
result_point.y += powTime * polySatellitePara[ptr_indx + yStep];
result_point.z += powTime * polySatellitePara[ptr_indx + zStep];
result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep];
result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep];
result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep];
if (polynum == 2)return result_point;
ptr_indx++;
powTime *= satelliteTime;
result_point.x += powTime * polySatellitePara[ptr_indx];
result_point.y += powTime * polySatellitePara[ptr_indx + yStep];
result_point.z += powTime * polySatellitePara[ptr_indx + zStep];
result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep];
result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep];
result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep];
if (polynum == 3)return result_point;
ptr_indx++;
powTime *= satelliteTime;
result_point.x += powTime * polySatellitePara[ptr_indx];
result_point.y += powTime * polySatellitePara[ptr_indx + yStep];
result_point.z += powTime * polySatellitePara[ptr_indx + zStep];
result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep];
result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep];
result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep];
if (polynum == 4)return result_point;
ptr_indx++;
powTime *= satelliteTime;
result_point.x += powTime * polySatellitePara[ptr_indx];
result_point.y += powTime * polySatellitePara[ptr_indx + yStep];
result_point.z += powTime * polySatellitePara[ptr_indx + zStep];
result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep];
result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep];
result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep];
ptr_indx++;
if (polynum == 5)return result_point;
for (int i = 5; i < polynum; i++) {
powTime *= satelliteTime;
result_point.x += powTime * polySatellitePara[ptr_indx];
result_point.y += powTime * polySatellitePara[ptr_indx+ yStep];
result_point.z += powTime * polySatellitePara[ptr_indx + zStep];
result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep];
result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep];
result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep];
ptr_indx++;
}
return result_point;
}
inline SatelliteSpacePoint getSatellitePostion_orange(long double satelliteTime, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4)
{
satelliteTime = satelliteTime - SatelliteModelStartTime;
SatelliteSpacePoint result_point = { 0,0,0,0,0,0 };
int ptr_indx = 0;
//x
for (int i = 0; i < polynum; i++) {
result_point.x += pow(satelliteTime, i) * polySatellitePara[ptr_indx];
ptr_indx++;
}
//y
for (int i = 0; i < polynum; i++) {
result_point.y += pow(satelliteTime, i) * polySatellitePara[ptr_indx];
ptr_indx++;
}
//z
for (int i = 0; i < polynum; i++) {
result_point.z += pow(satelliteTime, i) * polySatellitePara[ptr_indx];
ptr_indx++;
}
//vx
for (int i = 0; i < polynum; i++) {
result_point.vx += pow(satelliteTime, i) * polySatellitePara[ptr_indx];
ptr_indx++;
}
//vy
for (int i = 0; i < polynum; i++) {
result_point.vy += pow(satelliteTime, i) * polySatellitePara[ptr_indx];
ptr_indx++;
}
//vz
for (int i = 0; i < polynum; i++) {
result_point.vz += pow(satelliteTime, i) * polySatellitePara[ptr_indx];
ptr_indx++;
}
return result_point;
}
/// <summary>
/// 数值模拟法计算多普勒频移值
/// 修改时间2022.07.03
/// </summary>
/// <param name="R">斜距</param>
/// <param name="LightSpeed">光速</param>
/// <param name="T0">多普勒参考时间</param>
/// <param name="doppler_para">多普勒参数</param>
/// <returns>多普勒频移值</returns>
inline long double calNumericalDopplerValue(long double R, long double LightSpeed, long double refrange, long double* doppler_para, int doppler_paramenter_number)
{
//R = R * 2 / LightSpeed - T0;
long double result = 0;
result = doppler_para[0];
R = (R - refrange) * (1000000 / LightSpeed);
for (int i = 1; i < doppler_paramenter_number; i++) {
result =result+ doppler_para[i]*pow(R,i);
}
return result;
}
/// <summary>
/// 根据理论模型计算多普勒频移值
/// </summary>
/// <param name="R">斜距</param>
/// <param name="lamda">波长</param>
/// <param name="R_sl">地面->卫星的空间向量</param>
/// <param name="V_sl">地面->卫星之间的速度向量</param>
/// <returns>多普勒频移值</returns>
inline long double calTheoryDopplerValue(long double R, long double lamda, VectorPoint R_sl, VectorPoint V_sl)
{
long double result = -2 * (R_sl.x * V_sl.x + R_sl.y * V_sl.y + R_sl.z * V_sl.z) / (lamda * R);
return result;
}
/// <summary>
/// 根据地面点求解对应的sar影像坐标
/// 修改2022.07.03
/// </summary>
/// <param name="landpoint">地面点的坐标--地固坐标系</param>
/// <param name="Starttime">影片开始成像时间</param>
/// <param name="lamda">波长</param>
/// <param name="refrange">多普勒参考斜距</param>
/// <param name="LightSpeed">光速</param>
/// <param name="delta_t">时间间隔</param>
/// <param name="R0">近斜距</param>
/// <param name="delta_R">斜距间隔</param>
/// <param name="SatelliteModelStartTime">卫星轨道模型时间</param>
/// <param name="polySatellitePara">卫星轨道坐标模型参数</param>
/// <param name="polynum">卫星轨道模型项数</param>
/// <param name="doppler_paramenter_number">多普勒模型数</param>
/// <returns>影像坐标x:行号y:列号z成像时刻</returns>
inline point PSTN(point& landpoint, long double Starttime, long double lamda, long double refrange, long double* doppler_para, long double LightSpeed, long double prf, long double R0, long double widthspace, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum, int doppler_paramenter_number)
{
long double ti = Starttime;
long double dt = 0.01;
long double R = 0;
long double FdThory1 = 0;
long double FdThory2 = 0;
long double FdNumber = 0;
long double FdTheory_grad = 0;
SatelliteSpacePoint spacepoint{ 0,0,0,0,0,0 };
VectorPoint R_sl{ 0,0,0 };
VectorPoint V_sl{ 0,0,0 };
long double int_time = 0;
long double endfactor = 1e-4;//exp((floor(log10(1/prf))-1)* 2.302585092994046);
long double error = 0;
for (int i = 0; i < 100; i++) {
spacepoint = getSatellitePostion(ti + dt, SatelliteModelStartTime, polySatellitePara, polynum);
R_sl.x = spacepoint.x - landpoint.x; // 卫星->地面坐标
R_sl.y = spacepoint.y - landpoint.y; //
R_sl.z = spacepoint.z - landpoint.z;
V_sl.x = spacepoint.vx;
V_sl.y = spacepoint.vy;
V_sl.z = spacepoint.vz;
R = getModule(R_sl);
FdThory1 = calTheoryDopplerValue(R, lamda, R_sl, V_sl);
spacepoint = getSatellitePostion(ti, SatelliteModelStartTime, polySatellitePara, polynum);
R_sl.x = spacepoint.x - landpoint.x;
R_sl.y = spacepoint.y - landpoint.y;
R_sl.z = spacepoint.z - landpoint.z;
V_sl.x = spacepoint.vx;
V_sl.y = spacepoint.vy;
V_sl.z = spacepoint.vz;
R = getModule(R_sl);
FdThory2 = calTheoryDopplerValue(R, lamda, R_sl, V_sl);
FdNumber = calNumericalDopplerValue(R, LightSpeed, refrange, doppler_para, doppler_paramenter_number);
FdTheory_grad = (FdThory1 - FdThory2);
error = FdNumber - FdThory2;
int_time = error * dt / FdTheory_grad;
if (abs(error) < endfactor) {
ti = ti + int_time;
break;
}
ti = ti + int_time;
}
point result{ 0,0,0 };
result.x = (ti - Starttime) * prf;
result.y = (R - R0) / widthspace;
result.z = ti;
return result;
}
/// <summary>
/// 双线性插值
/// 11 12
/// c
/// 21 22
/// </summary>
/// <param name="p">c的x,y坐标以左上角的行列号为起始点</param>
/// <param name="p11"> </param>
/// <param name="p12"></param>
/// <param name="p21"></param>
/// <param name="p22"></param>
/// <returns></returns>
inline point bilineadInterpolation(point& p, point& p11, point& p12, point& p21, point& p22)
{
long double r = 1 - p.x;
long double c = 1 - p.y;
long double rc = r * c;
long double r_c_1 = r * p.y;// r* (1 - c);
long double r_1_c = p.x * c; //(1 - r) * c;
long double r_1_c_1 = p.x * p.y;// (1 - r)* (1 - c);
// 计算插值结果
p.x = rc * p11.x + r_c_1 * p12.x + r_1_c * p21.x + r_1_c_1 * p22.x;
p.y = rc * p11.y + r_c_1 * p12.y + r_1_c * p21.y + r_1_c_1 * p22.y;
p.z = rc * p11.z + r_c_1 * p12.z + r_1_c * p21.z + r_1_c_1 * p22.z;
return p;
}
/// <summary>
/// 三次卷积插值
/// 11 12 13 14
/// 21 22 23 24
/// c
/// 31 32 33 34
/// 41 42 43 44
/// </summary>
/// <param name="p"></param>
/// <param name="p11"></param>
/// <param name="p12"></param>
/// <param name="p13"></param>
/// <param name="p14"></param>
/// <param name="p21"></param>
/// <param name="p22"></param>
/// <param name="p23"></param>
/// <param name="p24"></param>
/// <param name="p31"></param>
/// <param name="p32"></param>
/// <param name="p33"></param>
/// <param name="p34"></param>
/// <param name="p41"></param>
/// <param name="p42"></param>
/// <param name="p43"></param>
/// <param name="p44"></param>
/// <returns></returns>
inline point cubicInterpolation(point& p, point& p11, point& p12, point& p13, point& p14, point& p21, point& p22, point& p23, point& p24, point& p31, point& p32, point& p33, point& p34, point& p41, point& p42, point& p43, point& p44)
{
long double r = p.x;
long double c = p.y;
long double r1 = r, r2 = r - 1, r3 = 2 - r, r4 = 3 - r;
long double c1 = c, c2 = c - 1, c3 = 2 - c, c4 = 3 - c;
long double wr1 = 4 - 8 * r1 + 5 * r1 * r1 - r1 * r1 * r1;
long double wr2 = 1 - 2 * r2 * r2 + r2 * r2 * r2;
long double wr3 = 1 - 2 * r3 * r3 + r3 * r3 * r3;
long double wr4 = 4 - 8 * r4 + 5 * r4 * r4 - r4 * r4 * r4;
long double wc1 = 4 - 8 * c1 + 5 * c1 * c1 - c1 * c1 * c1;
long double wc2 = 1 - 2 * c2 * c2 + c2 * c2 * c2;
long double wc3 = 1 - 2 * c3 * c3 + c3 * c3 * c3;
long double wc4 = 4 - 8 * c4 + 5 * c4 * c4 - c4 * c4 * c4;
long double wr1_wc1 = wr1 * wc1;
long double wr2_wc1 = wr2 * wc1;
long double wr3_wc1 = wr3 * wc1;
long double wr4_wc1 = wr4 * wc1;
long double wr1_wc2 = wr1 * wc2;
long double wr2_wc2 = wr2 * wc2;
long double wr3_wc2 = wr3 * wc2;
long double wr4_wc2 = wr4 * wc2;
long double wr1_wc3 = wr1 * wc3;
long double wr2_wc3 = wr2 * wc3;
long double wr3_wc3 = wr3 * wc3;
long double wr4_wc3 = wr4 * wc3;
long double wr1_wc4 = wr1 * wc4;
long double wr2_wc4 = wr2 * wc4;
long double wr3_wc4 = wr3 * wc4;
long double wr4_wc4 = wr4 * wc4;
p.x = 0;
p.x = p.x + wr1_wc1 * p11.x + wr1_wc2 * p12.x + wr1_wc3 * p13.x + wr1_wc4 * p14.x;
p.x = p.x + wr2_wc1 * p11.x + wr2_wc2 * p12.x + wr2_wc3 * p13.x + wr2_wc4 * p14.x;
p.x = p.x + wr3_wc1 * p11.x + wr3_wc2 * p12.x + wr3_wc3 * p13.x + wr3_wc4 * p14.x;
p.x = p.x + wr4_wc1 * p11.x + wr4_wc2 * p12.x + wr4_wc3 * p13.x + wr4_wc4 * p14.x;
p.y = 0;
p.y = p.y + wr1_wc1 * p11.y + wr1_wc2 * p12.y + wr1_wc3 * p13.y + wr1_wc4 * p14.y;
p.y = p.y + wr2_wc1 * p11.y + wr2_wc2 * p12.y + wr2_wc3 * p13.y + wr2_wc4 * p14.y;
p.y = p.y + wr3_wc1 * p11.y + wr3_wc2 * p12.y + wr3_wc3 * p13.y + wr3_wc4 * p14.y;
p.y = p.y + wr4_wc1 * p11.y + wr4_wc2 * p12.y + wr4_wc3 * p13.y + wr4_wc4 * p14.y;
p.z = 0;
p.z = p.z + wr1_wc1 * p11.z + wr1_wc2 * p12.z + wr1_wc3 * p13.z + wr1_wc4 * p14.z;
p.z = p.z + wr2_wc1 * p11.z + wr2_wc2 * p12.z + wr2_wc3 * p13.z + wr2_wc4 * p14.z;
p.z = p.z + wr3_wc1 * p11.z + wr3_wc2 * p12.z + wr3_wc3 * p13.z + wr3_wc4 * p14.z;
p.z = p.z + wr4_wc1 * p11.z + wr4_wc2 * p12.z + wr4_wc3 * p13.z + wr4_wc4 * p14.z;
return p;
}
//
// GDAL 数组操作---内置函数不进入头文件声明
//
float* ReadRasterArray(GDALRasterBand* demBand, int arrayWidth, int arrayHeight, GDALDataType gdal_datatype) {
float* result = new float[arrayWidth * arrayHeight]; // 别忘了释放内存
if (gdal_datatype == GDALDataType::GDT_UInt16) {
unsigned short* temp = (unsigned short*)calloc(arrayHeight * arrayWidth, sizeof(unsigned short));
demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0);
for (int i = 0; i < arrayHeight * arrayWidth; i++) {
result[i] = temp[i] * 1.0;
}
free(temp);
}
else if (gdal_datatype == GDALDataType::GDT_Int16) {
short* temp = (short*)calloc(arrayHeight * arrayWidth, sizeof(short));
demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0);
for (int i = 0; i < arrayHeight * arrayWidth; i++) {
result[i] = temp[i] * 1.0;
}
free(temp);
}
else if (gdal_datatype == GDALDataType::GDT_Float32) {
float* temp = (float*)calloc(arrayHeight * arrayWidth, sizeof(float));
demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0);
for (int i = 0; i < arrayHeight * arrayWidth; i++) {
result[i] = temp[i] * 1.0;
}
free(temp);
}
return result;
}
int WriteMatchPoint(string path, std::vector<matchPoint>* matchps) {
std::cout << "输出匹配文件中:" << path;
fstream f;
//追加写入,在原来基础上加了ios::app
f.open(path, ios::out | ios::app);
for (int i = 0; i < matchps->size(); i++) {
matchPoint matchP = (*matchps)[i];
//f << matchP.r << "," << matchP.c << "," << matchP.ti << "," << matchP.x << "," << matchP.y << "," << matchP.z << "\n";
}
f.close();
std::cout << "输出匹配文件over:" << path;
return 0;
}
sim_block::sim_block(int start_row, int end_row, int start_col, int end_col, int height, int width)
{
this->start_row = start_row;
this->end_row = end_row;
this->start_col = start_col;
this->end_col = end_col;
this->height = height;
this->width = width;
this->size = height * width;
this->block = (short*)calloc(this->size, sizeof(short));
this->distanceblock = (long double*)calloc(this->size, sizeof(long double));
this->pointblock = (matchPoint*)calloc(this->size, sizeof(matchPoint));
for (int i = 0; i < this->size; i++) {
this->distanceblock[i] = -1;
}
}
/// <summary>
/// 深度拷贝
/// </summary>
/// <param name="sim_blocks"></param>
sim_block::sim_block(const sim_block& sim_blocks)
{
this->height = sim_blocks.width;
this->width = sim_blocks.height;
this->start_row = sim_blocks.start_row;
this->start_col = sim_blocks.start_col;
this->end_col = sim_blocks.end_col;
this->end_row = sim_blocks.end_row;
this->size = sim_blocks.size;
// 声明块
this->block = (short*)calloc(this->size, sizeof(short));
this->distanceblock = (long double*)calloc(this->size, sizeof(long double));
this->pointblock = (matchPoint*)calloc(this->size, sizeof(matchPoint));
// 移动并复制块
memcpy(this->block, sim_blocks.block, this->size * sizeof(short));
memcpy(this->distanceblock, sim_blocks.distanceblock, this->size * sizeof(long double));
memcpy(this->pointblock, sim_blocks.pointblock, this->size * sizeof(matchPoint));
}
sim_block::~sim_block()
{
if (this->block) {
free(this->block);
this->block = NULL;
}
if (this->distanceblock) {
free(this->distanceblock);
this->distanceblock = NULL;
}
if (this->pointblock) {
free(this->pointblock);
this->pointblock = NULL;
}
}
int sim_block::rowcol2blockids(int row_ids, int col_ids)
{
if (this->start_row > row_ids && this->end_row <= row_ids && this->start_col > col_ids && this->end_col <= col_ids) {
return -1;
}
int ids = (row_ids - this->start_row) * this->width + col_ids - this->start_col;
return ids;
}
/// <summary>
/// 根据行列号设置指定块的数值
/// </summary>
/// <param name="row_ids">行号</param>
/// <param name="col_ids">列号</param>
/// <param name="value">设置的值</param>
/// <returns></returns>
int sim_block::setsimblock(int row_ids, int col_ids, short value)
{
int ids = this->rowcol2blockids(row_ids, col_ids);
if (ids < 0) {
return -1;
}
this->block[ids] = value;
/*
try {
this->block[ids] = value;
}
catch (exception e) {
throw "Error";
return -1;
}
*/
return 0;
}
int sim_block::addsimblock(int row_ids, int col_ids, short value)
{
int ids = this->rowcol2blockids(row_ids, col_ids);
if (ids < 0) {
return -1;
}
this->block[ids] += value;
/*
try {
this->block[ids] += value;
}
catch (exception e) {
throw "Error";
return -1;
}
*/
return 0;
}
/// <summary>
/// 根据行列号,获取指定行列号块的数值
/// </summary>
/// <param name="row_ids">行号</param>
/// <param name="col_ids">列号</param>
/// <returns></returns>
short sim_block::getsimblock(int row_ids, int col_ids)
{
int ids = this->rowcol2blockids(row_ids, col_ids);
if (ids < 0) {
return -1;
}
short result;
result = this->block[ids];
/*
try {
result = this->block[ids];
}
catch (exception e) {
throw "Error";
return -1;
}
*/
return result;
}
/// <summary>
/// 获取模拟坐标对应的点坐标
/// </summary>
/// <param name="row_ids">行号</param>
/// <param name="col_ids">列号</param>
/// <returns></returns>
matchPoint sim_block::getpointblock(int row_ids, int col_ids)
{
int ids = this->rowcol2blockids(row_ids, col_ids);
if (ids < 0) {
throw "坐标错误";
return matchPoint{ 0,0,0,0,0,0 };
}
matchPoint result = this->pointblock[ids];
return result;
}
/// <summary>
/// 设置模拟块对应的点坐标
/// </summary>
/// <param name="row_ids">行号</param>
/// <param name="col_ids">列号</param>
/// <param name="value">坐标点</param>
/// <returns>更新结果</returns>
int sim_block::setpointblock(int row_ids, int col_ids, matchPoint value)
{
int ids = this->rowcol2blockids(row_ids, col_ids);
if (ids < 0) { return -1; }
this->pointblock[ids] = value;
return 0;
}
long double sim_block::getdistanceblock(int row_ids, int col_ids)
{
int ids = this->rowcol2blockids(row_ids, col_ids);
if (ids < 0) {
return -1;
}
long double result;
result = this->distanceblock[ids];
/*
try {
result = this->distanceblock[ids];
}
catch (exception e) {
throw "Error";
return -1;
}
*/
return result;
}
int sim_block::setdistanceblock(int row_ids, int col_ids, long double value)
{
int ids = this->rowcol2blockids(row_ids, col_ids);
if (ids < 0) {
return -1;
}
this->distanceblock[ids] = value;
/*
try {
this->distanceblock[ids] = value;
}
catch (exception e) {
throw "Error";
return -1;
}
*/
return 0;
}
/// <summary>
/// 初始化dem_block
/// </summary>
/// <param name="start_row"></param>
/// <param name="end_row"></param>
/// <param name="start_col"></param>
/// <param name="end_col"></param>
/// <param name="height"></param>
/// <param name="width"></param>
/// <param name="sample_f"></param>
dem_block::dem_block(int all_start_row, int all_start_col, int start_row, int end_row, int start_col, int end_col, int height, int width, int sample_f)
{
this->all_start_row = all_start_row;
this->all_start_col = all_start_col;
this->start_row = start_row;
this->end_row = end_row;
this->start_col = start_col;
this->end_col = end_col;
this->height = height;
this->width = width;
this->size = height * width;
this->pointblock = (point*)calloc(this->size, sizeof(point));
this->sample_f = sample_f;
}
dem_block::dem_block(const dem_block& demblocks)
{
this->all_start_row = demblocks.all_start_row;
this->all_start_col = demblocks.all_start_col;
this->start_row = demblocks.start_row;
this->end_row = demblocks.end_row;
this->start_col = demblocks.start_col;
this->end_col = demblocks.end_col;
this->height = demblocks.height;
this->width = demblocks.width;
this->size = this->height * this->width;
this->pointblock = (point*)calloc(this->size, sizeof(point));
this->sample_f = sample_f;
memcpy(this->pointblock, demblocks.pointblock, this->size * sizeof(point));
}
dem_block::~dem_block()
{
if (this->pointblock) {
free(this->pointblock);
this->pointblock = NULL;
//delete this;
}
}
/// <summary>
/// 重采样dem--三次卷积插值-- 必须在地理坐标系下进行(经纬度)
/// 为了保证采样左右各舍弃了1格
/// </summary>
/// <returns></returns>
//dem_block dem_block::resample_dem()
//{
// int height = this->height -2;//[1,2 ....., n-1,n]
// int width = this->width -2;//[1,2 ....., n-1,n]
// height = height * this->sample_f; //重采样之后的高度
// width = width * this->sample_f; // 重采样之后的宽度
//
// int start_row = (this->start_row-1) * this ->sample_f;
// int start_col = (this->start_col-1) * this->sample_f;
// int end_row = (this->end_row-1) * this->sample_f;
// int end_col = (this->end_col-1) * this->sample_f;
// dem_block resample_dem = dem_block(start_row, end_row, start_col, end_col, height, width, this->sample_f);
//
// // 执行dem重采样采用双曲线插值
// for (int i = sample_f; i < height; i++) { // 行 从第一行
// int ori_i_2 = i / sample_f;
// int ori_i_1, ori_i_3, ori_i_4;
// if (ori_i_2 - 1 < 0) { continue; }
// ori_i_1 = ori_i_2 - 1;
// if (ori_i_2 + 1 > this->height || ori_i_2 + 2 > this->height) { break; }
// ori_i_3 = ori_i_2 + 1;
// ori_i_4 = ori_i_2 + 2;
// for (int j = sample_f; j < width; j++) { //列 从第一列
// point p{0,0,0};
// int ori_j_2 = j / sample_f;
// int ori_j_1, ori_j_3, ori_j_4;
// if (ori_i_2 - 1 < 0) { continue; }
// ori_j_1 = ori_j_2 - 1;
// if (ori_j_2 + 1 > this->height || ori_j_2 + 2 > this->height) { break; }
// ori_j_3 = ori_j_2 + 1;
// ori_j_4 = ori_j_2 + 2;
// // 获取插值需要的数据--三次重采样差值
// p.x = (i % sample_f) * 1.0 / sample_f; p.x = p.x + 1;
// p.y = (j % sample_f) * 1.0 / sample_f; p.y = p.y + 1;
// point p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44;
// // 获取对应节点
// p11 = this->getpointblock(ori_i_1, ori_j_1);
// p12 = this->getpointblock(ori_i_1, ori_j_2);
// p13 = this->getpointblock(ori_i_1, ori_j_3);
// p14 = this->getpointblock(ori_i_1, ori_j_4);
// p21 = this->getpointblock(ori_i_2, ori_j_1);
// p22 = this->getpointblock(ori_i_2, ori_j_2);
// p23 = this->getpointblock(ori_i_2, ori_j_3);
// p24 = this->getpointblock(ori_i_2, ori_j_4);
// p31 = this->getpointblock(ori_i_3, ori_j_1);
// p32 = this->getpointblock(ori_i_3, ori_j_2);
// p33 = this->getpointblock(ori_i_3, ori_j_3);
// p34 = this->getpointblock(ori_i_3, ori_j_4);
// p41 = this->getpointblock(ori_i_4, ori_j_1);
// p42 = this->getpointblock(ori_i_4, ori_j_2);
// p43 = this->getpointblock(ori_i_4, ori_j_3);
// p44 = this->getpointblock(ori_i_4, ori_j_4);
// p = cubicInterpolation(p, p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44);
// // 计算p 对应的行列号
// resample_dem.setpointblock(i - sample_f, j - sample_f, p);
// }
// }
//
//
// return resample_dem;
//}
/* -------需要优化的方法--------*/
dem_block dem_block::resample_dem() {
int height = this->height - 2;//[1,2 ....., n-1,n]
int width = this->width - 2;//[1,2 ....., n-1,n]
height = height * this->sample_f; //重采样之后的高度
width = width * this->sample_f; // 重采样之后的宽度
int start_row = (this->start_row - 1) * this->sample_f;
int start_col = (this->start_col - 1) * this->sample_f;
int end_row = (this->end_row - 1) * this->sample_f;
int end_col = (this->end_col - 1) * this->sample_f;
dem_block resample_dem = dem_block(all_start_row,all_start_col,start_row, end_row, start_col, end_col, height, width, this->sample_f);
long double sample_f_1 = 1.0 / sample_f;
// 执行dem重采样采用双曲线插值
int ori_i_2 =0;
int ori_i_1, ori_i_3, ori_i_4;
point p{ 0,0,0 };
point p11, p12, p13, p14;
for (int i = sample_f; i < height; i++) { // 行 从第一行
ori_i_2 = i * sample_f_1;
if (ori_i_2 - 1 < 0) { continue; }
ori_i_1 = ori_i_2 - 1;
if (ori_i_2 + 1 > this->height || ori_i_2 + 2 > this->height) { break; }
ori_i_3 = ori_i_2 + 1;
ori_i_4 = ori_i_2 + 2;
for (int j = sample_f; j < width; j++) { //列 从第一列
p={ 0,0,0 };
int ori_j_2 = j * sample_f_1;
int ori_j_1, ori_j_3, ori_j_4;
if (ori_i_2 - 1 < 0) { continue; }
ori_j_1 = ori_j_2 - 1;
if (ori_j_2 + 1 > this->height || ori_j_2 + 2 > this->height) { break; }
ori_j_3 = ori_j_2 + 1;
ori_j_4 = ori_j_2 + 2;
// 获取插值需要的数据--三次重采样差值
p.x = (i % sample_f) * sample_f_1 + 1;
//p.x = p.x + 1;
p.y = (j % sample_f) * sample_f_1 + 1;
//p.y = p.y + 1;
// 获取对应节点
p11 = this->getpointblock(ori_i_2, ori_j_2);
p12 = this->getpointblock(ori_i_2, ori_j_3);
p13 = this->getpointblock(ori_i_3, ori_j_2);
p14 = this->getpointblock(ori_i_3, ori_j_3);
p = bilineadInterpolation(p, p11, p12, p13, p14); // ----- 优化
// 计算p 对应的行列号
resample_dem.setpointblock(i - sample_f, j - sample_f, p);
}
}
return resample_dem;
}
/// <summary>
/// 根据重采样结果获取对应行列号的坡面法式向量(
/// 必须提前调用UpdatePointCoodinarary()方法,保证坐标系为地固坐标系
/// </summary>
/// <param name="row_ids">行号</param>
/// <param name="col_ids">列号</param>
/// <returns></returns>
VectorPoint dem_block::getslopeVector(int row_ids, int col_ids)
{
if (row_ids == 0 || col_ids == 0 || row_ids > this->height - 1 || col_ids > this->width - 1) { return VectorPoint{ 0,0,0 }; } // 无效值
VectorPoint result{ 0,0,0 };
// 计算向量值,注意向量值的计算初值结果
point p1 = this->getpointblock(row_ids - 1, col_ids);
point p2 = this->getpointblock(row_ids, col_ids - 1);
point p3 = this->getpointblock(row_ids + 1, col_ids);
point p4 = this->getpointblock(row_ids, col_ids + 1);
VectorPoint n24 = getVector(p2, p4);
VectorPoint n31 = getVector(p3, p1);
result = VectorFork(n24, n31); // 目标向量
return result;
}
int dem_block::rowcol2blockids(int row_ids, int col_ids)
{
return row_ids * this->width + col_ids;
}
/// <summary>
/// 根据行列号获取对应的点
/// </summary>
/// <param name="row_ids"></param>
/// <param name="col_ids"></param>
/// <returns></returns>
point dem_block::getpointblock(int row_ids, int col_ids)
{
int ids = this->rowcol2blockids(row_ids, col_ids);
//try {
return this->pointblock[ids];
//}
//catch (exception e) {
//throw "error";
//return point{ -1,-1,-1 };
//}
}
/// <summary>
/// 根据行列号更新值
/// </summary>
/// <param name="row_ids"></param>
/// <param name="col_ids"></param>
/// <param name="value"></param>
/// <returns></returns>
int dem_block::setpointblock(int row_ids, int col_ids, point& value)
{
this->pointblock[row_ids * this->width + col_ids]= value;
/*
int ids = this->rowcol2blockids(row_ids, col_ids);
try {
this->pointblock[ids] = value;
}
catch (exception ex) {
throw "error";
return -1;
}
*/
return 0;
}
point dem_block::getpointblock(int ids)
{
return this->pointblock[ids];
/*try {
point result = this->pointblock[ids];
return result;
}
catch (exception e) {
throw "error";
return point{ -1,-1,-1 };
}*/
}
int dem_block::setpointblock(int ids, point& value)
{
this->pointblock[ids] = value;
/*
try {
this->pointblock[ids] = value;
}
catch (exception ex) {
throw "error";
return -1;
}
*/
return 0;
}
/// <summary>
/// 将点坐标由经纬度->地固坐标系
/// </summary>
/// <param name="gt"></param>
/// <returns></returns>
int dem_block::UpdatePointCoodinarary()
{
for (int i = 0; i < this->size; i++) {
this->pointblock[i] = LLA2XYZ(this->pointblock[i]);
}
return 0;
}
ConvertResampleParameter::ConvertResampleParameter(string path)
{
// 解析文件
ifstream infile(path, ios::in);
if (!infile.is_open()) {
throw "参数文件未打开";
}
try {
int line_ids = 0;
string buf;
getline(infile, buf); this->in_ori_dem_path = buf;
getline(infile, buf); this->ori_sim = buf;
getline(infile, buf); this->out_sar_xyz_path = buf;
getline(infile, buf); this->out_sar_xyz_incidence_path = buf;
getline(infile, buf); this->out_orth_sar_incidence_path = buf;
getline(infile, buf); this->out_orth_sar_local_incidence_path = buf;
getline(infile, buf); this->outFolder_path = buf;
getline(infile, buf); this->file_count = stoi(buf);
this->inputFile_paths = std::vector<string>(this->file_count);
this->outFile_paths = std::vector<string>(this->file_count);
this->outFile_pow_paths = std::vector<string>(this->file_count);
for (int i = 0; i < this->file_count; i++) {
getline(infile, buf); this->inputFile_paths[i] = buf;
getline(infile, buf); this->outFile_paths[i] = buf;
getline(infile, buf); this->outFile_pow_paths[i] = buf;
}
getline(infile, buf); this->ori2sim_num = stoi(buf);
this->ori2sim_paras = (long double*)calloc(this->ori2sim_num, sizeof(long double));
for (int i = 0; i < this->ori2sim_num; i++) {
getline(infile, buf);
this->ori2sim_paras[i] = stod(buf);
}
getline(infile, buf); this->sim2ori_num = stoi(buf);
this->sim2ori_paras = (long double*)calloc(this->sim2ori_num, sizeof(long double));
for (int i = 0; i < this->sim2ori_num; i++) {
getline(infile, buf);
this->sim2ori_paras[i] = stod(buf);
}
}
catch (exception e) {
infile.close();
throw "文件读取错误";
}
infile.close();
}
ConvertResampleParameter::ConvertResampleParameter(const ConvertResampleParameter& para)
{
this->in_ori_dem_path = para.in_ori_dem_path;
this->ori_sim = para.ori_sim;
this->out_sar_xyz_path = para.out_sar_xyz_path;
this->out_sar_xyz_incidence_path = para.out_sar_xyz_incidence_path;
this->out_orth_sar_incidence_path = para.out_orth_sar_incidence_path;
this->out_orth_sar_local_incidence_path = para.out_orth_sar_local_incidence_path;
this->outFolder_path = para.outFolder_path;
this->file_count = para.file_count;
this->inputFile_paths = std::vector<string>(this->file_count);
this->outFile_paths = std::vector<string>(this->file_count);
this->outFile_pow_paths = std::vector<string>(this->file_count);
for (int i = 0; i < this->file_count; i++) {
this->inputFile_paths[i] = para.inputFile_paths[i];
this->outFile_paths[i] = para.outFile_paths[i];
this->outFile_pow_paths[i] = para.outFile_pow_paths[i];
}
this->ori2sim_num = para.ori2sim_num;
this->ori2sim_paras = (long double*)calloc(this->ori2sim_num, sizeof(long double));
memcpy(this->ori2sim_paras, para.ori2sim_paras, this->ori2sim_num * sizeof(long double));
this->sim2ori_num = para.sim2ori_num;
this->sim2ori_paras = (long double*)calloc(this->sim2ori_num, sizeof(long double));
memcpy(this->sim2ori_paras, para.sim2ori_paras, this->sim2ori_num * sizeof(long double));
}
ConvertResampleParameter::~ConvertResampleParameter()
{
free(this->sim2ori_paras);
free(this->ori2sim_paras);
this->outFile_paths.clear();
this->outFile_paths.swap(this->outFile_paths);
this->inputFile_paths.clear();
this->inputFile_paths.swap(this->inputFile_paths);
this->outFile_pow_paths.clear();
this->outFile_pow_paths.swap(this->outFile_pow_paths);
}
#include "threadpool.hpp"
//int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount)
// 插值算法
/// <summary>
/// 分块模拟求解
/// T0 变更为 refrange, delta_R: widthspace
/// </summary>
/// <param name="paras"></param>
/// <param name="demblock"></param>
/// <returns></returns>
int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount)
{
long double Starttime = paras.imgStartTime;
long double lamda = paras.lamda;
long double refrange = paras.refrange;
long double* doppler_para = paras.doppler_para;
long double LightSpeed = paras.LightSpeed;
long double delta_t = paras.delta_t;
long double prf = paras.PRF;
long double R0 = paras.R0;
long double widthspace = paras.widthspace;
long double SatelliteModelStartTime = paras.SatelliteModelStartTime;
long double* polySatellitePara = paras.polySatellitePara;
int sim_sar_width = paras.sim_width;
int sim_sar_height = paras.sim_height;
int polynum = paras.polynum;
int doppler_paramenter_number = paras.doppler_paramenter_number;
bool haspoint = true;
for (int i = 0; i < demblock.size; i++) {
point tempPoint = demblock.getpointblock(i);
tempPoint = LLA2XYZ(tempPoint);
// T0 变更为 refrange, delta_R: widthspace
point pixelpoint = PSTN(tempPoint, Starttime, lamda, refrange, doppler_para, LightSpeed, prf, R0, widthspace, SatelliteModelStartTime, polySatellitePara, polynum, doppler_paramenter_number);
if (pixelpoint.x >= -3000-paras.sample_f*5 && pixelpoint.x < paras.sim_height + paras.sample_f * 5 && pixelpoint.y >= -paras.sample_f * 5 && pixelpoint.y < paras.sim_width + paras.sample_f * 5) {
haspoint = false;
break;
}
}
if (haspoint) {
*Pcount = -1;
return -1;
}
// dem重采样
demblock.sample_f = paras.sample_f;
dem_block resample = demblock.resample_dem(); // 重采样的时候经纬度,
resample.UpdatePointCoodinarary(); // 可以优化
//声明
int sim_height = resample.end_row - resample.start_row;
int sim_width = resample.end_col - resample.start_col;
int sim_pixel_count = sim_width * sim_height;
// 计算对应的行列号
int ids = 0;
SatelliteSpacePoint satepoint_;
*Pcount = 0;
try {
// 计算间接定位法结果
for (int i = resample.start_row; i < resample.end_row; i++) {
for (int j = resample.start_col; j < resample.end_col; j++) {
point landPoint = resample.getpointblock(i, j);
point pixelpoint = PSTN(landPoint, Starttime, lamda, refrange, doppler_para, LightSpeed, prf, R0, widthspace, SatelliteModelStartTime, polySatellitePara, polynum, doppler_paramenter_number);
point temppoint{ round(pixelpoint.x),round(pixelpoint.y),pixelpoint.z };
if (temppoint.x < -3000 || temppoint.x >= paras.sim_height || temppoint.y < 0 || temppoint.y >= paras.sim_width) {
continue;
}
VectorPoint n = resample.getslopeVector(i, j);
satepoint_ = getSatellitePostion(pixelpoint.z, SatelliteModelStartTime, polySatellitePara, polynum);
point satepoint{ satepoint_.x,satepoint_.y,satepoint_.z };//卫星坐标
IncidenceAngle pixelIncidence = calIncidence(satepoint, landPoint, n);
if (pixelIncidence.localincidenceAngle >= 0 && pixelIncidence.localincidenceAngle <= 1)
{
matchPoint matchp{ temppoint.x, temppoint.y, pixelpoint.z,0,0,0,0,pixelIncidence.incidenceAngle,pixelIncidence.localincidenceAngle};
result_shared[ids] = matchp;
*Pcount = *Pcount + 1;
ids = ids + 1;
}
}
}
return 0;
}
catch (exception e) {
//free(pixelpoints);
throw "计算错误";
return -1;
}
}
static std::mutex s_sim_dem_Mutex; //数据锁
void taskFunc(ParameterInFile& paras, int dem_block_size, int width, short* sim_dem, int count_cure, int count_sum,
int i, int j, int block_height, int block_width, int end_row_ex, int end_col_ex, float* demarray, translateArray& gtt, translateArray& inv_gtt)
{
//dem_block *demblock,
int Pcount = 0;
dem_block* demblock = new dem_block(i - 3, j - 3, 3, block_height - 3, 3, block_width - 3, block_height, block_width, paras.sample_f);// 构建块结构
for (int ii = i - 3; ii < end_row_ex; ii++) {
for (int jj = j - 3; jj < end_col_ex; jj++) {
// 构建点集
int dem_ids = ii * width + jj;
point tempPoint = Translation(ii, jj, demarray[dem_ids], gtt);
demblock->setpointblock(ii - i + 3, jj - j + 3, tempPoint);
}
}
matchPoint* result_shared = (matchPoint*)calloc((dem_block_size + 7) * (dem_block_size + 7) * paras.sample_f * paras.sample_f, sizeof(matchPoint));
int nRet= SimProcessBlock(*demblock, paras,result_shared, &Pcount);
int tempstate = Pcount;
int row_ids = 0;
int col_ids = 0;
int ids = 0;
matchPoint* pixelpoint = NULL;
{
//std::lock_guard<std::mutex> guard(s_sim_dem_Mutex);
s_sim_dem_Mutex.lock();
for (int ii = 0; ii < tempstate; ii++) {
pixelpoint = &result_shared[ii];
row_ids = int(pixelpoint->r)+3000;
col_ids = int(pixelpoint->c);
ids = row_ids *paras.sim_width + col_ids;
sim_dem[ids] ++;
}
s_sim_dem_Mutex.unlock();
}
//根据匹配结果,尝试计算插值结果
delete demblock;
free(result_shared);
}
void taskFunc_Calsim2ori(ParameterInFile& paras, ConvertResampleParameter& conveparas,
int start_row, int end_row, int start_col, int end_col,
int dem_width,int dem_height,
float* sar_local_angle, float* sar_angle, float* sar_dem_x, float* sar_dem_y,
float* demarray, translateArray& gtt, translateArray& inv_gtt)
{
/*
// 计算向量值,注意向量值的计算初值结果
point p1 = this->getpointblock(row_ids - 1, col_ids);
point p2 = this->getpointblock(row_ids, col_ids - 1);
point p3 = this->getpointblock(row_ids + 1, col_ids);
point p4 = this->getpointblock(row_ids, col_ids + 1);
VectorPoint n24 = getVector(p2, p4);
VectorPoint n31 = getVector(p3, p1);
result = // 目标向量
*/
double templocalincidenceAngle = 0;
double tempincidenceAngle = 0;
double templocalincidenceAngle1 = 0;
double tempincidenceAngle1 = 0;
for (int i = start_row; i <= end_row; i++) {
if (i - 1 < 0 || i + 1 >= dem_height) {
continue;
}
for (int j = start_col; j <= end_col; j++) {
if (j - 1 < 0 || j + 1 >= dem_width) {
continue;
}
int dem_ids = i * dem_width + j;
point landPoint = Translation(i, j, demarray[dem_ids], gtt);
landPoint =LLA2XYZ(landPoint);
point pixelpoint = PSTN(landPoint, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number);
long double r, c; // 结果的行列号
sim2ori(pixelpoint.x, pixelpoint.y, r, c, conveparas.sim2ori_paras); // 计算得到的行列号 -->
// 计算向量1
dem_ids = (i - 1) * dem_width + j; point p1 = Translation(i - 1, j, demarray[dem_ids], gtt); p1 = LLA2XYZ(p1);
dem_ids = i * dem_width + (j - 1); point p2 = Translation(i, j - 1, demarray[dem_ids], gtt); p2 = LLA2XYZ(p2);
dem_ids = (i + 1) * dem_width + j; point p3 = Translation(i + 1, j, demarray[dem_ids], gtt); p3 = LLA2XYZ(p3);
dem_ids = i * dem_width + (j + 1); point p4 = Translation(i, j + 1, demarray[dem_ids], gtt); p4 = LLA2XYZ(p4);
VectorPoint n24 = getVector(p2, p4);
VectorPoint n31 = getVector(p3, p1);
VectorPoint n = VectorFork(n24, n31);
long double satelliteTime =r / paras.PRF + paras.imgStartTime;// pixelpoint.z;//
SatelliteSpacePoint satepoint_ = getSatellitePostion(satelliteTime, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum);
point satepoint{ satepoint_.x,satepoint_.y,satepoint_.z };//卫星坐标
IncidenceAngle pixelIncidence = calIncidence(satepoint, landPoint, n);
dem_ids = i * dem_width + j;
sar_local_angle[dem_ids] = acos(pixelIncidence.localincidenceAngle) * r2d;
sar_angle[dem_ids] =90- acos(pixelIncidence.incidenceAngle) * r2d;
sar_dem_x[dem_ids] = r;
sar_dem_y[dem_ids] = c;
}
}
//std::cout << "\r" << end_row << "/" << dem_height << "," << end_col << "/" << dem_width << "," << end_row*100.0 * end_col / (dem_width * dem_height) << " ------------------";
}
int SimProcess_LVY(ParameterInFile paras, int thread_num)
{
std::cout << "begin time:" << getCurrentTimeString() << std::endl;
GDALAllRegister();// 注册格式的驱动
// 打开DEM影像
GDALDataset* demDataset = (GDALDataset*)(GDALOpen(paras.dem_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像
int width = demDataset->GetRasterXSize();
int height = demDataset->GetRasterYSize();
int nCount = demDataset->GetRasterCount();
double* gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵
demDataset->GetGeoTransform(gt); // 获得仿射矩阵
translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] };
double* inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵
GDALInvGeoTransform(gt, inv_gt); // 逆矩阵
translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] };
GDALDataType gdal_datatype = demDataset->GetRasterBand(1)->GetRasterDataType();
const char* Projection = demDataset->GetProjectionRef();
GDALRasterBand* demBand = demDataset->GetRasterBand(1);
float* demarray = ReadRasterArray(demBand, width, height, gdal_datatype);
int dem_pixel_count = width * height;
int psize = (paras.sim_height+3000) * paras.sim_width;
short* sim_dem = (short*)calloc(psize, sizeof(short));
//// 计算每个块的尺寸
int dem_block_size = int(ceil(sqrt(10*1024* 1024 / (paras.sample_f* paras.sample_f *sizeof(gdal_datatype))))); // 获取每块dem的尺寸
//构建内存储空间对象
// try {
int a = 2;
int i = 3;
int j = 3;
int thread_ids = 0;
bool hasfullpool = false;
int count_sum = height * width / (dem_block_size * dem_block_size);
int count_cure = 0;
// 标志文件是否正在写出
//bool outmatchpointing = false;
//std::vector<thread> outmatchpointthread(0);
int tempstate = 0;
ThreadPool* subthreadPool = new ThreadPool(thread_num, true);
ThreadPoolPtr poolPtr(subthreadPool);
poolPtr->start();
int start_row =0;
int start_col =0;
int end_row = 0;
int end_col = 0;
// 扩充
int end_row_ex = 0;
int end_col_ex = 0;
int block_height = 0;
int block_width = 0;
while (i < height - 1) {
j = 3;
while (j < width - 1)
{
count_cure++;
// 计算起始行列数
start_row = i;
start_col = j;
end_row = start_row + dem_block_size;
end_col = start_col + dem_block_size;
// 扩充
end_row_ex = end_row + 3;
end_col_ex = end_col + 3;
if (end_row_ex > height) {
end_row = height - 3;
end_row_ex = height;
}
if (end_col_ex > width) {
end_col = width - 3;
end_col_ex = width;
}
block_height = end_row - start_row + 6;
block_width = end_col - start_col + 6;
poolPtr->append(std::bind(taskFunc, paras, dem_block_size, width, sim_dem, count_cure, count_sum,
i, j, block_height, block_width, end_row_ex, end_col_ex, demarray, gtt, inv_gtt));
thread_ids++;
j = j + dem_block_size;
}
i = i + dem_block_size;
}
std::cout << "SimProcess doing"<<std::endl;
poolPtr->waiteFinish();
// 输出文件
std::cout << "输出成果文件:" << getCurrentTimeString() << std::endl;
GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
const char* out_sar_sim = paras.out_sar_sim_path.c_str();
GDALDataset* poDstDS = poDriver->Create(out_sar_sim, paras.sim_width, paras.sim_height + 3000, 1, GDT_Int16, NULL);
poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, paras.sim_width, paras.sim_height + 3000, sim_dem, paras.sim_width, paras.sim_height + 3000, GDT_Int16, 0, 0);
GDALFlushCache(poDstDS);
GDALClose(poDstDS);
free(sim_dem);
GDALClose(demDataset);
delete demarray;
std::cout << "输出成果文件-over" << std::endl;
std::cout << "end time:" << getCurrentTimeString() << std::endl;
return 0;
}
int SimProcess_Calsim2ori(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num)
{
std::cout << "begin time:" << getCurrentTimeString() << std::endl;
GDALAllRegister();// 注册格式的驱动
// 打开DEM影像
GDALDataset* demDataset = (GDALDataset*)(GDALOpen(conveparas.in_ori_dem_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像
int width = demDataset->GetRasterXSize();
int height = demDataset->GetRasterYSize();
int nCount = demDataset->GetRasterCount();
double* gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵
demDataset->GetGeoTransform(gt); // 获得仿射矩阵
translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] };
double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵
GDALInvGeoTransform(gt, inv_gt); // 逆矩阵
translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] };
GDALDataType gdal_datatype = demDataset->GetRasterBand(1)->GetRasterDataType();
const char* Projection = demDataset->GetProjectionRef();
GDALRasterBand* demBand = demDataset->GetRasterBand(1);
float* demarray = ReadRasterArray(demBand, width, height, gdal_datatype);
int dem_pixel_count = width * height;
int psize = width * height;
float* sar_local_angle = (float*)calloc(psize, sizeof(float));
float* sar_angle = (float*)calloc(psize, sizeof(float));
float* sar_dem_x = (float*)calloc(psize, sizeof(float));
float* sar_dem_y = (float*)calloc(psize, sizeof(float));
for (int i = 0; i < psize; i++) {
sar_dem_x[i] = -100000;
sar_dem_y[i] = -100000;
sar_local_angle[i] = -9999;
sar_angle[i] = -9999;
}
int blocksize =1000 ; // 获取每块dem的尺寸
int tempstate = 0;
ThreadPool* subthreadPool = new ThreadPool(thread_num, true);
ThreadPoolPtr poolPtr(subthreadPool);
poolPtr->start();
for (int start_row = 1; start_row <height-2; ) {
int end_row = (start_row + blocksize >= height-2 )? height-2 : (start_row + blocksize);
for(int start_col =1; start_col < width -2;)
{
int end_col = (start_col + blocksize >= width-2) ? width-2 : (start_col + blocksize);
poolPtr->append(std::bind(taskFunc_Calsim2ori, paras, conveparas,
start_row, end_row, start_col, end_col,width, height,
sar_local_angle,sar_angle, sar_dem_x,sar_dem_y,
demarray, gtt, inv_gtt));
start_col = end_col;
}
start_row = end_row;
}
std::cout << "doing...." << std::endl;
poolPtr->waiteFinish();
// 输出文件;
std::cout << "输出成果文件:" << getCurrentTimeString() << std::endl;
GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
const char* out_sar_sim = paras.out_sar_sim_path.c_str();
poolPtr->stop();
GDALClose(demDataset);
delete demarray, demBand, subthreadPool;
out_sar_sim = conveparas.ori_sim.c_str();
GDALDataset* poDstDS = poDriver->Create(out_sar_sim, width, height, 2, GDT_Float32, NULL);
poDstDS->SetGeoTransform(gt);
poDstDS->SetProjection(Projection);
poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_dem_x, width, height, GDT_Float32, 0, 0);
poDstDS->GetRasterBand(1)->SetNoDataValue(-100000);
poDstDS->GetRasterBand(2)->RasterIO(GF_Write, 0, 0, width, height, sar_dem_y, width, height, GDT_Float32, 0, 0);
poDstDS->GetRasterBand(2)->SetNoDataValue(-100000);
GDALFlushCache(poDstDS);
GDALClose(poDstDS);
poDstDS = poDriver->Create(conveparas.out_orth_sar_local_incidence_path.c_str(), width, height, 1, GDT_Float32, NULL);
poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_local_angle, width, height, GDT_Float32, 0, 0);
poDstDS->GetRasterBand(1)->SetNoDataValue(-9999);
poDstDS->SetGeoTransform(gt);
poDstDS->SetProjection(Projection);
GDALFlushCache(poDstDS);
GDALClose(poDstDS);
poDstDS = poDriver->Create(conveparas.out_orth_sar_incidence_path.c_str(), width, height, 1, GDT_Float32, NULL);
poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_angle, width, height, GDT_Float32, 0, 0);
poDstDS->GetRasterBand(1)->SetNoDataValue(-9999);
poDstDS->SetGeoTransform(gt);
poDstDS->SetProjection(Projection);
GDALFlushCache(poDstDS);
GDALClose(poDstDS);
std::cout << "输出成果文件-over" << std::endl;
std::cout << "end time:" << getCurrentTimeString() << std::endl;
free(sar_dem_x);
free(sar_dem_y);
free(sar_local_angle);
free(sar_angle);
free(gt);
free(inv_gt);
return 0;
}
/*
11 12 13 14
21 22 23 24
31 32 33 34
41 42 43 44
*/
//分块重采样
int orth_ReSampling(int start_row,int end_row,int start_col,int end_col,
int width,int height,int ori_width,int ori_height ,
float* ori_array, float* result_arr, float* ori_r_array, float* ori_c_array) {
for (int i = start_row; i < end_row; i++) {
for (int j = start_col; j < end_col; j++) {
int ori_ids = i * width + j;
int p_ids = 0;
point p{ ori_r_array[ori_ids] ,ori_c_array[ori_ids],0 };
point p22 { floor(ori_r_array[ori_ids]),floor(ori_c_array[ori_ids]),0 };
if (p22.x < 0 || p22.y < 0 || p22.x >= ori_height - 1 || p22.y >= ori_width - 1) {
continue;
}
else if (p22.x < 1 || p22.y < 1 || p22.x >= ori_height - 2 || p22.y >= ori_width - 2) {
//双线性
point p23{ p22.x ,p22.y + 1,0 }; p_ids = p23.x * ori_width + p23.y; p23.z = ori_array[p_ids];
point p32{ p22.x + 1,p22.y ,0 }; p_ids = p32.x * ori_width + p32.y; p32.z = ori_array[p_ids];
point p33{ p22.x + 1,p22.y + 1,0 }; p_ids = p33.x * ori_width + p33.y; p33.z = ori_array[p_ids];
p.x = p.x - p22.x;
p.y = p.y - p22.y;
p=bilineadInterpolation(p, p22, p23, p32, p33);
result_arr[ori_ids] = p.z;
}
else { // p22.x >= 1 && p22.y >= 1 && p22.x < ori_height - 2&& p22.y < ori_width - 2
// 三次
point p11{ p22.x - 1,p22.y - 1,0 }; p_ids = p11.x * ori_width + p11.y; p11.z = ori_array[p_ids];
point p12{ p22.x - 1,p22.y ,0 }; p_ids = p12.x * ori_width + p12.y; p12.z = ori_array[p_ids];
point p13{ p22.x - 1,p22.y + 1,0 }; p_ids = p13.x * ori_width + p13.y; p13.z = ori_array[p_ids];
point p14{ p22.x - 1,p22.y + 2,0 }; p_ids = p14.x * ori_width + p14.y; p14.z = ori_array[p_ids];
point p21{ p22.x ,p22.y - 1,0 }; p_ids = p21.x * ori_width + p21.y; p21.z = ori_array[p_ids];
point p23{ p22.x ,p22.y + 1,0 }; p_ids = p23.x * ori_width + p23.y; p23.z = ori_array[p_ids];
point p24{ p22.x ,p22.y + 2,0 }; p_ids = p24.x * ori_width + p24.y; p24.z = ori_array[p_ids];
point p31{ p22.x + 1,p22.y - 1,0 }; p_ids = p31.x * ori_width + p31.y; p31.z = ori_array[p_ids];
point p32{ p22.x + 1,p22.y ,0 }; p_ids = p32.x * ori_width + p32.y; p32.z = ori_array[p_ids];
point p33{ p22.x + 1,p22.y + 1,0 }; p_ids = p33.x * ori_width + p33.y; p33.z = ori_array[p_ids];
point p34{ p22.x + 1,p22.y + 2,0 }; p_ids = p34.x * ori_width + p34.y; p34.z = ori_array[p_ids];
point p41{ p22.x + 2,p22.y - 1,0 }; p_ids = p41.x * ori_width + p41.y; p41.z = ori_array[p_ids];
point p42{ p22.x + 2,p22.y ,0 }; p_ids = p42.x * ori_width + p42.y; p42.z = ori_array[p_ids];
point p43{ p22.x + 2,p22.y + 1,0 }; p_ids = p43.x * ori_width + p43.y; p43.z = ori_array[p_ids];
point p44{ p22.x + 2,p22.y + 2,0 }; p_ids = p44.x * ori_width + p44.y; p44.z = ori_array[p_ids];
p.x = p.x - p11.x;
p.y = p.y - p11.y;
p = cubicInterpolation(p, p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44);
result_arr[ori_ids] = p.z;
}
}
}
//std::cout << "\r" << end_row << "/" << height << "," << end_col << "/" << width << ","<<end_row*end_col*100.0/(width*height) << "------------------";
return 0;
}
int orth_pow(int start_row, int end_row, int start_col, int end_col,
int width, int height,
float* result_arr, float* ori_a_array, float* ori_b_array) {
for (int i = start_row; i < end_row; i++) {
for (int j = start_col; j < end_col; j++) {
int ori_ids = i * width + j;
result_arr[ori_ids] = log10(ori_a_array[ori_ids] * ori_a_array[ori_ids] + ori_b_array[ori_ids] * ori_b_array[ori_ids]+1)*10;
}
}
//std::cout << "\r" << end_row << "/" << height << "," << end_col << "/" << width << ","<<end_row*end_col*100.0/(width*height) << "------------------";
return 0;
}
/*
重采样对象
*/
int SimProcess_ResamplingOri2Orth(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num)
{
std::cout << "begin time:" << getCurrentTimeString() << std::endl;
GDALAllRegister();// 注册格式的驱动
// 打开DEM影像
GDALDataset* sim2oriDataset = (GDALDataset*)(GDALOpen(conveparas.ori_sim.c_str(), GA_ReadOnly));//以只读方式读取地形影像
int width = sim2oriDataset->GetRasterXSize();
int height = sim2oriDataset->GetRasterYSize();
int nCount = sim2oriDataset->GetRasterCount();
double*gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵
sim2oriDataset->GetGeoTransform(gt); // 获得仿射矩阵
translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] };
double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵
GDALInvGeoTransform(gt, inv_gt); // 逆矩阵
translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] };
GDALDataType gdal_datatype = sim2oriDataset->GetRasterBand(1)->GetRasterDataType();
const char* Projection = sim2oriDataset->GetProjectionRef();
GDALRasterBand* ori_r_Band = sim2oriDataset->GetRasterBand(1);
float* ori_r_array = ReadRasterArray(ori_r_Band, width, height, gdal_datatype);
GDALRasterBand* ori_c_Band = sim2oriDataset->GetRasterBand(2);
float* ori_c_array = ReadRasterArray(ori_c_Band, width, height, gdal_datatype);
// 读取行列号
delete ori_r_Band, ori_c_Band;
for (int t = 0; t < conveparas.file_count; t++) {
// 读
// 创建
GDALAllRegister();// 注册格式的驱动
GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
string in_file_path = conveparas.inputFile_paths[t];
string out_file_path = conveparas.outFile_paths[t];
GDALDataset* inDataset = (GDALDataset*)(GDALOpen(in_file_path.c_str(), GA_ReadOnly));
int orth_width = inDataset->GetRasterXSize();
int orth_height = inDataset->GetRasterYSize();
int orth_num = inDataset->GetRasterCount();
// 写
GDALDataset* outDstDS = poDriver->Create(out_file_path.c_str(), width, height, orth_num, GDT_Float32, NULL);
outDstDS->SetGeoTransform(gt);
outDstDS->SetProjection(Projection);
float* result_arr = (float*)calloc(width * height, sizeof(float));
int psize = width * height;
int blocksize = 1000;
for (int b = 1; b <= orth_num; b++) {
for (int i = 0; i < psize; i++) {
result_arr[i] = -9999;
}
GDALRasterBand* ori_Band = inDataset->GetRasterBand(b);
float* ori_arr= ReadRasterArray(ori_Band, orth_width, orth_height, gdal_datatype);
// 线程池
ThreadPool* subthreadPool = new ThreadPool(thread_num, true);
ThreadPoolPtr poolPtr(subthreadPool);
poolPtr->start();
// 三次样条重采样
for (int start_row = 0; start_row < height; start_row = start_row + blocksize) {
int end_row = start_row + blocksize >= height ? height : start_row + blocksize;
for (int start_col = 0; start_col < width; start_col = start_col + blocksize) {
int end_col = start_col + blocksize >= width ? width : start_col + blocksize;
// 分块计算结果
poolPtr->append(std::bind(orth_ReSampling,start_row,end_row,start_col,end_col,width,height, orth_width, orth_height,
ori_arr, result_arr, ori_r_array, ori_c_array));
}
}
std::cout << "resampling...." << std::endl;
poolPtr->waiteFinish();
// 输出文件
std::cout<<t<<" " << b << ",输出成果文件:" << getCurrentTimeString() << std::endl;
outDstDS->GetRasterBand(b)->RasterIO(GF_Write, 0, 0, width, height, result_arr, width, height, GDT_Float32, 0, 0);
outDstDS->GetRasterBand(b)->SetNoDataValue(-9999);
poolPtr->stop();
delete ori_arr, ori_Band, subthreadPool;
}
free(result_arr);
GDALFlushCache(outDstDS);
GDALClose(outDstDS);
GDALClose(inDataset);
}
free(gt);
free(inv_gt);
delete ori_r_array, ori_c_array;// , sim2oriDataset;
//GDALClose(sim2oriDataset);
return 0;
}
/// <summary>
/// 生成影像的强度图
/// </summary>
/// <param name="paras"></param>
/// <param name="conveparas"></param>
/// <param name="thread_num"></param>
/// <returns></returns>
int SimProcess_Calspow(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num)
{
for (int t = 0; t < conveparas.file_count; t++) {
// 读
// 创建
GDALAllRegister();// 注册格式的驱动
GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
string in_file_path = conveparas.outFile_paths[t];
string out_file_path = conveparas.outFile_pow_paths[t];
GDALDataset* inDataset = (GDALDataset*)(GDALOpen(in_file_path.c_str(), GA_ReadOnly));
int width = inDataset->GetRasterXSize();
int height = inDataset->GetRasterYSize();
int num = inDataset->GetRasterCount();
double*gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵
inDataset->GetGeoTransform(gt); // 获得仿射矩阵
translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] };
double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵
GDALInvGeoTransform(gt, inv_gt); // 逆矩阵
translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] };
const char* Projection = inDataset->GetProjectionRef();
GDALDataset* outDstDS = poDriver->Create(out_file_path.c_str(), width, height, 1, GDT_Float32, NULL);
outDstDS->SetGeoTransform(gt);
outDstDS->SetProjection(Projection);
GDALDataType gdal_datatype = inDataset->GetRasterBand(1)->GetRasterDataType();
GDALRasterBand* ori_Band = inDataset->GetRasterBand(1);
float* ori_a_array = ReadRasterArray(ori_Band, width, height, gdal_datatype);
ori_Band = inDataset->GetRasterBand(2);
float* ori_b_array = ReadRasterArray(ori_Band, width, height, gdal_datatype);
float* result_arr = (float*)calloc(width * height, sizeof(float));
int psize = width * height;
int blocksize = 1000;
for (int i = 0; i < psize; i++) {
result_arr[i] = -9999;
}
// 线程池
ThreadPool* subthreadPool = new ThreadPool(thread_num, true);
ThreadPoolPtr poolPtr(subthreadPool);
poolPtr->start();
// 三次样条重采样
for (int start_row = 0; start_row < height; start_row = start_row + blocksize) {
int end_row = start_row + blocksize >= height ? height : start_row + blocksize;
for (int start_col = 0; start_col < width; start_col = start_col + blocksize) {
int end_col = start_col + blocksize >= width ? width : start_col + blocksize;
// 分块计算结果
poolPtr->append(std::bind(orth_pow, start_row, end_row, start_col, end_col, width, height,
result_arr, ori_a_array, ori_b_array));
}
}
std::cout << "pow resampling ..." << std::endl;
poolPtr->waiteFinish();
// 输出文件
std::cout << t << " " << 1 << ",输出成果文件:" << getCurrentTimeString() << std::endl;
outDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, result_arr, width, height, GDT_Float32, 0, 0);
outDstDS->GetRasterBand(1)->SetNoDataValue(-9999);
poolPtr->stop();
delete ori_a_array, ori_b_array, ori_Band, subthreadPool;
free(gt);
free(inv_gt);
free(result_arr);
//GDALFlushCache(outDstDS);
//GDALClose(outDstDS);
//GDALClose(inDataset);
//delete poDriver;
}
//GDALClose(sim2oriDataset);
return 0;
}
int ResamplingSim(ParameterInFile paras)
{
GDALAllRegister();
// 打开DEM影像
GDALDataset* simDataset = (GDALDataset*)(GDALOpen(paras.out_sar_sim_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像
int ori_sim_width = simDataset->GetRasterXSize();
int ori_sim_height = simDataset->GetRasterYSize();
int width = paras.sim_width;
int height = paras.sim_height;
float width_scales = width * 1.0 / ori_sim_width;
float height_scales = height * 1.0 / ori_sim_height;
GDALClose(simDataset);
ResampleGDAL(paras.out_sar_sim_path.c_str(), paras.out_sar_sim_resampling_path.c_str(), width_scales, height_scales, GDALResampleAlg::GRA_CubicSpline);
return 0;
}
int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, float fResX = 1.0, float fResY = 1.0, GDALResampleAlg eResample = GRA_Bilinear)
{
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly);
if (pDSrc == NULL)
{
return -1;
}
GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
if (pDriver == NULL)
{
GDALClose((GDALDatasetH)pDSrc);
return -2;
}
int width = pDSrc->GetRasterXSize();
int height = pDSrc->GetRasterYSize();
int nBandCount = pDSrc->GetRasterCount();
GDALDataType dataType = GDALDataType::GDT_Float32;// pDSrc->GetRasterBand(1)->GetRasterDataType();
char* pszSrcWKT = NULL;
pszSrcWKT = const_cast<char*>(pDSrc->GetProjectionRef());
double dGeoTrans[6] = { 0 };
int nNewWidth = width, nNewHeight = height;
pDSrc->GetGeoTransform(dGeoTrans);
bool bNoGeoRef = false;
long double dOldGeoTrans0 = dGeoTrans[0];
//如果没有投影,人为设置一个
if (strlen(pszSrcWKT) <= 0)
{
//OGRSpatialReference oSRS;
//oSRS.SetUTM(50,true); //北半球 东经120度
//oSRS.SetWellKnownGeogCS("WGS84");
//oSRS.exportToWkt(&pszSrcWKT);
//pDSrc->SetProjection(pszSrcWKT);
//////////////////////////////////////////////////////////////////////////
dGeoTrans[0] = 1.0;
pDSrc->SetGeoTransform(dGeoTrans);
//////////////////////////////////////////////////////////////////////////
bNoGeoRef = true;
}
//adfGeoTransform[0] /* top left x */
//adfGeoTransform[1] /* w-e pixel resolution */
//adfGeoTransform[2] /* rotation, 0 if image is "north up" */
//adfGeoTransform[3] /* top left y */
//adfGeoTransform[4] /* rotation, 0 if image is "north up" */
//adfGeoTransform[5] /* n-s pixel resolution */
dGeoTrans[1] = dGeoTrans[1] / fResX;
dGeoTrans[5] = dGeoTrans[5] / fResY;
nNewWidth = static_cast<int>(nNewWidth * fResX + 0.5);
nNewHeight = static_cast<int>(nNewHeight * fResY + 0.5);
//创建结果数据集
GDALDataset* pDDst = pDriver->Create(pszOutFile, nNewWidth, nNewHeight, nBandCount, dataType, NULL);
if (pDDst == NULL)
{
GDALClose((GDALDatasetH)pDSrc);
return -2;
}
pDDst->SetProjection(pszSrcWKT);
pDDst->SetGeoTransform(dGeoTrans);
void* hTransformArg = NULL;
hTransformArg = GDALCreateGenImgProjTransformer2((GDALDatasetH)pDSrc, (GDALDatasetH)pDDst, NULL); //GDALCreateGenImgProjTransformer((GDALDatasetH) pDSrc,pszSrcWKT,(GDALDatasetH) pDDst,pszSrcWKT,FALSE,0.0,1);
if (hTransformArg == NULL)
{
GDALClose((GDALDatasetH)pDSrc);
GDALClose((GDALDatasetH)pDDst);
return -3;
}
GDALWarpOptions* psWo = GDALCreateWarpOptions();
psWo->papszWarpOptions = CSLDuplicate(NULL);
psWo->eWorkingDataType = dataType;
psWo->eResampleAlg = eResample;
psWo->hSrcDS = (GDALDatasetH)pDSrc;
psWo->hDstDS = (GDALDatasetH)pDDst;
psWo->pfnTransformer = GDALGenImgProjTransform;
psWo->pTransformerArg = hTransformArg;
psWo->nBandCount = nBandCount;
psWo->panSrcBands = (int*)CPLMalloc(nBandCount * sizeof(int));
psWo->panDstBands = (int*)CPLMalloc(nBandCount * sizeof(int));
for (int i = 0; i < nBandCount; i++)
{
psWo->panSrcBands[i] = i + 1;
psWo->panDstBands[i] = i + 1;
}
GDALWarpOperation oWo;
if (oWo.Initialize(psWo) != CE_None)
{
GDALClose((GDALDatasetH)pDSrc);
GDALClose((GDALDatasetH)pDDst);
return -3;
}
oWo.ChunkAndWarpImage(0, 0, nNewWidth, nNewHeight);
GDALDestroyGenImgProjTransformer(hTransformArg);
GDALDestroyWarpOptions(psWo);
if (bNoGeoRef)
{
dGeoTrans[0] = dOldGeoTrans0;
pDDst->SetGeoTransform(dGeoTrans);
//pDDst->SetProjection("");
}
GDALFlushCache(pDDst);
GDALClose((GDALDatasetH)pDSrc);
GDALClose((GDALDatasetH)pDDst);
return 0;
}
/// <summary>
/// 根据地面坐标获取计算结果
/// </summary>
/// <param name="landp"></param>
/// <param name="paras"></param>
/// <param name="convparas"></param>
/// <returns></returns>
point GetOriRC(point& landp, ParameterInFile& paras, ConvertResampleParameter& convparas)
{
long double Starttime = paras.imgStartTime;
long double lamda = paras.lamda;
long double refrange = paras.refrange;
long double* doppler_para = paras.doppler_para;
long double LightSpeed = paras.LightSpeed;
long double delta_t = paras.delta_t;
long double R0 = paras.R0;
long double delta_R = paras.delta_R;
long double SatelliteModelStartTime = paras.SatelliteModelStartTime;
long double* polySatellitePara = paras.polySatellitePara;
int sim_sar_width = paras.sim_width;
int sim_sar_height = paras.sim_height;
int polynum = paras.polynum;
int doppler_paramenter_number = paras.doppler_paramenter_number;
point pixelpoint = PSTN(landp, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number);
long double r, c;
sim2ori(pixelpoint.x, pixelpoint.y, r, c, convparas.sim2ori_paras);
return point{ r,c,0 };
}
// 根据坐标变换求解行列号
int calSARPosition(ParameterInFile paras, ConvertResampleParameter converPara) {
//
return 0;
}
///
/// 测试代码
///
int testPP() {
point landpoint;
landpoint.x = -1945072.5;
landpoint.y = 5344083.0;
landpoint.z = 2878316.0;
point targetpoint;
targetpoint.x = 31;
targetpoint.y = 118;
targetpoint.z = 33;
landpoint = LLA2XYZ(targetpoint);
std::cout << "PTSN\nX" << landpoint.x<< "\nY:" << landpoint.y << "\nZ" << landpoint.z << "\n"; // <0.1
return 0;
}
int testPTSN(ParameterInFile paras) {
point landpoint;
landpoint.x = -1945072.5;
landpoint.y = 5344083.0;
landpoint.z = 2878316.0;
point targetpoint;
targetpoint.x = 31;
targetpoint.y = 118;
targetpoint.z = 1592144812.73686337471008300781;
landpoint=LLA2XYZ(targetpoint);
point pixelpoint = PSTN(landpoint, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number);
std::cout << "PTSN\nX" << targetpoint.x - pixelpoint.x << "\nY:" << targetpoint.y - pixelpoint.y << "\nZ" << targetpoint.z - pixelpoint.z << "\n"; // <0.1
SatelliteSpacePoint sateP = getSatellitePostion(1592144812.7368634, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum);
SatelliteSpacePoint sateT{ -3044863.2137617283, 5669112.1303918585, 3066571.1073331647, -26.15659591374557, 3600.8531673370803, -6658.59211430739 };
std::cout << "Sate\nX" << sateP.x - sateT.x << "\nY:" << sateP.y - sateT.y << "\nZ" << sateP.z - sateT.z << "\nVx" << sateP.vx - sateT.vx << "\nVy:" << sateP.vy - sateT.vy << "\nVz:" << sateP.vz - sateT.vz << "\n";
return 0;
}