#pragma once
///
/// 仿真成像算法
/// 
//#define EIGEN_USE_MKL_ALL
//#define EIGEN_VECTORIZE_SSE4_2
//#include <mkl.h>
// 本地方法

#include "BaseTool.h"
#include <iostream>
#include <Eigen/Core>
#include <Eigen/Dense>
#include <time.h>
//#include <mkl.h>
#include <omp.h>
#include "SateOrbit.h"
 using namespace std;
using namespace Eigen;

////////////// 常用函数 ////////////////////////

double getRangeColumn(long double R, long double NearRange, long double Fs, long double lamda);
Eigen::MatrixXd getRangeColumn(Eigen::MatrixXd R, long double NearRange, long double Fs, long double lamda);

double getRangebyColumn(double j, long double NearRange, long double Fs, long double lamda);
Eigen::MatrixXd getRangebyColumn(Eigen::MatrixXd j, long double NearRange, long double Fs, long double lamda);
/////////////  ptsn 算法 /////////////////////

class PSTNAlgorithm {
public:
	// 初始化与析构函数
	PSTNAlgorithm();
	PSTNAlgorithm(QString parameterPath);
	~PSTNAlgorithm();

	int dem2lat_lon(QString dem_path, QString lon_path, QString lat_path);
	int dem2SAR_RC(QString dem_path, QString sim_rc_path);
	
	// 模拟算法函数
	Eigen::MatrixX<double> calNumericalDopplerValue(Eigen::MatrixX<double> R);// 数值模拟法计算多普勒频移值
	double calNumericalDopplerValue(double R);// 数值模拟法计算多普勒频移值
	Eigen::MatrixX<double> calTheoryDopplerValue(Eigen::MatrixX<double> R, Eigen::MatrixX<double> R_s1, Eigen::MatrixX<double> V_s1);//根据理论模型计算多普勒频移值
	double calTheoryDopplerValue(double R, Eigen::MatrixX<double> R_s1, Eigen::MatrixX<double> V_s1);
	Eigen::MatrixX<double> PSTN(Eigen::MatrixX<double> TargetPostion, double ave_dem, double dt, bool isCol ); // 输入DEM
	//Eigen::MatrixXd WGS842J2000(Eigen::MatrixXd blh);
	//Landpoint WGS842J2000(Landpoint p);
public: // WGS84 到 J2000 之间的变换参数
	Eigen::MatrixXd UTC;
	double Xp = 0.204071;
	double Yp = 0.318663;
	double Dut1 = 0.0366742;
	double Dat = 37;
public:
	int height; // 影像的高
	int width;
	
	int widthspace;

	// 入射角
	double near_in_angle;// 近入射角
	double far_in_angle;// 远入射角

	// SAR的成像参数
	double fs;// 距离向采样率
	double R0;//近斜距
	double LightSpeed; // 光速
	double lamda;// 波长
	double refrange;// 参考斜距

	double imgStartTime;// 成像起始时间
	double PRF;// 脉冲重复率

	int doppler_paramenter_number;//多普勒系数个数
	MatrixX<double> doppler_paras;// 多普勒系数
	
	OrbitPoly orbit; // 轨道模型

};
 
/// <summary>
/// 侧视入射角,角度值
/// </summary>
/// <param name="satepoint"></param>
/// <param name="landpoint"></param>
/// <returns></returns>
double getIncAngle(Landpoint& satepoint, Landpoint& landpoint);


/// <summary>
/// ASF计算方法
/// </summary>
class ASFOrthClass {

public:
	Eigen::MatrixXd Satellite2ECR(Eigen::Vector3d Rsc, Eigen::Vector3d Vsc); // 根据卫星坐标计算变换矩阵 M
	Eigen::Vector3d UnitVectorOfSatelliteAndTarget(double alpha, double beta, Eigen::MatrixXd M);
	double GetLookFromRangeYaw(double R, double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, double R_threshold, double H = 0);
	
	Eigen::Vector3d GetXYZByBetaAlpha(double alpha,double beta, Eigen::Vector3d SatellitePosition,double R, Eigen::MatrixXd M);

	double FD(double alpha, double beta, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetVelocity,double  R,double  lamda, Eigen::MatrixXd M);
	double FR(double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::MatrixXd M, double R_threshold, double H = 0);

	Eigen::Vector3d ASF(double R, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetPosition, PSTNAlgorithm PSTN, double R_threshold, double H = 0, double alpha0 = 0, double beta0 = 0);

};

/// <summary>
/// 仿真处理流程
/// </summary>
class simProcess {
public:
	simProcess();
	~simProcess();

	int parameters(int argc, char* argv[]);

	int InitSimulationSAR(QString paras_path,QString workspace_path,QString out_dir_path,QString in_dem_path,QString in_sar_path); // 间接定位法
	
	int CreateSARDEM();
	int dem2SAR(); // 切换行号
	int SARIncidentAngle();
	int SARSimulationWGS();
	int SARSimulation();
	int in_sar_power();
	int ReflectTable_WGS2Range();

