#include "DEMLLA2XYZTool.h"
#include <QMessageBox>
#include <QFileDialog>
#include "ImageOperatorBase.h"
#include "GeoOperator.h"


DEMLLA2XYZTool::DEMLLA2XYZTool(QWidget *parent)
	: QDialog(parent)
{
	ui.setupUi(this);

	connect(this->ui.dialogBtn, SIGNAL(accepted()), this, SLOT(onaccept()));
	connect(this->ui.dialogBtn, SIGNAL(rejected()), this, SLOT(onreject()));
	connect(this->ui.DEMWSG84SelectBtn, SIGNAL(clicked()), this, SLOT(onDEMWSG84SelectBtn_Clicked()));
	connect(this->ui.DEMXYZSelectBtn, SIGNAL(clicked()), this, SLOT(onDEMXYZSelectBtn_Clicked()));
	connect(this->ui.BtnSloper, SIGNAL(clicked()), this, SLOT(onBtnSloper_Clicked()));
 

}

DEMLLA2XYZTool::~DEMLLA2XYZTool()
{}

void DEMLLA2XYZTool::onaccept()
{
	QString DEMPath = this->ui.lineEditLLA->text();
	QString XYZPath = this->ui.lineEditXYZ->text();
	QString SLOPERPath = this->ui.lineEditSloper->text();

	this->ui.progressBar->setValue(0);
	this->ui.progressBar->setMaximum(100);

	gdalImage demds(DEMPath);
	gdalImage demxyz = CreategdalImageDouble(XYZPath, demds.height, demds.width, 3, demds.gt, demds.projection, true, true, true);// X,Y,Z

	// 分块计算并转换为XYZ

	//Eigen::MatrixXd demArr = demds.getData(0, 0, demds.height, demds.width, 1);
	//Eigen::MatrixXd demR = demArr;

	double R = 0;
	double dem_row = 0, dem_col = 0, dem_alt = 0;

	long line_invert = Memory1MB/8.0/ demds.width*1000;


	this->ui.label_3->setText("WGS84 : LLA -> XYZ");
	
	for (int max_rows_ids = 0; max_rows_ids < demds.height; max_rows_ids = max_rows_ids + line_invert) {
		

		Eigen::MatrixXd demdata = demds.getData(max_rows_ids, 0, line_invert, demds.width, 1);
		Eigen::MatrixXd xyzdata_x = demdata.array() * 0;
		Eigen::MatrixXd xyzdata_y = demdata.array() * 0;
		Eigen::MatrixXd xyzdata_z = demdata.array() * 0;

		int datarows = demdata.rows();
		int datacols = demdata.cols();

#pragma omp parallel for
		for (int i = 0; i < datarows; i++) {
			Landpoint LandP{ 0,0,0 };
			Point3 GERpoint{ 0,0,0 };
			double rowidx = 0;
			double colidx = 0;
			for (int j = 0; j < datacols; j++) {
				rowidx = i + max_rows_ids;
				colidx = j;
				demds.getLandPoint(rowidx, colidx, demdata(i, j), LandP); // 获取地理坐标
				LLA2XYZ(LandP, GERpoint); // 经纬度转换为地心坐标系
				xyzdata_x(i, j) = GERpoint.x;
				xyzdata_y(i, j) = GERpoint.y;
				xyzdata_z(i, j) = GERpoint.z;
			}
		}
		demxyz.saveImage(xyzdata_x, max_rows_ids, 0, 1);
		demxyz.saveImage(xyzdata_y, max_rows_ids, 0, 2);
		demxyz.saveImage(xyzdata_z, max_rows_ids, 0, 3);

		this->ui.progressBar->setValue(100.0*(max_rows_ids/ demds.height/2));
	}


	// 计算坡向角

 

	gdalImage demsloperxyz = CreategdalImageDouble(SLOPERPath, demds.height, demds.width, 4, demds.gt, demds.projection, true, true, true);// X,Y,Z,cosangle
 
	line_invert = 1000;
	long start_ids = 0;
	long dem_rows = 0, dem_cols = 0;
	this->ui.label_3->setText("WGS84 : XYZ -> Sloper XYZ ");
	for (start_ids = 1; start_ids < demds.height; start_ids = start_ids + line_invert) {
		Eigen::MatrixXd demdata = demds.getData(start_ids - 1, 0, line_invert + 2, demxyz.width, 1);
		long startlineid = start_ids;
 
		Eigen::MatrixXd demsloper_x = demsloperxyz.getData(start_ids - 1, 0, line_invert + 2, demxyz.width, 1);
		Eigen::MatrixXd demsloper_y = demsloperxyz.getData(start_ids - 1, 0, line_invert + 2, demxyz.width, 2);
		Eigen::MatrixXd demsloper_z = demsloperxyz.getData(start_ids - 1, 0, line_invert + 2, demxyz.width, 3);
		Eigen::MatrixXd demsloper_angle = demsloperxyz.getData(start_ids - 1, 0, line_invert + 2, demxyz.width, 4);
		 
		Landpoint p0, p1, p2, p3, p4, pslopeVector, pp;
		Vector3D  slopeVector;

		dem_rows = demsloper_x.rows();
		dem_cols = demsloper_x.cols();
		double sloperAngle = 0;
		Vector3D Zaxis = { 0,0,1 };

		double rowidx = 0, colidx = 0;
#pragma omp parallel for
		for (long i = 1; i < dem_rows - 1; i++) {
			for (long j = 1; j < dem_cols - 1; j++) {
				rowidx = i + startlineid;
				colidx = j;
				demds.getLandPoint(rowidx, colidx, demdata(i, j), p0);
				demds.getLandPoint(rowidx - 1, colidx, demdata(i - 1, j), p1);
				demds.getLandPoint(rowidx, colidx - 1, demdata(i, j - 1), p2);
				demds.getLandPoint(rowidx + 1, colidx, demdata(i + 1, j), p3);
				demds.getLandPoint(rowidx, colidx + 1, demdata(i, j + 1), p4);

				pslopeVector = getSlopeVector(p0, p1, p2, p3, p4); // 地面坡向矢量
				slopeVector = { pslopeVector.lon,pslopeVector.lat,pslopeVector.ati };
				pp = LLA2XYZ(p0);
				Zaxis.x = pp.lon;
				Zaxis.y = pp.lat;
				Zaxis.z = pp.ati;
				sloperAngle = getCosAngle(slopeVector, Zaxis); // 地面坡向角

				demsloper_x(i, j) = slopeVector.x;
				demsloper_y(i, j) = slopeVector.y;
				demsloper_z(i, j) = slopeVector.z;
				demsloper_angle(i, j) = sloperAngle;
			 
			}
		}
 
		demsloperxyz.saveImage(demsloper_x, start_ids - 1, 0, 1);
		demsloperxyz.saveImage(demsloper_y, start_ids - 1, 0, 2);
		demsloperxyz.saveImage(demsloper_z, start_ids - 1, 0, 3);
		demsloperxyz.saveImage(demsloper_angle, start_ids - 1, 0, 4);

		this->ui.progressBar->setValue(50+ 100.0 * start_ids / demds.height / 2);
	}

	QMessageBox::information(this, tr(u8"程序执行完成"), tr(u8"程序执行完成。"));

	this->ui.progressBar->setValue(0);
	this->ui.label_3->setText("");
}

