初始化
This commit is contained in:
373
tools/ui/tabs/acid_stat_tab.py
Normal file
373
tools/ui/tabs/acid_stat_tab.py
Normal file
@@ -0,0 +1,373 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
栅格处理界面: 提供栅格重分类、栅格转矢量和小面积图斑消除的界面操作
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import arcpy
|
||||
|
||||
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
|
||||
QPushButton, QFileDialog, QGridLayout,
|
||||
QGroupBox, QMessageBox)
|
||||
from tools.ui.runners.script_runner import ScriptRunner
|
||||
|
||||
|
||||
class AcidStatsTab(QWidget):
|
||||
"""栅格处理窗口部件类"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(AcidStatsTab, self).__init__(parent)
|
||||
self.main_window = parent
|
||||
# 创建的导出线程
|
||||
self.script_runner = ScriptRunner()
|
||||
self.connect_signals()
|
||||
self.init_ui()
|
||||
self.setWindowTitle("酸化状况统计")
|
||||
|
||||
def connect_signals(self):
|
||||
# 连接ScriptRunner的信号
|
||||
self.script_runner.task_started.connect(self.on_script_started)
|
||||
self.script_runner.task_finished.connect(self.on_script_finished)
|
||||
self.script_runner.task_error.connect(self.on_script_error)
|
||||
self.script_runner.task_log.connect(self.on_script_log)
|
||||
self.script_runner.manager_log.connect(self.log_message)
|
||||
|
||||
def init_ui(self):
|
||||
"""初始化用户界面"""
|
||||
main_layout = QVBoxLayout(self)
|
||||
|
||||
# 批量处理区域
|
||||
self.batch_mode_group = QGroupBox("批量处理设置")
|
||||
batch_layout = QGridLayout()
|
||||
|
||||
# 输入行政区名称
|
||||
batch_layout.addWidget(QLabel("行政区名称:"), 0, 0)
|
||||
self.input_xzqmc_edit = QLineEdit()
|
||||
batch_layout.addWidget(self.input_xzqmc_edit, 0, 1)
|
||||
|
||||
# 设置工作空间
|
||||
batch_layout.addWidget(QLabel("工作空间:"), 1, 0)
|
||||
self.input_workspace_edit = QLineEdit()
|
||||
batch_layout.addWidget(self.input_workspace_edit, 1, 1)
|
||||
self.browse_input_workspace_btn = QPushButton("选择GDB")
|
||||
self.browse_input_workspace_btn.clicked.connect(self.browse_input_workspace)
|
||||
batch_layout.addWidget(self.browse_input_workspace_btn, 1, 2)
|
||||
|
||||
# 批量输出文件夹
|
||||
batch_layout.addWidget(QLabel("输出文件夹:"), 2, 0)
|
||||
self.batch_output_folder_edit = QLineEdit()
|
||||
batch_layout.addWidget(self.batch_output_folder_edit, 2, 1)
|
||||
self.browse_batch_output_btn = QPushButton("选择文件夹")
|
||||
self.browse_batch_output_btn.clicked.connect(self.browse_batch_output_folder)
|
||||
batch_layout.addWidget(self.browse_batch_output_btn, 2, 2)
|
||||
|
||||
# 选择乡镇界线
|
||||
batch_layout.addWidget(QLabel("乡镇界线:"), 3, 0)
|
||||
self.xzq_features_edit = QLineEdit()
|
||||
batch_layout.addWidget(self.xzq_features_edit, 3, 1)
|
||||
batch_layout.addWidget(QLabel("GDB中的要素类名"), 3, 2)
|
||||
|
||||
# 选择地类图斑
|
||||
batch_layout.addWidget(QLabel("地类图斑:"), 4, 0)
|
||||
self.dltb_features_edit = QLineEdit()
|
||||
batch_layout.addWidget(self.dltb_features_edit, 4, 1)
|
||||
batch_layout.addWidget(QLabel("GDB中的要素类名"), 4, 2)
|
||||
|
||||
# 选择历史PH样点图斑
|
||||
batch_layout.addWidget(QLabel("历史PH样点:"), 5, 0)
|
||||
self.ph_samples_edit = QLineEdit()
|
||||
batch_layout.addWidget(self.ph_samples_edit, 5, 1)
|
||||
batch_layout.addWidget(QLabel("GDB中的要素类名"), 5, 2)
|
||||
|
||||
# 选择重分类后的PH面要素
|
||||
batch_layout.addWidget(QLabel("分类后酸化PH面:"), 6, 0)
|
||||
self.acid_ph_edit = QLineEdit()
|
||||
batch_layout.addWidget(self.acid_ph_edit, 6, 1)
|
||||
batch_layout.addWidget(QLabel("GDB中的要素类名"), 6, 2)
|
||||
|
||||
# 选择土壤类型图斑
|
||||
batch_layout.addWidget(QLabel("土壤类型图斑:"), 7, 0)
|
||||
self.soil_type_features_edit = QLineEdit()
|
||||
batch_layout.addWidget(self.soil_type_features_edit, 7, 1)
|
||||
batch_layout.addWidget(QLabel("GDB中的要素类名"), 7, 2)
|
||||
|
||||
# 选择三普PH赋值栅格
|
||||
batch_layout.addWidget(QLabel("三普PH栅格:"), 8, 0)
|
||||
self.assign_raster_edit = QLineEdit()
|
||||
batch_layout.addWidget(self.assign_raster_edit, 8, 1)
|
||||
self.assign_raster_btn = QPushButton("选择TIF")
|
||||
self.assign_raster_btn.clicked.connect(self.browse_assign_raster)
|
||||
batch_layout.addWidget(self.assign_raster_btn, 8, 2)
|
||||
|
||||
# 选择酸化PH赋值栅格
|
||||
batch_layout.addWidget(QLabel("酸化PH栅格:"), 9, 0)
|
||||
self.acid_raster_edit = QLineEdit()
|
||||
batch_layout.addWidget(self.acid_raster_edit, 9, 1)
|
||||
self.acid_raster_btn = QPushButton("选择TIF")
|
||||
self.acid_raster_btn.clicked.connect(self.browse_acid_raster)
|
||||
batch_layout.addWidget(self.acid_raster_btn, 9, 2)
|
||||
|
||||
self.batch_mode_group.setLayout(batch_layout)
|
||||
|
||||
# 操作按钮
|
||||
btn_layout = QHBoxLayout()
|
||||
|
||||
# 导出酸化统计表
|
||||
self.generate_sh_stat_btn = QPushButton("生成酸化统计表")
|
||||
self.generate_sh_stat_btn.clicked.connect(self.on_generate_area_stat)
|
||||
|
||||
self.cancel_btn = QPushButton("取消")
|
||||
# self.cancel_btn.clicked.connect(self.close)
|
||||
|
||||
btn_layout.addWidget(self.generate_sh_stat_btn)
|
||||
btn_layout.addWidget(self.cancel_btn)
|
||||
|
||||
# 添加所有组件到主布局
|
||||
main_layout.addWidget(self.batch_mode_group)
|
||||
main_layout.addLayout(btn_layout)
|
||||
|
||||
self.setLayout(main_layout)
|
||||
|
||||
|
||||
def browse_input_workspace(self):
|
||||
"""浏览选择输入GDB"""
|
||||
folder_path = QFileDialog.getExistingDirectory(self, "选择GDB数据库")
|
||||
if folder_path:
|
||||
self.input_workspace_edit.setText(folder_path)
|
||||
|
||||
def browse_batch_output_folder(self):
|
||||
"""浏览选择表格输出文件夹"""
|
||||
folder_path = QFileDialog.getExistingDirectory(self, "选择表格输出文件夹")
|
||||
if folder_path:
|
||||
self.batch_output_folder_edit.setText(folder_path)
|
||||
|
||||
def browse_assign_raster(self):
|
||||
"""浏览选择赋值栅格 (支持栅格数据)"""
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
self, "选择赋值栅格", "",
|
||||
"栅格文件 (*.tif *.img *.jpg);;所有文件 (*)"
|
||||
)
|
||||
if not file_path:
|
||||
return
|
||||
|
||||
if file_path.lower().endswith(('.tif', '.img', '.jpg')):
|
||||
self.assign_raster_edit.setText(file_path)
|
||||
self.log_message(f"已选择栅格文件: {file_path}")
|
||||
|
||||
else:
|
||||
QMessageBox.warning(self, "选择错误", "不支持的文件类型。请选择有效的栅格文件。")
|
||||
self.assign_raster_edit.clear()
|
||||
|
||||
def browse_acid_raster(self):
|
||||
"""浏览选择赋值栅格 (支持栅格数据)"""
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
self, "选择赋值栅格", "",
|
||||
"栅格文件 (*.tif *.img *.jpg);;所有文件 (*)"
|
||||
)
|
||||
if not file_path:
|
||||
return
|
||||
|
||||
if file_path.lower().endswith(('.tif', '.img', '.jpg')):
|
||||
self.acid_raster_edit.setText(file_path)
|
||||
self.log_message(f"已选择栅格文件: {file_path}")
|
||||
|
||||
else:
|
||||
QMessageBox.warning(self, "选择错误", "不支持的文件类型。请选择有效的栅格文件。")
|
||||
self.acid_raster_edit.clear()
|
||||
|
||||
def validate_inputs(self):
|
||||
"""验证输入参数"""
|
||||
# 验证工作空间路径
|
||||
if not self.input_workspace_edit.text() or not arcpy.Exists(self.input_workspace_edit.text()):
|
||||
QMessageBox.warning(self, "输入错误", "请选择有效的工作空间")
|
||||
return False
|
||||
|
||||
if not self.batch_output_folder_edit.text():
|
||||
QMessageBox.warning(self, "输入错误", "请选择批量处理输出文件夹")
|
||||
return False
|
||||
|
||||
# 行政界线验证
|
||||
xzq_path = os.path.join(self.input_workspace_edit.text(),self.xzq_features_edit.text())
|
||||
if not xzq_path or not arcpy.Exists(xzq_path):
|
||||
QMessageBox.warning(self, "输入错误", "行政界线要素路径无效或不存在")
|
||||
return False
|
||||
|
||||
try:
|
||||
desc = arcpy.Describe(xzq_path)
|
||||
if desc.dataType != 'FeatureClass':
|
||||
QMessageBox.warning(self, "输入错误", f"行政界线不是一个要素类:\n{xzq_path}")
|
||||
return False
|
||||
except Exception as e:
|
||||
QMessageBox.warning(self, "输入错误", f"未知要素,请检查是否为有效要素类:\n{xzq_path}\n错误: {e}")
|
||||
return False
|
||||
|
||||
# 地类图斑验证
|
||||
dltb_path = os.path.join(self.input_workspace_edit.text(),self.dltb_features_edit.text())
|
||||
if not dltb_path or not arcpy.Exists(dltb_path):
|
||||
QMessageBox.warning(self, "输入错误", "地类图斑要素路径无效或不存在")
|
||||
return False
|
||||
|
||||
try:
|
||||
desc = arcpy.Describe(dltb_path)
|
||||
if desc.dataType != 'FeatureClass':
|
||||
QMessageBox.warning(self, "输入错误", f"地类图斑不是一个要素类:\n{dltb_path}")
|
||||
return False
|
||||
except Exception as e:
|
||||
QMessageBox.warning(self, "输入错误", f"未知要素,请检查是否为有效要素类:\n{dltb_path}\n错误: {e}")
|
||||
return False
|
||||
|
||||
# 验证PH样点
|
||||
samples_path = os.path.join(self.input_workspace_edit.text(), self.ph_samples_edit.text())
|
||||
if not samples_path or not arcpy.Exists(samples_path):
|
||||
QMessageBox.warning(self, "输入错误", "PH样点要素路径无效或不存在")
|
||||
return False
|
||||
try:
|
||||
desc = arcpy.Describe(samples_path)
|
||||
if desc.dataType != 'FeatureClass':
|
||||
QMessageBox.warning(self, "输入错误", f"PH样点不是一个要素类:\n{samples_path}")
|
||||
return False
|
||||
except Exception as e:
|
||||
QMessageBox.warning(self, "输入错误", f"未知要素,请检查是否为有效要素类:\n{samples_path}\n错误: {e}")
|
||||
return False
|
||||
|
||||
# 重分类后酸化面要素验证
|
||||
acid_ph_path = os.path.join(self.input_workspace_edit.text(), self.acid_ph_edit.text())
|
||||
if not acid_ph_path or not arcpy.Exists(acid_ph_path):
|
||||
QMessageBox.warning(self, "输入错误", "酸化PH要素路径无效或不存在")
|
||||
return False
|
||||
try:
|
||||
desc = arcpy.Describe(acid_ph_path)
|
||||
if desc.dataType != 'FeatureClass':
|
||||
QMessageBox.warning(self, "输入错误", f"酸化PH不是一个要素类:\n{acid_ph_path}")
|
||||
return False
|
||||
except Exception as e:
|
||||
QMessageBox.warning(self, "输入错误", f"未知要素,请检查是否为有效要素类:\n{acid_ph_path}\n错误: {e}")
|
||||
return False
|
||||
|
||||
# 土壤类型验证
|
||||
trlx_path = os.path.join(self.input_workspace_edit.text(), self.soil_type_features_edit.text())
|
||||
if not self.soil_type_features_edit.text() or not arcpy.Exists(trlx_path):
|
||||
QMessageBox.warning(self, "输入错误", "土壤类型要素路径无效或不存在")
|
||||
return False
|
||||
try:
|
||||
desc = arcpy.Describe(trlx_path)
|
||||
if desc.dataType != 'FeatureClass':
|
||||
QMessageBox.warning(self, "输入错误", f"土壤类型不是一个要素类:\n{trlx_path}")
|
||||
return False
|
||||
except Exception as e:
|
||||
QMessageBox.warning(self, "输入错误", f"未知要素,请检查是否为有效要素类:\n{trlx_path}\n错误: {e}")
|
||||
return False
|
||||
|
||||
# 验证输入是否为栅格
|
||||
if not self.acid_raster_edit.text() or not self.assign_raster_edit.text():
|
||||
QMessageBox.warning(self, "输入错误", "请选择输入栅格")
|
||||
return False
|
||||
elif not arcpy.Exists(self.acid_raster_edit.text()) or not arcpy.Exists(self.assign_raster_edit.text()):
|
||||
QMessageBox.warning(self, "输入错误", "输入栅格不存在")
|
||||
return False
|
||||
|
||||
|
||||
return True
|
||||
|
||||
# 执行生成酸化统计表
|
||||
def on_generate_area_stat(self):
|
||||
"""执行生成面积统计表"""
|
||||
if not self.validate_inputs():
|
||||
return
|
||||
|
||||
try:
|
||||
if self.main_window and hasattr(self.main_window, 'save_settings'):
|
||||
self.main_window.update_settings()
|
||||
self.main_window.save_settings()
|
||||
settings_file = self.main_window.settings_file
|
||||
|
||||
params = {
|
||||
"settings_path": settings_file,
|
||||
}
|
||||
|
||||
task_id = self.script_runner.run_suanhua_stat(params)
|
||||
|
||||
if task_id:
|
||||
self.log_message(f"[GUI] 面积统计任务 {task_id} 已添加到列队")
|
||||
except Exception as e:
|
||||
error_msg = f"处理过程中出错: {str(e)}"
|
||||
QMessageBox.critical(self, "处理错误", error_msg)
|
||||
self.log_message(error_msg)
|
||||
|
||||
def get_acid_stat_settings(self):
|
||||
"""保存当前配置到JSON文件"""
|
||||
config = {
|
||||
"workspace_path": self.input_workspace_edit.text(),
|
||||
"batch_output_folder": self.batch_output_folder_edit.text(),
|
||||
"xzq_features": self.xzq_features_edit.text(),
|
||||
"dltb_features": self.dltb_features_edit.text(),
|
||||
"ph_samples": self.ph_samples_edit.text(),
|
||||
"acid_ph_features": self.acid_ph_edit.text(),
|
||||
"assign_raster": self.assign_raster_edit.text(),
|
||||
"acid_raster": self.acid_raster_edit.text(),
|
||||
"soil_type_features": self.soil_type_features_edit.text(),
|
||||
"xzqmc": self.input_xzqmc_edit.text()
|
||||
}
|
||||
|
||||
return config
|
||||
|
||||
def load_settings(self, settings):
|
||||
"""从字典加载配置"""
|
||||
try:
|
||||
# 批处理参数
|
||||
self.input_workspace_edit.setText(settings.get("workspace_path", ""))
|
||||
self.batch_output_folder_edit.setText(settings.get("batch_output_folder", ""))
|
||||
self.xzq_features_edit.setText(settings.get("xzq_features", ""))
|
||||
self.dltb_features_edit.setText(settings.get("dltb_features", ""))
|
||||
self.ph_samples_edit.setText(settings.get("ph_samples", ""))
|
||||
self.acid_ph_edit.setText(settings.get("acid_ph_features", ""))
|
||||
self.assign_raster_edit.setText(settings.get("assign_raster", ""))
|
||||
self.acid_raster_edit.setText(settings.get("acid_raster", ""))
|
||||
self.soil_type_features_edit.setText(settings.get("soil_type_features", ""))
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
QMessageBox.critical(self, "加载配置错误", f"加载配置时出错: {str(e)}")
|
||||
return False
|
||||
|
||||
def set_buttons_enabled(self, enabled):
|
||||
"""设置按钮是否可用"""
|
||||
self.generate_sh_stat_btn.setEnabled(enabled)
|
||||
|
||||
def on_script_started(self, task_id, task_description):
|
||||
"""脚本开始执行"""
|
||||
self.set_buttons_enabled(False)
|
||||
self.log_message(f"{task_id}: 正在运行 - {task_description}")
|
||||
|
||||
def on_script_finished(self, task_id:str, success:bool, message:str):
|
||||
"""脚本执行完成"""
|
||||
self.set_buttons_enabled(True)
|
||||
status = "完成" if success else "失败"
|
||||
self.log_message(f"[{task_id}] 脚本执行{status}: {message}")
|
||||
|
||||
def on_script_error(self,task_id, error_msg):
|
||||
"""脚本执行出错"""
|
||||
self.set_buttons_enabled(True)
|
||||
self.log_message(f"错误:{task_id}-{error_msg}")
|
||||
# QMessageBox.critical(self, "错误", error_msg)
|
||||
|
||||
def on_script_log(self, task_id, message):
|
||||
"""脚本输出日志"""
|
||||
self.log_message(f"{task_id}: {message}")
|
||||
|
||||
def log_message(self, message):
|
||||
"""日志输出"""
|
||||
if self.main_window and hasattr(self.main_window, 'log_signal'):
|
||||
self.main_window.log_signal.emit(message)
|
||||
else:
|
||||
print(message)
|
||||
|
||||
if __name__ == "__main__":
|
||||
from PyQt6.QtWidgets import QApplication
|
||||
import sys
|
||||
app = QApplication(sys.argv)
|
||||
window = AcidStatsTab()
|
||||
window.show()
|
||||
sys.exit(app.exec())
|
||||
Reference in New Issue
Block a user