2 Commits

Author SHA1 Message Date
keyeslll ef3f64410d 添加项目文件。 2023-03-13 16:17:55 +08:00
keyeslll 57d01cc7fb 添加 .gitignore 和 .gitattributes。 2023-03-13 16:17:52 +08:00
21 changed files with 1066 additions and 1212 deletions
-364
View File
@@ -1,364 +0,0 @@
#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);
}
}
}
-6
View File
@@ -1,6 +0,0 @@
<RCC>
<qresource prefix="/DEM_Fill">
<file>resources/fill.svg</file>
<file>DEM_Fill.qss</file>
</qresource>
</RCC>
-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="26" height="26" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="36" height="36" rx="3" fill="none" stroke="#2c2c2c" stroke-width="3" stroke-linecap="butt" stroke-linejoin="round"/><rect x="14" y="14" width="20" height="20" fill="none" stroke="#2c2c2c" stroke-width="3" stroke-linecap="butt" stroke-linejoin="round"/><path d="M34 23L23 34" stroke="#2c2c2c" stroke-width="3" stroke-linecap="butt" stroke-linejoin="round"/><path d="M25 14L14 25" stroke="#2c2c2c" stroke-width="3" stroke-linecap="butt" stroke-linejoin="round"/><path d="M34 14L14 34" stroke="#2c2c2c" stroke-width="3" stroke-linecap="butt" stroke-linejoin="round"/><path d="M14 22V34H26" stroke="#2c2c2c" stroke-width="3" stroke-linecap="butt" stroke-linejoin="round"/><path d="M22 14H34V26" stroke="#2c2c2c" stroke-width="3" stroke-linecap="butt" stroke-linejoin="round"/></svg>

Before

Width:  |  Height:  |  Size: 936 B