void DEMLLA2XYZTool::onreject()
{
	this->close();
}

void DEMLLA2XYZTool::onDEMWSG84SelectBtn_Clicked()
{
	QString fileName = QFileDialog::getOpenFileName(
		this,                           // 父窗口
		tr(u8"选择影像文件"),               // 标题
		QString(),                      // 默认路径
		tr(u8"tif Files (*.tif);;data Files (*.data);;bin Files (*.bin);;All Files (*)")  // 文件过滤器
	);

	// 如果用户选择了文件
	if (!fileName.isEmpty()) {
		this->ui.lineEditLLA->setText(fileName);
		
	}
	else {
		QMessageBox::information(this, tr(u8"没有选择文件"), tr(u8"没有选择任何文件。"));
	}

}

void DEMLLA2XYZTool::onDEMXYZSelectBtn_Clicked()
{
	QString fileName = QFileDialog::getSaveFileName(
		this,                           // 父窗口
		tr(u8"选择XYZ文件"),               // 标题
		QString(),                      // 默认路径
		tr(u8"data Files (*.data);;bin Files (*.bin)")  // 文件过滤器
	);

	// 如果用户选择了文件
	if (!fileName.isEmpty()) {
		this->ui.lineEditXYZ->setText(fileName);

	}
	else {
		QMessageBox::information(this, tr(u8"没有选择文件"), tr(u8"没有选择任何文件。"));
	}

}

void DEMLLA2XYZTool::onBtnSloper_Clicked()
{
	QString fileName = QFileDialog::getSaveFileName(
		this,                           // 父窗口
		tr(u8"选择 sloper 文件"),               // 标题
		QString(),                      // 默认路径
		tr(u8"data Files (*.data);;bin Files (*.bin)")  // 文件过滤器
	);

	// 如果用户选择了文件
	if (!fileName.isEmpty()) {
		this->ui.lineEditSloper->setText(fileName);

	}
	else {
		QMessageBox::information(this, tr(u8"没有选择文件"), tr(u8"没有选择任何文件。"));
	}
}
