#include "DEM_Fill.h" #include #include #include 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 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 mapLayers; mapLayers << mapLayer; QgsProject::instance()->addMapLayers(mapLayers); } } }