	int InitRPCIncAngle(QString paras_path, QString workspace_path, QString out_dir_path, QString in_dem_path,QString in_rpc_lon_lat_path,QString out_inc_angle_path, QString out_local_inc_angle_path, QString out_inc_angle_geo_path, QString out_local_inc_angle_geo_path);
	int dem2SAR_row(); // 切换行号
	int SARIncidentAngle_RPC();
	int createRPCDEM();

	// 格网离散插值
	int Scatter2Grid(QString lon_lat_path, QString data_tiff, QString grid_path, double space);

	// ASF 模块计算
	int InitASFSAR(QString paras_path, QString workspace_path, QString out_dir_path, QString in_dem_path);

	int ASF(QString in_dem_path, QString out_latlon_path, ASFOrthClass asfclass, PSTNAlgorithm PSTN);

	//int dem2simSAR(QString dem_path, QString out_sim_path, PSTNAlgorithm PSTN); // 根据DEM生成输出仿真图像
	int sim_SAR(QString dem_path, QString sim_rc_path, QString sim_sar_path, PSTNAlgorithm PSTN);
	int dem2aspect_slope(QString dem_path, QString aspect_path, QString slope_path);
	int sim_sum_SAR(QString sim_dem_path,QString sim_rc_path, QString sim_orth_path, QString sim_sum_path,PSTNAlgorithm pstn);
	void interpolation_GTC_sar_sigma(QString in_rc_wgs84_path, QString in_ori_sar_path, QString out_orth_sar_path, PSTNAlgorithm pstn);
	// 原始影像强度图
	int ori_sar_power(QString ori_sar_path, QString out_sar_power_path);

	// 匹配偏移模型构建
	int createImageMatchModel(QString ori_sar_rsc_path, QString ori_sar_rsc_jpg_path, QString sim_sar_path, QString sim_sar_jpg_path, QString matchmodel_path);


	int correct_ati(QString orth_rc_path, QString dem_path, QString out_inclocal_path, QString out_dem_path, QString out_count_path, PSTNAlgorithm PSTN);

	void calcalIncident_localIncident_angle(QString in_dem_path, QString in_rc_wgs84_path, QString out_incident_angle_path, QString out_local_incident_angle_path, PSTNAlgorithm PSTN);

	void calGEC_Incident_localIncident_angle(QString in_dem_path, QString in_gec_lon_lat_path,QString  out_incident_angle_path, QString out_local_incident_angle_path,PSTNAlgorithm PSTN);

	void interpolation_GTC_sar(QString in_rc_wgs84_path, QString   in_ori_sar_path, QString   out_orth_sar_path, PSTNAlgorithm pstn);
	// RPC
	void CreateRPC_DEM(QString in_rpc_rc_path, QString in_dem_path, QString out_rpc_dem_path);

	void CreateRPC_refrenceTable(QString in_rpc_tiff_path, QString in_merge_dem, QString out_rpc_lon_lat_tiff_path);

	void CorrectionFromSLC2Geo(QString in_lon_lat_path, QString in_radar_path, QString out_radar_path, int in_band_ids);


// 内部参数
public:
 
	bool isMatchModel;

	QString workSpace_path;// 工作空间路径
	QString outSpace_path;// 输出工作空间路径
	PSTNAlgorithm pstn; // 参数组件
	/////  RPC 局地入射角   ///////////////////////////////////
	QString in_rpc_lon_lat_path;
	QString out_dir_path;
	QString workspace_path;
	// 临时文件
	QString rpc_wgs_path;
	QString ori_sim_count_tiff;// 映射角文件
	// 输出文件
	QString out_inc_angle_rpc_path;
	QString out_local_inc_angle_rpc_path;

	// 输出文件
	QString out_inc_angle_geo_path;
	QString out_local_inc_angle_geo_path;

	///// 正向仿真方法 /////////


	
	// 临时产品文件
	QString in_dem_path; // 输入DEM
	QString dem_path; // 重采样之后DEM
	QString dem_r_path;// 行号影像
	QString dem_rc_path; // 行列号 
	QString sar_sim_wgs_path;
	QString sar_sim_path;
	QString in_sar_path;
	QString sar_jpg_path;
	QString sar_power_path;
	// 最终产品
	QString out_dem_rc_path; // 经纬度与行列号变换文件

	QString out_dem_slantRange_path; // 斜距文件
	QString out_plant_slantRange_path;// 平面斜距文件

	//// ASF 方法 /////////////
	QString out_lon_path;// 经度
	QString out_lat_path;// 纬度
	QString out_slantRange_path;// 斜距文件

	/// 共同文件 ///
	QString out_localIncidenct_path;// 计算局地入射角
	QString out_incidence_path; // 入射角文件
	QString out_ori_sim_tiff;// 映射角文件'
	QString out_sim_ori_tiff;
};

bool PtInRect(Point3 pCur, Point3 pLeftTop, Point3 pRightTop, Point3 pRightBelow, Point3 pLeftBelow);


