365 lines
9.9 KiB
C++
365 lines
9.9 KiB
C++
#include "DEM_Fill.h"
|
||
|
||
#include <qgsrasterlayer.h>
|
||
#include <qgsvectorlayer.h>
|
||
#include <qgsmapcanvas.h>
|
||
|
||
void WorkThreadObject::runFillingWork(QString in_masked, QString out_filled, QString scale, QString size)
|
||
{
|
||
QDir pyDir = QDir(qApp->applicationDirPath());
|
||
if (!pyDir.cd("models\\mask_fill"))
|
||
{
|
||
qDebug() << "no folder models\\mask_fill";
|
||
return;
|
||
}
|
||
QString pyFilePath = pyDir.absoluteFilePath("demFillHoles.py");
|
||
if (pyFilePath == "")
|
||
{
|
||
qDebug() << "not find demFillHoles.py";
|
||
return;
|
||
}
|
||
QDir datDir = QDir(qApp->applicationDirPath());
|
||
if (!datDir.cd("QGIS_3.22.8\\bin"))
|
||
{
|
||
qDebug() << "no folder QGIS_3.22.8\\bin";
|
||
return;
|
||
}
|
||
QString datPath = datDir.absoluteFilePath("python-qgis-ltr.bat");
|
||
if (datPath == "")
|
||
{
|
||
qDebug() << "not find qgis env";
|
||
return;
|
||
}
|
||
const char* cmd = (datPath + " " + pyFilePath + " --in_holedem " + in_masked + "/" + " --work_space " + out_filled + "/" +
|
||
" --scale " + scale + " --win_size " + size).toStdString().c_str();
|
||
cout << cmd << "\n";
|
||
run_cmd(cmd);
|
||
//QString cmd = datPath + " " + pyFilePath
|
||
// + " --in_holedem " + in_masked + "/" + " --work_space " + out_filled + "/"
|
||
// + " --scale " + scale + " --win_size " + size;
|
||
//QProcess* pProces = new QProcess(this);
|
||
//connect(pProces, SIGNAL(readyReadStandardOutput()), this, SLOT(readProcessStandardOutput()));
|
||
//pProces->start(cmd);
|
||
//emit process(2);
|
||
}
|
||
|
||
void WorkThreadObject::readProcessStandardOutput()
|
||
{
|
||
mProcess = (QProcess*)sender();
|
||
QString output = QString::fromLocal8Bit(mProcess->readAllStandardOutput());
|
||
output.chop(2);
|
||
if (output.toFloat() != 0)
|
||
{
|
||
qDebug() << "process:" << output.toFloat();
|
||
emit process(output.toFloat());
|
||
}
|
||
else
|
||
qDebug() << "unsolved exe out:" << output;
|
||
}
|
||
|
||
int WorkThreadObject::run_cmd(const char* cmd)
|
||
{
|
||
char MsgBuff[1024];
|
||
int MsgLen = 1020;
|
||
FILE* fp;
|
||
if (cmd == NULL)
|
||
return -1;
|
||
if ((fp = _popen(cmd, "r")) == NULL)
|
||
return -2;
|
||
else
|
||
{
|
||
memset(MsgBuff, 0, MsgLen);
|
||
//读取命令执行过程中的输出
|
||
while (fgets(MsgBuff, MsgLen, fp) != NULL)
|
||
{
|
||
printf("MsgBuff: %s\n", MsgBuff);
|
||
QString qStr = QString(MsgBuff);
|
||
if (qStr.toDouble() != 0.0)
|
||
emit process(qStr.toDouble());
|
||
}
|
||
//关闭执行的进程
|
||
if (_pclose(fp) == -1)
|
||
return -3;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
|
||
DataFilling::DataFilling()
|
||
{
|
||
//ui.setupUi(this);
|
||
}
|
||
|
||
QString DataFilling::PannelName()
|
||
{
|
||
return QString::fromLocal8Bit("");
|
||
}
|
||
|
||
QString DataFilling::CategoryName()
|
||
{
|
||
return QString::fromLocal8Bit("DEM模块");
|
||
}
|
||
|
||
QString DataFilling::EnglishName()
|
||
{
|
||
return QString::fromLocal8Bit("DEM_Module");
|
||
}
|
||
|
||
QString DataFilling::ChineseName()
|
||
{
|
||
return QString::fromLocal8Bit("数据填补");
|
||
}
|
||
|
||
QString DataFilling::Information()
|
||
{
|
||
return "数据填补";
|
||
}
|
||
|
||
QString DataFilling::IconPath()
|
||
{
|
||
return ":/DEM_Fill/resources/fill.svg";
|
||
}
|
||
|
||
QWidget* DataFilling::CenterWidget()
|
||
{
|
||
QString gdal_path = qApp->applicationDirPath().toLocal8Bit() + "/share/gdal";
|
||
QString pro_lib_path = qApp->applicationDirPath().toLocal8Bit() + "/share/proj";
|
||
qputenv("GDAL_DATA", gdal_path.toLocal8Bit());
|
||
qputenv("PROJ_LIB", pro_lib_path.toLocal8Bit());
|
||
|
||
bool showWin = false;
|
||
if (myWidget == nullptr)
|
||
{
|
||
myWidget = new QDialog();
|
||
showWin = true;
|
||
qDebug() << "new QDialog()";
|
||
}
|
||
else
|
||
{
|
||
qDebug() << "already have myWidget";
|
||
myWidget->activateWindow();
|
||
myWidget->raise();
|
||
return myWidget;
|
||
}
|
||
ui.setupUi(myWidget);
|
||
|
||
myWidget->setWindowTitle(QString::fromLocal8Bit("数据填补"));
|
||
myWidget->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
|
||
myWidget->setWindowIcon(QIcon(":/DEM_Fill/resources/fill.svg"));
|
||
myWidget->setAttribute(Qt::WA_QuitOnClose, false);
|
||
|
||
myWidget->setAttribute(Qt::WA_DeleteOnClose);
|
||
connect(myWidget, &QDialog::destroyed, this, [=] {
|
||
qDebug() << "----DEM Fill window close----";
|
||
|
||
QDir pluginsDir = QDir(qApp->applicationDirPath());
|
||
if (pluginsDir.cd("srsplugins\\DemModel"))
|
||
{
|
||
QString strConfigPath = pluginsDir.absoluteFilePath("dem_config.ini");
|
||
QFile f(strConfigPath);
|
||
if (f.exists())
|
||
{
|
||
WriteConfigPaths(strConfigPath);
|
||
f.close();
|
||
}
|
||
}
|
||
|
||
myWidget->close();
|
||
myWidget = nullptr;
|
||
if (mWorkThread != nullptr)
|
||
{
|
||
mWorkThread->quit();
|
||
mWorkThread->wait();//调用wait后先调用finished信号对应的槽函数,执行完成后再往下走
|
||
mWorkThread = nullptr;//mWorkThread, &QThread::finished, mWorkThread, &QObject::deleteLater,不需要delete
|
||
mWorker = nullptr;//mWorkThread, &QThread::finished, mWorker, &QObject::deleteLater
|
||
}
|
||
});
|
||
connect(ui.pbtMasked, &QPushButton::pressed, this, &DataFilling::chooseMaskedSlope);
|
||
connect(ui.pbtOutFill, &QPushButton::pressed, this, &DataFilling::chooseOutFill);
|
||
|
||
connect(ui.pushButton_ok, &QPushButton::pressed, this, &DataFilling::readAndStart);
|
||
connect(ui.pushButton_cancel, &QPushButton::pressed, this, &DataFilling::pbCancel);
|
||
|
||
ui.progressBar->setTextVisible(true);
|
||
ui.progressBar->setRange(0, 100);
|
||
|
||
ui.pbtMasked->setFocus();
|
||
|
||
ui.lineRectangleScale->setValidator(new QRegExpValidator(QRegExp("^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$")));
|
||
ui.lineExpandSize->setValidator(new QIntValidator(0, 999, this));
|
||
ui.lineRectangleScale->setText("0.1");
|
||
ui.lineExpandSize->setText("3");
|
||
|
||
QFile qssFile(":/DEM_Fill/DEM_Fill.qss");
|
||
qssFile.open(QFile::ReadOnly); //以只读方式打开
|
||
if (qssFile.isOpen())
|
||
{
|
||
QString qss = QLatin1String(qssFile.readAll());
|
||
myWidget->setStyleSheet(qss);
|
||
qssFile.close();
|
||
}
|
||
else
|
||
qDebug() << "无法打开文件";
|
||
|
||
QDir pluginsDir = QDir(qApp->applicationDirPath());
|
||
if (pluginsDir.cd("srsplugins\\DemModel"))
|
||
{
|
||
QString strConfigPath = pluginsDir.absoluteFilePath("dem_config.ini");
|
||
QFile f(strConfigPath);
|
||
if (f.exists())
|
||
{
|
||
ReadConfigHistoryPaths(strConfigPath);
|
||
f.close();
|
||
}
|
||
}
|
||
|
||
if (showWin)
|
||
myWidget->show();
|
||
|
||
return myWidget;
|
||
}
|
||
|
||
void DataFilling::startWorkThread()
|
||
{
|
||
if (mWorker != nullptr)
|
||
{
|
||
return;
|
||
}
|
||
mWorkThread = new QThread();
|
||
mWorker = new WorkThreadObject();
|
||
mWorker->moveToThread(mWorkThread);
|
||
connect(mWorkThread, &QThread::finished, mWorkThread, &QObject::deleteLater);
|
||
connect(mWorkThread, &QThread::finished, mWorker, &QObject::deleteLater);
|
||
connect(mWorker, &WorkThreadObject::sendMaskedTiff, this, &DataFilling::openResultData);
|
||
|
||
connect(mWorker, &WorkThreadObject::process, myWidget, [=](int value) {
|
||
ui.progressBar->setValue(value);
|
||
if (value == 100)
|
||
{
|
||
QMessageBox mess(QMessageBox::Information,
|
||
QString::fromLocal8Bit("填补结束"),
|
||
QString::fromLocal8Bit("填补结果文件夹:\n") + outPath);
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
mess.setStandardButtons(QMessageBox::Yes);
|
||
mess.button(QMessageBox::StandardButton::Yes)->setText(QString::fromLocal8Bit("确认"));
|
||
//mess.setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||
int result = mess.exec();
|
||
pbCancel();
|
||
}
|
||
});
|
||
connect(this, &DataFilling::startDataFill, mWorker, &WorkThreadObject::runFillingWork);
|
||
|
||
mWorkThread->start();
|
||
}
|
||
|
||
void DataFilling::chooseMaskedSlope()
|
||
{
|
||
QString dirDom = QFileDialog::getExistingDirectory(ui.pbtMasked, QString::fromLocal8Bit("选择输入裁剪后的DEM文件夹"), "");
|
||
if (dirDom != "")
|
||
ui.lineMasked->setText(dirDom);
|
||
}
|
||
void DataFilling::chooseOutFill()
|
||
{
|
||
QString dirDom = QFileDialog::getExistingDirectory(ui.pbtOutFill, QString::fromLocal8Bit("选择输出数据填补结果文件夹"), "");
|
||
if (dirDom != "")
|
||
ui.lineOutFill->setText(dirDom);
|
||
}
|
||
void DataFilling::readAndStart()
|
||
{
|
||
QString in_masked = ui.lineMasked->text();
|
||
QString out_filled = ui.lineOutFill->text();
|
||
QString scale = ui.lineRectangleScale->text();
|
||
QString size = ui.lineExpandSize->text();
|
||
if (in_masked == "" || out_filled == "" || scale == "" || size == "")
|
||
{
|
||
QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("请检查输入输出路径"));
|
||
mess.setWindowFlags(Qt::Drawer);
|
||
int result = mess.exec();
|
||
return;
|
||
}
|
||
outPath = out_filled;
|
||
|
||
ui.progressBar->setValue(0);
|
||
|
||
if (mWorkThread == nullptr)
|
||
{
|
||
qDebug() << "--startThread";
|
||
startWorkThread();
|
||
}
|
||
emit startDataFill(in_masked, out_filled, scale, size);
|
||
}
|
||
|
||
void DataFilling::ReadConfigHistoryPaths(QString strPath)
|
||
{
|
||
QSettings configIni(strPath, QSettings::IniFormat);
|
||
|
||
//打开标题为:[DemFill] 的组
|
||
configIni.beginGroup("DemFill");
|
||
|
||
ui.lineMasked->setText(configIni.value("MaskedFiles").toString());
|
||
ui.lineOutFill->setText(configIni.value("FilledFiles").toString());
|
||
|
||
configIni.endGroup();//关闭组
|
||
}
|
||
void DataFilling::WriteConfigPaths(QString strPath)
|
||
{
|
||
QSettings configIni(strPath, QSettings::IniFormat);
|
||
configIni.setIniCodec("utf-8");
|
||
//打开标题为:[DemFill] 的组
|
||
configIni.beginGroup("DemFill");
|
||
|
||
//更新输入模型路径
|
||
QString temp = ui.lineMasked->text();
|
||
if (temp != "")
|
||
configIni.setValue("MaskedFiles", temp);
|
||
//更新输入DOM路径
|
||
temp = ui.lineOutFill->text();
|
||
if (temp != "")
|
||
configIni.setValue("FilledFiles", temp);
|
||
|
||
configIni.endGroup();//关闭组
|
||
}
|
||
|
||
void DataFilling::pbCancel()
|
||
{
|
||
delete myWidget;//调起&QDialog::destroyed
|
||
}
|
||
|
||
void DataFilling::openResultData(QStringList string_list)
|
||
{
|
||
if (string_list.isEmpty())
|
||
return;
|
||
QgsRasterLayer* rastLayer;
|
||
QgsVectorLayer* vecLayer;
|
||
for each (QString layerPath in string_list)
|
||
{
|
||
QFileInfo fileInfo(layerPath);
|
||
QString layerBaseName = fileInfo.baseName(); // 图层名称
|
||
if ("tif" == fileInfo.suffix() || "tiff" == fileInfo.suffix())
|
||
{
|
||
rastLayer = new QgsRasterLayer(fileInfo.filePath(), layerPath, "gdal");
|
||
if (!rastLayer)
|
||
return;
|
||
QgsMapLayer* mapLayer = rastLayer;
|
||
QgsRectangle myRectangle;
|
||
//rastLayer->setContrastEnhancement(QgsContrastEnhancement::StretchToMinimumMaximum
|
||
// , QgsRasterMinMaxOrigin::StdDev, myRectangle);
|
||
QList<QgsMapLayer*> mapLayers;
|
||
mapLayers << mapLayer;
|
||
QgsProject::instance()->addMapLayers(mapLayers);
|
||
//zoomToSelectedLayer(mapLayer);
|
||
}
|
||
else if ("shp" == fileInfo.suffix())
|
||
{
|
||
vecLayer = new QgsVectorLayer(fileInfo.filePath(), layerPath);
|
||
if (!vecLayer)
|
||
return;
|
||
QgsMapLayer* mapLayer = vecLayer;
|
||
QList<QgsMapLayer*> mapLayers;
|
||
mapLayers << mapLayer;
|
||
QgsProject::instance()->addMapLayers(mapLayers);
|
||
}
|
||
}
|
||
}
|