#include "LandslidePredict.h" #include #include #include LandslidePredict::LandslidePredict() { //ui.setupUi(this); } QString LandslidePredict::PannelName() { return QString::fromLocal8Bit("地质模块"); } QString LandslidePredict::CategoryName() { return QString::fromLocal8Bit("地质模块"); } QString LandslidePredict::EnglishName() { return QString::fromLocal8Bit("LandslidePredict"); } QString LandslidePredict::ChineseName() { return QString::fromLocal8Bit("滑坡识别"); } QString LandslidePredict::Information() { return QString::fromLocal8Bit("滑坡识别"); } QString LandslidePredict::IconPath() { return QString(":/LandslidePredict/resources/landslide.svg"); } QWidget* LandslidePredict::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(":/LandslidePredict/resources/landslide.svg")); myWidget->setAttribute(Qt::WA_QuitOnClose, false); myWidget->setAttribute(Qt::WA_DeleteOnClose); connect(myWidget, &QDialog::destroyed, this, [=]() { qDebug() << "----Landslide Predict window close----"; QDir pluginsDir = QDir(qApp->applicationDirPath()); if (pluginsDir.cd("srsplugins\\SldModel")) { QString strConfigPath = pluginsDir.absoluteFilePath("sld_config.ini"); QFile f(strConfigPath); if (f.exists()) { WriteConfigPaths(strConfigPath); f.close(); } } if (mWorkThread != nullptr) { mWorkThread->requestInterruption();//请求线程中断 mWorkThread->quit(); mWorkThread->wait();//调用wait后先调用finished信号对应的槽函数,执行完成后再往下走 mWorkObject->on_cancel(); mWorkThread = nullptr;//mWorkThread, &QThread::finished, mWorkThread, &QObject::deleteLater,不需要delete mWorkObject = nullptr;//mWorkThread, &QThread::finished, mWorker, &QObject::deleteLater } myWidget->close(); myWidget = nullptr; qDebug() << "--destroyed"; }); connect(ui.pbtInModel, &QPushButton::clicked, this, &LandslidePredict::chooseInModel); connect(ui.pbtInDataset, &QPushButton::clicked, this, &LandslidePredict::chooseInDataset); connect(ui.pbtPreResult, &QPushButton::clicked, this, &LandslidePredict::chooseResultPath); connect(ui.pushButton_ok, &QPushButton::clicked, this, &LandslidePredict::readAndStart); connect(ui.pushButton_cancel, &QPushButton::clicked, this, &LandslidePredict::pbCancel); ui.pbtInModel->setFocus(); ui.progressBar->setTextVisible(true); ui.progressBar->setRange(0, 100); QFile qssFile(":/LandslidePredict/LandslidePredict.qss"); qssFile.open(QFile::ReadOnly); //以只读方式打开 if (qssFile.isOpen()) { QString qss = QLatin1String(qssFile.readAll()); myWidget->setStyleSheet(qss); qssFile.close(); } else qDebug() << "no qssFile"; QDir pluginsDir = QDir(qApp->applicationDirPath()); if (pluginsDir.cd("srsplugins\\SldModel")) { QString strConfigPath = pluginsDir.absoluteFilePath("sld_config.ini"); QFile f(strConfigPath); if (f.exists()) { ReadConfigHistoryPaths(strConfigPath); f.close(); } } if (showWin) myWidget->show(); return myWidget; } void LandslidePredict::startWorkThread() { if (mWorkObject != nullptr) return; mWorkThread = new QThread(); mWorkObject = new WorkObject(); mWorkObject->moveToThread(mWorkThread); connect(mWorkThread, &QThread::finished, mWorkThread, &QObject::deleteLater); connect(mWorkThread, &QThread::finished, mWorkObject, &QObject::deleteLater); connect(mWorkObject, &WorkObject::progress, myWidget, [=](int value) {ui.progressBar->setValue(value); }); connect(mWorkObject, &WorkObject::preFinished, this, &LandslidePredict::finished); connect(mWorkObject, &WorkObject::addShpDataToMap, this, &LandslidePredict::openResultData); connect(this, &LandslidePredict::startTiffToShp, mWorkObject, &WorkObject::runFormatConvert); connect(this, &LandslidePredict::start, mWorkObject, &WorkObject::runPredictWork); mWorkThread->start(); } void LandslidePredict::ReadConfigHistoryPaths(QString strPath) { QSettings configIni(strPath, QSettings::IniFormat); //打开标题为:[SldPredict] 的组 configIni.beginGroup("SldPredict"); ui.lineInDataset->setText(configIni.value("SrcDom").toString()); ui.linePreResult->setText(configIni.value("PredictResult").toString()); configIni.endGroup();//关闭组 } void LandslidePredict::WriteConfigPaths(QString strPath) { QSettings configIni(strPath, QSettings::IniFormat); configIni.setIniCodec("utf-8"); //打开标题为:[SldPredict] 的组 configIni.beginGroup("SldPredict"); //更新输入DOM路径 QString temp = ui.lineInDataset->text(); if (temp != "") configIni.setValue("SrcDom", temp); //更新输出结果路径 temp = ui.linePreResult->text(); if (temp != "") configIni.setValue("PredictResult", temp); configIni.endGroup();//关闭组 } void LandslidePredict::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); } } } void LandslidePredict::readAndStart() { QString dirModel = ui.lineInModel->text(); QString dirDataset = ui.lineInDataset->text(); QString dirPRE = ui.linePreResult->text(); ui.progressBar->setValue(0); if (dirModel == "" || dirDataset == "" || dirPRE == "") { QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("请检查输入输出文件或路径")); mess.setWindowFlags(Qt::Drawer); int result = mess.exec(); return; } if (mWorkThread == nullptr) { qDebug() << "--startThread"; startWorkThread(); } ui.label_progress->setText(QString::fromLocal8Bit("预测进度:")); emit start(dirModel, dirDataset, dirPRE); } void LandslidePredict::pbCancel() { qDebug() << "--pbtCancel"; delete myWidget;//调起&QDialog::destroyed } void LandslidePredict::chooseInModel() { QString dirModel = QFileDialog::getOpenFileName(ui.pbtInModel, QString::fromLocal8Bit("选择模型文件"), "", "*.pth"); if (dirModel != "") ui.lineInModel->setText(dirModel); } void LandslidePredict::chooseInDataset() { QString dirInDataset = QFileDialog::getExistingDirectory(ui.pbtInDataset, QString::fromLocal8Bit("选择输入预测数据路径"), ""); if (dirInDataset != "") ui.lineInDataset->setText(dirInDataset); } void LandslidePredict::chooseResultPath() { QString dirPre = QFileDialog::getExistingDirectory(ui.pbtPreResult, QString::fromLocal8Bit("选择预测结果输出文件路径"), ""); if (dirPre != "") ui.linePreResult->setText(dirPre); } //预测结束,转矢量 void LandslidePredict::finished() { QMessageBox mess(QMessageBox::NoIcon, QString::fromLocal8Bit("滑坡识别结束"), QString::fromLocal8Bit("将对如下路径中结果进行转矢量处理:\n") + ui.linePreResult->text(), QMessageBox::Ok, NULL); mess.setWindowFlags(Qt::Drawer); mess.setButtonText(QMessageBox::Ok, QString::fromLocal8Bit("确认")); int result = mess.exec(); switch (result) { case QMessageBox::Ok: emit startTiffToShp(ui.linePreResult->text(), ui.lineInDataset->text()); ui.label_progress->setText(QString::fromLocal8Bit("转矢量进度:")); ui.progressBar->setValue(0); break; default: break; } } void WorkObject::runPredictWork(QString inModel, QString inDataset, QString outPre) { QDir pluginsDir = QDir(qApp->applicationDirPath()); if (!pluginsDir.cd("models\\envs")) { qDebug() << "no folder models\\envs"; return; } QString exeDirName = pluginsDir.absoluteFilePath("predict_3c_landslide.exe"); QString strModel = " --model_path " + inModel; QString strData = " --dom_path " + inDataset + "/"; QString strPre = " --pre_path " + outPre + "/"; QString ss = exeDirName + strModel + strData + strPre; qDebug() << ss; QProcess* pProces = new QProcess(this); connect(pProces, SIGNAL(readyReadStandardOutput()), this, SLOT(on_read())); pProces->start(ss); } void WorkObject::on_read() { mProcess = (QProcess*)sender(); QString output = QString::fromLocal8Bit(mProcess->readAllStandardOutput()); if (output.toFloat() > 0) { qDebug() << "exe out:" << output.toFloat(); emit progress(output.toFloat()); if (output.toFloat() == 100) emit preFinished(); } else qDebug() << "Unresolved exe out:" << output; } void WorkObject::on_cancel() { if (mProcess == nullptr) { qDebug() << "--mProces null"; } else { QString KillStr = "taskkill /f /im predict_3c_landslide.exe"; mProcess->startDetached(KillStr); qDebug() << "--kill Proces"; } } void WorkObject::runFormatConvert(QString pre, QString dataset) { QDir dir(pre); QStringList nameFilters; nameFilters << "*.tif" << "*.tiff"; QStringList pre_tiff_files = dir.entryList(nameFilters, QDir::Files | QDir::Readable, QDir::Name); int list_len = pre_tiff_files.size(); for (int i = 0; i < list_len; i++) { emit progress(float(i) / float(list_len) * 95); qDebug() << "TiffToShp progress:" << float(i) / float(list_len) * 100; QString file_path = pre + "\\" + pre_tiff_files[i]; QString dsm_path = dataset + "\\" + pre_tiff_files[i]; string path_preTiff = file_path.toStdString(); string pathPureName = path_preTiff.substr(0, path_preTiff.rfind(".")); string shp_path = pathPureName + ".shp"; //调起栅格转矢量 img2shp cc; QtGDALProcessBar* gb = new QtGDALProcessBar(); bool returnval = cc.ImagePolygonize(path_preTiff.c_str(), shp_path.c_str(), "ESRI Shapefile", 1, gb, gb); if (returnval == true) { QStringList list; list << dsm_path << QString::fromStdString(shp_path); emit addShpDataToMap(list); } else qDebug() << "ImagePolygonize fail"; } emit progress(100); }