+5 -5
View File
@@ -1,22 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32126.315
VisualStudioVersion = 16.0.32630.194
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DEM_Fill", "DEM_Fill\DEM_Fill.vcxproj", "{32F04C81-EC93-432F-9B60-0B92B5FCC5C5}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LandslidePredict", "LandslidePredict\LandslidePredict.vcxproj", "{ABE55CAB-C9A0-4D11-AF67-DEFEF07F3DA5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{32F04C81-EC93-432F-9B60-0B92B5FCC5C5}.Release|x64.ActiveCfg = Release|x64
{32F04C81-EC93-432F-9B60-0B92B5FCC5C5}.Release|x64.Build.0 = Release|x64
{ABE55CAB-C9A0-4D11-AF67-DEFEF07F3DA5}.Release|x64.ActiveCfg = Release|x64
{ABE55CAB-C9A0-4D11-AF67-DEFEF07F3DA5}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D6C86E29-E4F8-449B-838C-C7B217220096}
SolutionGuid = {A9D5438D-7ABE-4CBF-BEAE-6F3FE0CBEB3F}
EndGlobalSection
EndGlobal
+98
View File
@@ -0,0 +1,98 @@
#pragma once
#include <iostream>
using namespace std;
/**
* @brief 进度条基类
*
* 提供进度条基类接口,来反映当前算法的进度值
*/
//源码:class IMGALG_API CProcessBase
class CProcessBase
{
public:
/**
* @brief 构造函数
*/
CProcessBase()
{
m_dPosition = 0.0;
m_iStepCount = 100;
m_iCurStep = 0;
m_bIsContinue = true;
}
/**
* @brief 析构函数
*/
virtual ~CProcessBase() {}
/**
* @brief 设置进度信息
* @param pszMsg 进度信息
*/
virtual void SetMessage(const char* pszMsg) = 0;
/**
* @brief 设置进度值
* @param dPosition 进度值
* @return 返回是否取消的状态,true为不取消,false为取消
*/
virtual bool SetPosition(double dPosition) = 0;
/**
* @brief 进度条前进一步,返回true表示继续,false表示取消
* @return 返回是否取消的状态,true为不取消,false为取消
*/
virtual bool StepIt() = 0;
/**
* @brief 设置进度个数
* @param iStepCount 进度个数
*/
virtual void SetStepCount(int iStepCount)
{
ReSetProcess();
m_iStepCount = iStepCount;
}
/**
* @brief 获取进度信息
* @return 返回当前进度信息
*/
string GetMessage()
{
return m_strMessage;
}
/**
* @brief 获取进度值
* @return 返回当前进度值
*/
double GetPosition()
{
return m_dPosition;
}
/**
* @brief 重置进度条
*/
void ReSetProcess()
{
m_dPosition = 0.0;
m_iStepCount = 100;
m_iCurStep = 0;
m_bIsContinue = true;
}
/*! 进度信息 */
string m_strMessage;
/*! 进度值 */
double m_dPosition;
/*! 进度个数 */
int m_iStepCount;
/*! 进度当前个数 */
int m_iCurStep;
/*! 是否取消,值为false时表示计算取消 */
bool m_bIsContinue;
};
+383
View File
@@ -0,0 +1,383 @@
#include "LandslidePredict.h"
#include <qgsrasterlayer.h>
#include <qgsvectorlayer.h>
#include <qgsmapcanvas.h>
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<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);
}
}
}
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);
}
@@ -1,54 +1,55 @@
#pragma once
#include <QtWidgets/QDialog>
#include "ui_LandslidePredict.h"
#include <QProcess>
#include <QThread>
#include <QFile>
#include <QIcon>
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <QStringList>
#include <QIntValidator>
#include <QRegExpValidator>
#include "SrsMainPluginInterFace.h"
#include "ui_DEM_Fill.h"
#include <string>
#include <iostream>
#include "im2shp.h"
using namespace std;
class WorkThreadObject :public QObject
class WorkObject :public QObject
{
Q_OBJECT
public:
int run_cmd(const char* cmd);
public slots:
void runPredictWork(QString inModel, QString inDataset, QString outPre);
void on_read();
void on_cancel();
void runFormatConvert(QString pre, QString dataset);
signals:
void process(int value);
void sendMaskedTiff(QStringList maskedData);
public slots:
void runFillingWork(QString in_masked, QString out_filled, QString scale, QString size);
void readProcessStandardOutput();
void progress(int value);
void preFinished();
void addShpDataToMap(QStringList list);
private:
QProcess* mProcess = nullptr;
QString outTiffPath, tifflinear, tiffcubic;
};
class DataFilling : public SrsMainInterface
class LandslidePredict : public SrsMainInterface
{
Q_OBJECT
Q_INTERFACES(SrsMainInterface)
Q_PLUGIN_METADATA(IID MainInterface_iid)
public:
DataFilling();
LandslidePredict();
virtual QString PannelName() override;
virtual QString CategoryName() override;
@@ -66,27 +67,28 @@ public:
//保存本次打开的路径到json文件
void WriteConfigPaths(QString strPath);
void openResultData(QStringList string_list);
public slots:
//pushbutton_OK
void readAndStart();
void pbCancel();
void chooseMaskedSlope();
void chooseOutFill();
void chooseInModel();
void chooseInDataset();
void chooseResultPath();
void openResultData(QStringList string_list);
void finished();
signals:
void startDataFill(QString in_masked, QString out_filled, QString scale, QString size);
void start(QString inModel, QString inDataset, QString outPre);
void startTiffToShp(QString pre, QString dataset);
private:
Ui::DEM_FillClass ui;
Ui::LandslidePredictClass ui;
QDialog* myWidget = nullptr;
QThread* mWorkThread = nullptr;
WorkThreadObject* mWorker = nullptr;
WorkObject* mWorkObject = nullptr;
QString outPath;
};
+6
View File
@@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/LandslidePredict">
<file>resources/landslide.svg</file>
<file>LandslidePredict.qss</file>
</qresource>
</RCC>
@@ -15,7 +15,6 @@ QProgressBar#progressBar QLineEdit {
background-color:transparent;
}
QLabel{
color:black;
font-family:'Microsoft YaHei';
@@ -23,7 +22,7 @@ QLabel{
}
/*----QPushButtonÑùʽ±í*/
#pushButton_ok, #pushButton_cancel, #pbtMasked, #pbtOutFill{
#pushButton_ok, #pushButton_cancel, #pbtInModel, #pbtInDataset , #pbtPreResult{
font-family:'Microsoft YaHei';
font-size:12px;
background-color: #ffffff;
@@ -32,37 +31,38 @@ QLabel{
border-radius: 5px;
max-height:20px;
}
#pushButton_ok:hover, #pushButton_cancel:hover, #pbtMasked:hover, #pbtOutFill:hover{
#pushButton_ok, #pushButton_cancel{
min-width:36px;
}
#pushButton_ok:hover, #pushButton_cancel:hover, #pbtInModel:hover, #pbtInDataset:hover,#pbtPreResult:hover{
background-color: #ecf5ff;
color: #409eff;
}
#pushButton_ok:pressed, #pushButton_cancel:pressed, #pbtMasked:pressed, #pbtOutFill:pressed{
#pushButton_ok:pressed, #pushButton_cancel:pressed, #pbtInModel:pressed, #pbtInDataset:pressed,#pbtPreResult:pressed{
border: 1px solid #3a8ee6;
color: #409eff;
}
#pushButton_ok:checked, #pushButton_cancel:checked, #pbtMasked:checked, #pbtOutFill:checked{
#pushButton_ok:checked, #pushButton_cancel:checked, #pbtInModel:checked, #pbtInDataset:checked,#pbtPreResult:checked{
border: 1px solid #3a8ee6;
color: #409eff;
}
#pushButton_ok:focus, #pushButton_cancel:focus, #pbtMasked:focus, #pbtOutFill:focus{
#pushButton_ok:focus, #pushButton_cancel:focus, #pbtInModel:focus, #pbtInDataset:focus,#pbtPreResult:focus{
border: 1px solid #3a8ee6;
color: #409eff;
outline: none;
}
#pushButton_ok, #pushButton_cancel{
min-width:36px;
}
/*----QLineEditÑùʽ*/
#lineMasked, #lineOutFill,#lineRectangleScale,#lineExpandSize{
#lineInModel, #lineInDataset, #linePreResult{
border:0px;
border-bottom: 1px solid #B3B3B3;
font-family:'Microsoft YaHei';
font-size:12px;
background-color:transparent;
}
#lineMasked:hover, #lineOutFill:hover,#lineRectangleScale:hover,#lineExpandSize:hover{
#lineInModel:hover, #lineInDataset:hover, #linePreResult:hover{
border-bottom: 2px solid #66A3FF;
}
#lineMasked:focus, #lineOutFill:focus,#lineRectangleScale:focus,#lineExpandSize:focus{
#lineInModel:focus, #lineInDataset:focus, #linePreResult:focus{
border-bottom: 2px solid #7666FF;
}
@@ -1,165 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DEM_FillClass</class>
<widget class="QDialog" name="DEM_FillClass">
<class>LandslidePredictClass</class>
<widget class="QDialog" name="LandslidePredictClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>250</height>
<width>460</width>
<height>270</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>250</height>
<width>460</width>
<height>270</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>250</height>
<width>460</width>
<height>270</height>
</size>
</property>
<property name="windowTitle">
<string>DEM_Fill</string>
</property>
<property name="windowIcon">
<iconset resource="DEM_Fill.qrc">
<normaloff>:/DEM_Fill/resources/fill.svg</normaloff>:/DEM_Fill/resources/fill.svg</iconset>
<string>LandslidePredict</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>输入裁剪后的DEM文件</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="lineMasked"/>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pbtMasked">
<property name="minimumSize">
<size>
<width>75</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>选择文件夹</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>输出数据填补结果文件</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLineEdit" name="lineOutFill"/>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="pbtOutFill">
<property name="minimumSize">
<size>
<width>75</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>选择文件夹</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>外接矩形外扩比例</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineRectangleScale"/>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>空洞外扩像素</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineExpandSize"/>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>81</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
<item row="2" column="1">
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_progress">
<property name="text">
<string>进度:</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -173,19 +57,13 @@
</item>
<item>
<widget class="QPushButton" name="pushButton_ok">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>确</string>
<string>确</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -194,7 +72,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
<width>13</width>
<width>10</width>
<height>20</height>
</size>
</property>
@@ -209,28 +87,130 @@
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
</widget>
<item row="0" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>输入模型文件路径</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineInModel"/>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pbtInModel">
<property name="minimumSize">
<size>
<width>75</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>打开文件</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>输入预测数据路径</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineInDataset"/>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pbtInDataset">
<property name="minimumSize">
<size>
<width>75</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>打开文件夹</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>预测结果文件路径</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="linePreResult"/>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pbtPreResult">
<property name="minimumSize">
<size>
<width>75</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>打开文件夹</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>lineMasked</tabstop>
<tabstop>pbtMasked</tabstop>
<tabstop>lineOutFill</tabstop>
<tabstop>pbtOutFill</tabstop>
<tabstop>lineRectangleScale</tabstop>
<tabstop>lineExpandSize</tabstop>
<tabstop>lineInModel</tabstop>
<tabstop>pbtInModel</tabstop>
<tabstop>lineInDataset</tabstop>
<tabstop>pbtInDataset</tabstop>
<tabstop>linePreResult</tabstop>
<tabstop>pbtPreResult</tabstop>
<tabstop>pushButton_ok</tabstop>
<tabstop>pushButton_cancel</tabstop>
</tabstops>
<resources>
<include location="DEM_Fill.qrc"/>
<include location="LandslidePredict.qrc"/>
</resources>
<connections/>
</ui>
@@ -7,9 +7,9 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{32F04C81-EC93-432F-9B60-0B92B5FCC5C5}</ProjectGuid>
<ProjectGuid>{ABE55CAB-C9A0-4D11-AF67-DEFEF07F3DA5}</ProjectGuid>
<Keyword>QtVS_v304</Keyword>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0</WindowsTargetPlatformVersion>
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@@ -22,7 +22,7 @@
<Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
<QtInstall>qt5.11.2</QtInstall>
<QtInstall>QtQgis</QtInstall>
<QtModules>core;gui;widgets</QtModules>
<QtBuildConfig>release</QtBuildConfig>
</PropertyGroup>
@@ -37,13 +37,13 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<TargetName>dem4-$(ProjectName)</TargetName>
<IncludePath>D:\qgis\osgeo4w\include;D:\qgis\osgeo4w\apps\Qt5\include;D:\qgis\osgeo4w\apps\qgis_build_sdk\include;D:\qgis\osgeo4w\apps\Qt5\include\QtXml;$(IncludePath)</IncludePath>
<LibraryPath>D:\qgis\osgeo4w\lib;D:\qgis\osgeo4w\apps\Qt5\lib;D:\qgis\osgeo4w\apps\qgis_build_sdk\lib;$(LibraryPath)</LibraryPath>
<IncludePath>D:\qgis\osgeo4w\include;D:\qgis\osgeo4w\apps\qgis_build_sdk\include;D:\qgis\osgeo4w\apps\Qt5\include;D:\qgis\osgeo4w\apps\Qt5\include\QtXml;$(IncludePath)</IncludePath>
<LibraryPath>D:\qgis\osgeo4w\lib;D:\qgis\osgeo4w\apps\qgis_build_sdk\lib;D:\qgis\osgeo4w\apps\Qt5\lib;$(LibraryPath)</LibraryPath>
<TargetName>landslide3_pre</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<AdditionalDependencies>qgis_gui.lib;qgis_analysis.lib;qgis_core.lib;qgis_native.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>gdal_i.lib;qgis_gui.lib;qgis_analysis.lib;qgis_core.lib;qgis_native.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
@@ -55,25 +55,30 @@
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<QtRcc Include="DEM_Fill.qrc" />
<QtUic Include="DEM_Fill.ui" />
<QtMoc Include="DEM_Fill.h" />
<ClCompile Include="DEM_Fill.cpp" />
<ClCompile Include="QtGDALProcessBar.cpp" />
<QtRcc Include="LandslidePredict.qrc" />
<QtUic Include="LandslidePredict.ui" />
<QtMoc Include="LandslidePredict.h" />
<ClCompile Include="im2shp.cpp" />
<ClCompile Include="LandslidePredict.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="SrsMainPluginInterFace.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="x64\Release\uic\ui_DEM_Fill.h" />
<ClInclude Include="CProcessBase.h" />
<ClInclude Include="im2shp.h" />
<QtMoc Include="QtGDALProcessBar.h" />
<ClInclude Include="x64\Release\uic\ui_LandslidePredict.h" />
</ItemGroup>
<ItemGroup>
<None Include="DEM_Fill.qss" />
<None Include="LandslidePredict.qss" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
@@ -3,7 +3,7 @@
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
@@ -23,16 +23,16 @@
</Filter>
</ItemGroup>
<ItemGroup>
<QtRcc Include="DEM_Fill.qrc">
<QtRcc Include="LandslidePredict.qrc">
<Filter>Resource Files</Filter>
</QtRcc>
<QtUic Include="DEM_Fill.ui">
<QtUic Include="LandslidePredict.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtMoc Include="DEM_Fill.h">
<QtMoc Include="LandslidePredict.h">
<Filter>Header Files</Filter>
</QtMoc>
<ClCompile Include="DEM_Fill.cpp">
<ClCompile Include="LandslidePredict.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@@ -40,19 +40,34 @@
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="im2shp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="QtGDALProcessBar.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="SrsMainPluginInterFace.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="QtGDALProcessBar.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<ClInclude Include="x64\Release\uic\ui_DEM_Fill.h">
<ClInclude Include="x64\Release\uic\ui_LandslidePredict.h">
<Filter>Form Files</Filter>
</ClInclude>
<ClInclude Include="CProcessBase.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="im2shp.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="DEM_Fill.qss">
<None Include="LandslidePredict.qss">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
+100
View File
@@ -0,0 +1,100 @@
#include "QtGDALProcessBar.h"
#include <QCoreApplication>
QtGDALProcessBar::QtGDALProcessBar(QWidget *parent)
: QProgressBar(parent)
{
//ui.setupUi(this);
this->setTextVisible(true);
m_dPosition = 0.0;
m_iStepCount = 100;
m_iCurStep = 0;
}
QtGDALProcessBar::~QtGDALProcessBar()
{
}
/**
* @brief 设置进度信息
* @param pszMsg 进度信息
*/
void QtGDALProcessBar::SetMessage(const char* pszMsg)
{
if (pszMsg != NULL)
{
m_strMessage = pszMsg;
//setLabelText(QString(pszMsg));
}
}
/**
* @brief 设置进度值
* @param dPosition 进度值
*/
bool QtGDALProcessBar::SetPosition(double dPosition)
{
m_dPosition = dPosition;
//cout << "m_dPosition " << m_dPosition << endl;
//current_value = value();
int temp_value = int(m_start_value +std::min(100u, (uint)(m_dPosition * 100.0 )) * m_scale);
setValue(temp_value);
//setFormat(tr("%1%").arg(temp_value));
//cout << "StepIt " << temp_value << "\t" << "current_value" << int(m_start_value + temp_value * m_scale) << endl;
//QCoreApplication::instance()->processEvents();
//this->update();
//if (this->wasCanceled())
// return false;
return true;
}
bool QtGDALProcessBar::SetStartEndValue(int i_start_value, int i_end_value)
{
if (i_end_value< i_start_value )
{
return false;
}
else
{
m_start_value = i_start_value;
m_end_value = i_end_value;
m_scale = (m_end_value - m_start_value) / 100.0;
return true;
}
}
/**
* @brief 进度条前进一步,返回false表示终止操作
*/
bool QtGDALProcessBar::StepIt()
{
m_iCurStep++;
m_dPosition = m_iCurStep * 1.0 / m_iStepCount;
//current_value = value();
int temp_value = std::min(100u, (uint)(m_dPosition * 100.0));
setValue(int(m_start_value + temp_value * m_scale));
//setFormat(QString("当前进度为:%1%").arg(temp_value));
//cout << "StepIt " << temp_value <<"\t"<<"current_value"<< current_value << endl;
//QCoreApplication::instance()->processEvents();
//if (this->wasCanceled())
// return false;
return true;
}
void QtGDALProcessBar::updateProgress(int step)
{
this->setValue(step);
//this->update();
//cout << "updateProgress " << step << endl;
//QCoreApplication::instance()->processEvents();
}
+62
View File
@@ -0,0 +1,62 @@
#pragma once
#include <QProgressBar>
#include "CProcessBase.h"
class QtGDALProcessBar : public QProgressBar,public CProcessBase
{
Q_OBJECT
public:
QtGDALProcessBar(QWidget *parent = Q_NULLPTR);
~QtGDALProcessBar();
/**
* @brief 设置进度信息
* @param pszMsg 进度信息
*/
void SetMessage(const char* pszMsg);
/**
* @brief 设置进度值
* @param dPosition 进度值
*/
bool SetPosition(double dPosition);
/// <summary>
/// 设置进度条开始结束值
/// </summary>
/// <param name="i_start_value"></param>
/// <returns></returns>
bool SetStartEndValue(int i_start_value,int i_end_value);
/**
* @brief 进度条前进一步
*/
bool StepIt();
/// <summary>
/// 当前进度值
/// </summary>
int current_value;
public slots:
void updateProgress(int);
private:
/// <summary>
/// 进度条开始值
/// </summary>
int m_start_value;
/// <summary>
/// 进度条结束值
/// </summary>
int m_end_value;
float m_scale;
};
+154
View File
@@ -0,0 +1,154 @@
#include "im2shp.h"
#include <ogrsf_frmts.h>
#include "CProcessBase.h"
/**
* \brief 调用GDAL进度条接口
*
* 该函数用于将GDAL算法中的进度信息导出到CProcessBase基类中,供给界面显示
*
* @param dfComplete 完成进度值,其取值为 0.0 到 1.0 之间
* @param pszMessage 进度信息
* @param pProgressArg CProcessBase的指针
*
* @return 返回TRUE表示继续计算,否则为取消
*/
int STD_API ALGTermProgress(double dfComplete, const char* pszMessage, void* pProgressArg)
{
if (pProgressArg != NULL)
{
QtGDALProcessBar* pProcess = (QtGDALProcessBar*)pProgressArg;
pProcess->m_bIsContinue = pProcess->SetPosition(dfComplete);
if (pProcess->m_bIsContinue)
return TRUE;
else
return FALSE;
}
else
return TRUE;
}
int img2shp::ImagePolygonize(const char* pszSrcFile, const char* pszDstFile, const char* pszFormat, int BandNum,
QtGDALProcessBar* probar, QProgressBar* progressBar)
{
if (NULL == pszSrcFile || NULL == pszDstFile)
{
printf("待处理的栅格数据及输出矢量数据数据无效!");
return false;
}
if (GDALGetDriverCount() == 0)
GDALAllRegister();
OGRRegisterAll();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
CPLSetConfigOption("SHAPE_ENCODING", "gb2312");
//打开输入图像,并判断是否正常
GDALDataset* poSrcDS = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly);
if (NULL == poSrcDS)
{
printf("输入文件不能打开,请检查文件是否存在!");
return false;
}
//构造矢量文件驱动并创建矢量图层
GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
if (NULL == poDriver)
{
printf("不能创建指定类型的矢量文件驱动!");
GDALClose((GDALDatasetH)poSrcDS);
return false;
}
/*
*Create方法主要用于创建栅格文件的新数据集,其中nXSize,nYSize,nBands,都是对栅格文件的描述,**都置零后台会默认创建矢量数据集**
*/
//根据文件名创建输出矢量数据集
GDALDataset* poDstDs = poDriver->Create(pszDstFile, 0, 0, 0, GDT_Unknown, NULL);
if (NULL == poDstDs)
{
printf("不能创建矢量文件!");
GDALClose((GDALDatasetH)poSrcDS);
return false;
}
OGRSpatialReference* poSpatialRef = new OGRSpatialReference(poSrcDS->GetProjectionRef());
OGRLayer* poLayer = poDstDs->CreateLayer("Target", poSpatialRef, wkbPolygon, NULL);
if (NULL == poLayer)
{
printf("创建矢量图层失败!");
GDALClose((GDALDatasetH)poSrcDS);
GDALClose(poDstDs);
poSpatialRef = NULL;
return false;
}
OGRFieldDefn ofieldDef("value", OFTInteger);
if (OGRERR_NONE != poLayer->CreateField(&ofieldDef))
{
printf("创建矢量图层属性表失败!");
GDALClose((GDALDatasetH)poSrcDS);
GDALClose(poDstDs);
poSpatialRef = NULL;
return false;
}
//获取图像的对应波段
GDALRasterBandH hSrcBand = (GDALRasterBandH)poSrcDS->GetRasterBand(1);
GDALRasterBand* rasterband = poSrcDS->GetRasterBand(1);
GDALProgressFunc pfnProgress = ALGTermProgress;
if (!probar->SetStartEndValue(0, 100))
{
cout << "初始进度值设置失败!!!" << endl;
}
//if (GDALPolygonize(hSrcBand, NULL, (OGRLayerH)poLayer, 0, NULL, pfnProgress, probar) != CE_None)
//if (GDALPolygonize(hSrcBand, NULL, (OGRLayerH)poLayer, 0, NULL, GDALTermProgress, NULL) != CE_None)
//qDebug() << rasterband->GetNoDataValue() << endl;
//if (0.0 == poSrcDS->GetRasterBand(1)->GetNoDataValue())
//{
// if (CE_None != GDALPolygonize(hSrcBand, hSrcBand, (OGRLayerH)poLayer, 0, NULL, pfnProgress, probar))
// {
// GDALClose((GDALDatasetH)poSrcDS);
// GDALClose(poDstDs);
// delete poSpatialRef;
// poSpatialRef = NULL;
// return 0;
// }
//}
//else
//{
// if (CE_None != GDALPolygonize(hSrcBand, NULL, (OGRLayerH)poLayer, 0, NULL, pfnProgress, probar))
// {
// GDALClose((GDALDatasetH)poSrcDS);
// GDALClose(poDstDs);
// delete poSpatialRef;
// poSpatialRef = NULL;
// return 0;
// }
//}
if (CE_None != GDALPolygonize(hSrcBand, hSrcBand, (OGRLayerH)poLayer, 0, NULL, pfnProgress, probar))
{
GDALClose((GDALDatasetH)poSrcDS);
GDALClose(poDstDs);
delete poSpatialRef;
poSpatialRef = NULL;
return 0;
}
GDALClose((GDALDatasetH)poSrcDS);
GDALClose(poDstDs);
poSpatialRef = NULL;
return true;
}
+35
View File
@@ -0,0 +1,35 @@
#pragma once
#include "gdal_priv.h"
#include "ogrsf_frmts.h" //for ogr
#include "gdal_alg.h" //for GDALPolygonize
#include "cpl_conv.h" //for CPLMalloc()
#include "QtGDALProcessBar.h"
#include <QDebug>
/**
* @brief 导出符号定义
*/
#ifndef STD_API
#define STD_API __stdcall
#endif
/**
* \brief 调用GDAL进度条接口
*
* 该函数用于将GDAL算法中的进度信息导出到CProcessBase基类中,供给界面显示
*
* @param dfComplete 完成进度值,其取值为 0.0 到 1.0 之间
* @param pszMessage 进度信息
* @param pProgressArg CProcessBase的指针
*
* @return 返回TRUE表示继续计算,否则为取消
*/
int STD_API ALGTermProgress(double dfComplete, const char* pszMessage, void* pProgressArg);
class img2shp
{
public:
int ImagePolygonize(const char* pszSrcFile, const char* pszDstFile, const char* pszFormat, int BandNum, QtGDALProcessBar* probar, QProgressBar* progressBar);
bool createChineseStringProperty(OGRLayer* poLayer, const char* filterFieldName, const char* createFieldName, vector<string> nameVal, float min, QProgressBar* progressBar);
protected:
private:
};
@@ -1,10 +1,10 @@
#include "DEM_Fill.h"
#include "LandslidePredict.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
DataFilling w;
LandslidePredict w;
w.CenterWidget()->show();
return a.exec();
}
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32" fill="none"><g opacity="1" transform="translate(0 0) rotate(0 16 16)"><path id="路径 1 (轮廓)" fill-rule="evenodd" style="fill:#2C2C2C" transform="translate(0 1.5374328853267798) rotate(0 15.99999999999979 14.46256711467357)" opacity="1" d="M17.11 8.78L19.6 20.62L29.27 24.69L32 28.93L0 28.93L0 14.53L6.07 1.45L6.29 0.99L14.08 0L17.11 8.78ZM7.53 2.69L1.84 14.94L1.84 27.08L28.62 27.08L28.03 26.16L17.99 21.94L15.33 9.27L12.82 2.02L7.53 2.69Z" /><path id="路径 2" fill-rule="evenodd" style="fill:#2C2C2C" transform="translate(18.9798339264529 9.916436213707748) rotate(0 5.021363830056714 7.462944407974411)" opacity="1" d="M1.75,11.42L10.04,14.93L7.09,6.73L0.18,0L0,0.28L1.75,11.42Z " /><path id="路径 3" fill-rule="evenodd" style="fill:#2C2C2C" transform="translate(26.07423786983578 13.693975975768783) rotate(0 1.4741618583652738 1.3820267422174524)" opacity="1" d="M0.53,0.2C0.46,0.17 0.37,0.19 0.32,0.26C0.27,0.32 0.27,0.41 0.31,0.47L1.66,2.53C1.7,2.59 1.75,2.62 1.82,2.62C1.88,2.62 1.93,2.59 1.97,2.54L2.82,1.3C2.85,1.25 2.86,1.19 2.84,1.14C2.82,1.09 2.78,1.04 2.73,1.02L0.53,0.2Z " /><path id="路径 4" fill-rule="evenodd" style="fill:#2C2C2C" transform="translate(21.28321183014864 9.640030865264256) rotate(0 1.8427023229565922 1.5662969745131128)" opacity="1" d="M3.66,0.65C3.67,0.6 3.65,0.55 3.62,0.51C3.59,0.47 3.55,0.45 3.5,0.44L0.56,0.07C0.48,0.06 0.41,0.1 0.37,0.18C0.34,0.25 0.36,0.34 0.41,0.39L3.08,2.89C3.13,2.93 3.2,2.95 3.27,2.93C3.33,2.9 3.38,2.84 3.39,2.78L3.66,0.65Z " /></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -1,548 +0,0 @@
import os
import cv2
import numpy as np
import tifIO
import shutil
import sys
import argparse
import math
from math import floor
import json
import subprocess
import qgis
from qgis.core import * # attach main QGIS library
from qgis.utils import * # attach main python library
from qgis.analysis import *
from osgeo import gdal
#相对路径
qgis_path = sys.executable
process_path = qgis_path.split('bin')[0]+'apps\\qgis-ltr\\python\\plugins'
# process_path = 'D:/code/RsSurvey/RsSurvey_Build/x64/Release/QGIS_3.22.8/apps/qgis-ltr/python/plugins/'
if os.path.exists(process_path):
print("exists path:"+process_path)
sys.stdout.flush()
else:
print("fine no path:"+process_path)
sys.stdout.flush()
sys.path.append(process_path)
qgs = QgsApplication([], False)
qgs.initQgis()
import processing
from processing.core.Processing import Processing
Processing.initialize()
#添加参数
parser = argparse.ArgumentParser()
parser.add_argument('--in_holedem', type=str,
default='D:/A_testdata/dianli_test/00yanshou/data_train_dem/05veg_maskedTiff/',
help='输入数据,经过裁剪的dem')
parser.add_argument('--work_space', type=str,
default='D:/A_testdata/dianli_test/00yanshou/data_train_dem/06veg_dataFill_workspace/',
help='用于填补时存放中间路径及结果文件')
parser.add_argument('--scale', type=float,
default=0.1,
help='外接矩形放大的比例')
parser.add_argument('--win_size', type=int,
default=3,
help='空洞外扩像素')
opt = parser.parse_args()
in_holedem = opt.in_holedem
work_space = opt.work_space
scale = opt.scale
win_size = opt.win_size
'''
txt文件名以in_holedem中dem数据文件名命名
内容以singlehole文件开始,包含位置信息
subname, lt_x,lt_y,rb_x,rb_y
tktk130_mask_id_1_hw_83_106.tif,1364,1950,1470,2033
'''
out_txt_folder = 'txt_singlehole/'
singlehole_folder = 'dem_singlehole/'# 保存单个空洞
ras2pot_folder = 'raster2points/'
ras2potpro_folder = 'raster2points_pro/'
tinmesh_folder = 'TINMesh/'
potfrommesh_folder = 'pointfrommesh/'
potfrommeshfloat_folder = 'pointfrommeshfloat/'
filltif_folder = 'tif/'
filltifpro_folder = 'tif_pro/'
out_fulltif_folder = 'out_result/'# 填补并放回的整图结果
print("win_size:%d,scale:%.4f" % (win_size, scale))
sys.stdout.flush()
def findHoles(in_demfolder, out_singlehole, txt_folder):
count = 0
ev = floor(win_size / 2)
if os.path.exists(txt_folder):
try:
shutil.rmtree(txt_folder)
time.sleep(2) # 防止删除操作未结束就运行mkdir()
except Exception as e:
print("error {}".format(str(e)))
sys.stdout.flush()
print(-1.0)
sys.stdout.flush()
os.mkdir(txt_folder)
if os.path.exists(out_singlehole):
try:
shutil.rmtree(out_singlehole)
time.sleep(2) # 防止删除操作未结束就运行mkdir()
except Exception as e:
print("error {}".format(str(e)))
sys.stdout.flush()
print(-1)
sys.stdout.flush()
os.mkdir(out_singlehole)
dem_list = []
src_list = os.listdir(in_demfolder)
for f in src_list:
if os.path.splitext(f)[1] == '.tif' or os.path.splitext(f)[1] == '.TIF':
dem_list.append(f)
for imgfile in dem_list:
filename = os.path.splitext(imgfile)[0]
txtname = filename + '.txt'
txt_route = os.path.join(txt_folder, txtname)
file_handle = open(txt_route, mode='w')
# file_handle.writelines(['文件名,左上角列号,左上角行号,右下角列号,右下角行号\n'])
dem_route = os.path.join(in_demfolder, imgfile)
proj, geotrans, dem_img, width, height = tifIO.ReadTif(dem_route) # c,h,w
origin = cv2.imread(dem_route, cv2.IMREAD_UNCHANGED)
img = origin.copy()
# 二值化,转换类型
ret2, binary = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV)
thresh_image = binary.astype(np.uint8)
# 连通域分析
contours, hierarchy = cv2.findContours(thresh_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 检索最外轮廓
# contours, hierarchy = cv2.findContours(thresh_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 检索所有轮廓
for i in range(0, len(contours)):
thisgeo = geotrans.copy()
lt_x, lt_y, w, h = cv2.boundingRect(contours[i]) # 最小包络矩形的四至
# 矩形外扩,最小外扩2像元,保证空洞再小也能外扩
w_ex = floor(w * scale / 2) if floor(w * scale / 2) > 2 else 2
h_ex = floor(h * scale / 2) if floor(h * scale / 2) > 2 else 2
if lt_x - w_ex >= 0:
new_lt_x = lt_x - w_ex
else:
new_lt_x = 0
if lt_y - h_ex >= 0:
new_lt_y = lt_y - h_ex
else:
new_lt_y = 0
if lt_x + w + w_ex <= width:
new_rb_x = lt_x + w + w_ex
else:
new_rb_x = width
if lt_y + h + h_ex <= height:
new_rb_y = lt_y + h + h_ex
else:
new_rb_y = height
this_hole = img[new_lt_y: new_rb_y, new_lt_x: new_rb_x]
flag = np.zeros(this_hole.shape, dtype=int)
flag[this_hole > -9999] = 1 # 如果低于-9999arcgis中nodata是极小的负数
# 洞不扩大
# this_hole[this_hole <=0] = np.nan
# 洞外扩
new_w = new_rb_x - new_lt_x
new_h = new_rb_y - new_lt_y
for c in range(0, new_w):
for r in range(0, new_h):
if flag[r, c] == 0:
for win_c in range(win_size):
for win_r in range(win_size):
tempr = r + win_r - ev
tempc = c + win_c - ev
if tempr >= 0 and tempr < new_h and tempc >= 0 and tempc < new_w:
this_hole[tempr, tempc] = np.nan
lon = thisgeo[0] + thisgeo[1] * new_lt_x
lat = thisgeo[3] + thisgeo[5] * new_lt_y
thisgeo[0] = lon
thisgeo[3] = lat
# fileroutesub =filename+ '_%d.tif' % count
fileroutesub = filename + '_id_%d_hw_%d_%d' % (i + 1, new_h, new_w) + '.tif'
fileroute = os.path.join(out_singlehole, fileroutesub)
this_hole[np.where(this_hole == 0.0)] = np.nan
tifIO.writeTif(fileroute, proj, thisgeo, this_hole) # 投影信息不对
# 坐标从【0,0】开始计,左上坐标【x,y】,右下坐标[x+w-1,y+h-1]
file_handle.writelines([fileroutesub, ',', str(new_lt_x), ',',
str(new_lt_y), ',', str(new_rb_x), ',', str(new_rb_y), '\n'])
count = count + 1
file_handle.close()
def confirmWorkspaceClear(rootPath):
out_path_raster2points = os.path.join(rootPath, ras2pot_folder)
if os.path.exists(out_path_raster2points):
try:
shutil.rmtree(out_path_raster2points)
time.sleep(2) # 防止删除操作未结束就运行mkdir()
except Exception as e:
print(-1.0)
sys.stdout.flush()
os.mkdir(out_path_raster2points)
print(4)
sys.stdout.flush()
out_path_raster2points_pro = os.path.join(rootPath, ras2potpro_folder)
if os.path.exists(out_path_raster2points_pro):
try:
shutil.rmtree(out_path_raster2points_pro)
time.sleep(2) # 防止删除操作未结束就运行mkdir()
except Exception as e:
print(-1.0)
sys.stdout.flush()
os.mkdir(out_path_raster2points_pro)
print(5)
sys.stdout.flush()
out_path_TINMesh = os.path.join(rootPath, tinmesh_folder)
if os.path.exists(out_path_TINMesh):
try:
shutil.rmtree(out_path_TINMesh)
time.sleep(2) # 防止删除操作未结束就运行mkdir()
except Exception as e:
print(-1.0)
sys.stdout.flush()
os.mkdir(out_path_TINMesh)
print(6)
sys.stdout.flush()
out_path_pointfrommesh = os.path.join(rootPath, potfrommesh_folder)
if os.path.exists(out_path_pointfrommesh):
try:
shutil.rmtree(out_path_pointfrommesh)
time.sleep(2) # 防止删除操作未结束就运行mkdir()
except Exception as e:
print(-1.0)
sys.stdout.flush()
os.mkdir(out_path_pointfrommesh)
print(7)
sys.stdout.flush()
out_path_pointfrommeshfloat = os.path.join(rootPath, potfrommeshfloat_folder)
if os.path.exists(out_path_pointfrommeshfloat):
try:
shutil.rmtree(out_path_pointfrommeshfloat)
time.sleep(2) # 防止删除操作未结束就运行mkdir()
except Exception as e:
print(-1.0)
sys.stdout.flush()
os.mkdir(out_path_pointfrommeshfloat)
print(8)
sys.stdout.flush()
out_path_tif = os.path.join(rootPath, filltif_folder)
if os.path.exists(out_path_tif):
try:
shutil.rmtree(out_path_tif)
time.sleep(2) # 防止删除操作未结束就运行mkdir()
except Exception as e:
print(-1.0)
sys.stdout.flush()
os.mkdir(out_path_tif)
print(9)
sys.stdout.flush()
out_path_tif_pro = os.path.join(rootPath, filltifpro_folder)
if os.path.exists(out_path_tif_pro):
try:
shutil.rmtree(out_path_tif_pro)
time.sleep(2) # 防止删除操作未结束就运行mkdir()
except Exception as e:
print(-1.0)
sys.stdout.flush()
os.mkdir(out_path_tif_pro)
print(10)
sys.stdout.flush()
def raster2points(fileName):
inFile=work_space+singlehole_folder+fileName
# 获取文件信息
rlayer = QgsRasterLayer(inFile, "SRTM layer name")
tif_crs =rlayer.crs().toWkt()
if not rlayer.isValid():
print("图层加载失败!")
dataset = gdal.Open(inFile)
gt = dataset.GetGeoTransform()
Xmin = gt[0]
Ymin = gt[3]
width = dataset.RasterXSize
height = dataset.RasterYSize
Xmax = gt[0] + width*gt[1] + height*gt[2]
Ymax = gt[3] + width*gt[4] + height*gt[5]
extent = [Xmin,Xmax,min(Ymin,Ymax),max(Ymin,Ymax)]
cellHeight = math.fabs(gt[1])
cellWidth = math.fabs(gt[5])
# #准备进行处理
# aid='saga:rastervaluestopoints'
out_path = os.path.join(work_space,ras2pot_folder)
outFile=out_path+fileName[0:fileName.index('.')]+'.geojson'
# p = {
# 'GRIDS': [inFile],
# 'NODATA': True,
# 'POLYGONS': None,
# 'SHAPES': outFile,
# 'TYPE': 0}
# processing.run(aid, p)
print(qgis_path)
exe_path= qgis_path.split('python.exe')[0]+"saga_cmd.exe"
print(exe_path)
cammand_line=exe_path+" shapes_grid 3 -GRIDS {} -POLYGONS None -NODATA 1 -SHAPES {} -TYPE 0".format(inFile,outFile)# --flags[qr]
process_status=subprocess.call(cammand_line)
if 0!=process_status:
print("error ")
pro_aid = 'native:assignprojection'
proFile = work_space+ras2potpro_folder+fileName[0:fileName.index('.')]+'.geojson'
pro_p = {
'CRS': QgsCoordinateReferenceSystem('EPSG:4546'),
'INPUT': outFile,
'OUTPUT': proFile,
}
processing.run(pro_aid, pro_p)
return fileName[0:fileName.index('.')]+'.geojson', cellHeight, cellWidth, tif_crs, extent
def points2mesh(fileName,tif_crs):
aid='native:tinmeshcreation'
inFile=work_space+ras2potpro_folder+fileName
optFile=work_space+tinmesh_folder+fileName[0:fileName.index('.')]+'.file'
p={ 'CRS_OUTPUT' : QgsCoordinateReferenceSystem('EPSG:4546'), 'MESH_FORMAT' : 2, 'OUTPUT_MESH' : optFile,
'SOURCE_DATA' : [{'source': inFile,'type': 0,'attributeIndex': 3}] }
processing.run(aid,p)
return fileName[0:fileName.index('.')]+'.file'
def getpointFromMesh(fileName, tif_crs,extent):
inFile = work_space + tinmesh_folder + fileName
if not os.path.exists(inFile):
inFile = work_space + tinmesh_folder + fileName + '.ply'
optFile = 'TEMPORARY_OUTPUT'
aid = 'native:exportmeshongrid'
# tif_crs
p = {'CRS_OUTPUT' : QgsCoordinateReferenceSystem('EPSG:4546'), 'DATASET_GROUPS': [0],
'DATASET_TIME': {'type': 'static'},
'EXTENT':None,
'GRID_SPACING': 0.05,
'INPUT' : inFile, 'OUTPUT': optFile, 'VECTOR_OPTION': 0}
# 'EXTENT': '%.8f,%.8f,%.8f,%.8f [EPSG:4546]' % (extent[0],extent[1],extent[2],extent[3]),
res = processing.run(aid, p)
# Save as a shapefile
Fl_ou = fileName[0:fileName.index('.')] + '.geojson'
Fl_ou = work_space + potfrommesh_folder + Fl_ou
options = QgsVectorFileWriter.SaveVectorOptions()
options.driverName = "geojson"
QgsVectorFileWriter.writeAsVectorFormatV2(res['OUTPUT'], Fl_ou, QgsCoordinateTransformContext(), options)
# TODO turn string to realNumber
return fileName[0:fileName.index('.')] + '.geojson'
def transString2float(fileName):
inFile = work_space + potfrommesh_folder + fileName
opt = work_space + potfrommeshfloat_folder + fileName
optFile = open(opt, 'w')
# minx=9999999
# maxx=0
# miny=99999999
# maxy=0
with open(inFile) as jsonFile:
points = json.load(jsonFile)
features = points['features']
for feature in features:
properties = feature['properties']
Bed_Elevation = float(properties['Bed Elevation'])
properties['Bed Elevation'] = Bed_Elevation
#
# geometry=feature['geometry']
'''
coordinates = geometry['coordinates']
x = coordinates[0]
if minx>x:
minx =x
if maxx<x:
maxx=x
y= coordinates[1]
if miny > y:
miny=y
if maxy <y:
maxy=y
'''
json.dump(points, optFile)
optFile.close()
return fileName
def point2tif(fileName,cellHeight,cellWidth,tif_crs,extent):
inFile=work_space+potfrommeshfloat_folder+fileName
# print(inFile)
optFile=work_space+filltif_folder+fileName[0:fileName.index('.')]+'.tif'
# print(extent)
aid='gdal:rasterize'
p = {'BURN':0, 'DATA_TYPE':5,
'EXTENT':None,
'EXTRA': '', 'FIELD' : 'Bed Elevation', 'HEIGHT' : cellHeight,'INIT' : None,
'INPUT': inFile, 'INVERT' : False, 'NODATA' : 0, 'OPTIONS' : '', 'OUTPUT' : optFile,
'UNITS': 1, 'USE_Z' : False, 'WIDTH' : cellWidth}
# p= { 'BURN':0, 'DATA_TYPE':5,
# 'EXTENT':'544158.5540865903, 544161.2540865903, 4450451.895210848, 4450455.295210849 [EPSG:4546]',
# 'EXTRA' : '', 'FIELD' : 'Bed Elevation', 'HEIGHT' : cellHeight,
# 'INIT' : None, 'INPUT' : inFile, 'INVERT' : False, 'NODATA' : 0,
# 'OPTIONS' : '',
# 'OUTPUT' : optFile, 'UNITS' : 1, 'USE_Z' : False, 'WIDTH' : cellWidth}
processing.run(aid,p)
dataset=gdal.Open(optFile)
width = dataset.RasterXSize
height = dataset.RasterYSize
# print('out wid,hei:',width,height)
optFile2=work_space+'tif2/'+fileName[0:fileName.index('.')]+'.tif'
# print(optFile2)
pro_aid='gdal:warpreproject'
# proFile=optFile
# proFile=rootPath+'raster2points_pro/'+fileName[0:fileName.index('.')]+'.shp'
# pro_p={ 'CRS' : QgsCoordinateReferenceSystem('EPSG:4546'), 'INPUT' : outFile, 'OUTPUT' :proFile}
pro_p={'SOURCE_CRS' : QgsCoordinateReferenceSystem('EPSG:4546'),
'TARGET_CRS' : QgsCoordinateReferenceSystem(tif_crs),
'EXTENT': '%.8f,%.8f,%.8f,%.8f [EPSG:4546]' % (extent[0], extent[1], extent[2], extent[3]),
'RESAMPLING':2,'INPUT' : optFile, 'OUTPUT' :optFile2}
processing.run(pro_aid,pro_p)
return fileName
def processOneTif(fileName):
# 转矢量点,赋投影
processedFile, cellHeight, cellWidth, tif_crs, extent = raster2points(fileName)
meshFile = points2mesh(processedFile, tif_crs)
pointsFile = getpointFromMesh(meshFile, tif_crs, extent)
pointsFilefloat = transString2float(pointsFile)
point2tif(pointsFilefloat, cellHeight, cellWidth, tif_crs, extent)
def demFill():
# print("demFill")
# sys.stdout.flush()
single_files_list=os.listdir(work_space+singlehole_folder)
temp_file_lists = []
for file in single_files_list:
if os.path.splitext(file)[1] == '.tif' or os.path.splitext(file)[1] == '.TIF':
temp_file_lists.append(file)
total = len(temp_file_lists)
for index, file in enumerate(temp_file_lists):
sys.stdout.flush()
processOneTif(file)
print(10+float((index+1) / total * 79))
sys.stdout.flush()
def back2Whole():
txtList=[]
txt_dir=work_space+out_txt_folder
sub_list = os.listdir(txt_dir)
#先找txt,保存文件名到list中
for f in sub_list:
if os.path.splitext(f)[1] == '.txt' or os.path.splitext(f)[1] == '.TXT':
txtList.append(f)
txtNum=len(txtList)
if txtNum<=0:
# print("There is no holes to join")
print(-1.0)
sys.stdout.flush()
currentIndicator=0
for txtfile in txtList:
#根据文件名找原来的图像文件,拷贝
imgname=os.path.splitext(txtfile)[0]
demfile=imgname+'.tif'# txt文件名与dem文件名对应
txt_route= os.path.join(txt_dir, txtfile)# txt文件
dem_route = os.path.join(in_holedem, demfile)# 空缺的整图
proj, geotrans, dem_img, width, height = tifIO.ReadTif(dem_route) # c,h,w
img = dem_img.copy()
#读txt,找到对应的小矩形文件
file_handle=open(txt_route,mode="r")
lines=file_handle.readlines()
for i in lines:
s=i.split(',')
#['文件名,左上角列号,左上角行号,右下角列号,右下角行号\n']
subname=s[0]
lt_x=int(s[1])
lt_y=int(s[2])
rb_x=int(s[3])
rb_y=int(s[4])
# print(subname+" img's lt_x:%d,lt_y:%d,rb_x:%d,rb_y:%d" % (lt_x,lt_y,rb_x,rb_y))
# 读相应的文件,根据行列号替换
sub_route = os.path.join(work_space+filltif_folder, subname)
proj_sub, geotrans_sub, sub_img, w_sub, h_sub = tifIO.ReadTif(sub_route)
sp = sub_img.shape
img_w = sp[1]
img_h = sp[0]
# print(subname + " img's w:%d,h:%d" % (img_w,img_h))
# img[lt_y:rb_y,lt_x:rb_x]=sub_img
img[lt_y:lt_y+img_h,lt_x:lt_x+img_w]=sub_img
file_handle.close()
out_path = os.path.join(work_space,out_fulltif_folder)
if os.path.exists(out_path):
try:
shutil.rmtree(out_path)
time.sleep(2) # 防止删除操作未结束就运行mkdir()
except Exception as e:
print(-1.0)
sys.stdout.flush()
os.mkdir(out_path)
out_wholefile=imgname+'_whole.tif'
tifIO.writeTif(out_path+out_wholefile, proj, geotrans, img)
currentIndicator=currentIndicator+1
print(90.0+float(currentIndicator/txtNum)*10)
sys.stdout.flush()
if __name__ == '__main__':
print(0)
sys.stdout.flush()
in_demfolder = in_holedem
out_singlehole = os.path.join(work_space, singlehole_folder)
txt_folder = os.path.join(work_space, out_txt_folder)
# 执行寻找并保存单个空洞
findHoles(in_demfolder,out_singlehole,txt_folder)
print(2)
sys.stdout.flush()
confirmWorkspaceClear(work_space)
demFill()
back2Whole()
-68
View File
@@ -1,68 +0,0 @@
from osgeo import gdal
# from tqdm import tqdm
def ReadTif(tif_path):
dataset = gdal.Open(tif_path)
width = dataset.RasterXSize
height = dataset.RasterYSize
geotrans = list(dataset.GetGeoTransform()) # 仿射矩阵
proj = dataset.GetProjection() # 地图投影信息
data = dataset.ReadAsArray(0, 0, width, height) # 将数据写成数组,对应栅格矩阵
del dataset # 关闭对象,文件dataset
return proj, geotrans, data, width, height
def writeTif(fileroute, im_proj, im_geotrans, im_data):
# 判断栅格数据的数据类型
"""
GDAL中的GDALDataType是一个枚举型,其中的值为:
GDT_Unknown : 未知数据类型
GDT_Byte : 8bit正整型 (C++中对应unsigned char)
GDT_UInt16 : 16bit正整型 (C++中对应 unsigned short)
GDT_Int16 : 16bit整型 (C++中对应 short 或 short int)
GDT_UInt32 : 32bit 正整型 (C++中对应unsigned long)
GDT_Int32 : 32bit整型 (C++中对应int 或 long 或 long int)
GDT_Float32 : 32bit 浮点型 (C++中对应float)
GDT_Float64 : 64bit 浮点型 (C++中对应double)
GDT_CInt16 : 16bit复整型 (?)
GDT_CInt32 : 32bit复整型 (?)
GDT_CFloat32 : 32bit复浮点型 (?)
GDT_CFloat64 : 64bit复浮点型 (?)
"""
if 'int8' in im_data.dtype.name:
datatype = gdal.GDT_Byte
elif 'int16' in im_data.dtype.name:
datatype = gdal.GDT_UInt16
else:
datatype = gdal.GDT_Float32
# 判读数组维数
if len(im_data.shape) == 3:
im_bands, im_height, im_width = im_data.shape
else:
im_bands, (im_height, im_width) = 1, im_data.shape
im_data = im_data.reshape(im_bands,im_height, im_width)
# 创建文件
driver = gdal.GetDriverByName("GTiff") # 数据类型必须有,因为要计算需要多大内存空间
dataset = driver.Create(fileroute, im_width,im_height, im_bands, datatype)
dataset.SetGeoTransform(im_geotrans) # 写入仿射变换参数
dataset.SetProjection(im_proj) # 写入投影
if im_bands == 1:
dataset.GetRasterBand(1).WriteArray(im_data[0]) # 写入数组数据
else:
#for i in range(im_bands):
for i in tqdm(range(im_bands)):
dataset.GetRasterBand(i + 1).WriteArray(im_data[i])
del dataset
def np2gdal(hwc): # hwc2chw
chw = hwc.swapaxes(2, 0).swapaxes(1, 2) # h,w,c to c,h,w
return chw
def gdal2np(chw): #chw2hwc
hwc = chw.swapaxes(1, 0).swapaxes(1, 2) # h,w,c
return hwc