113 lines
4.2 KiB
Python
113 lines
4.2 KiB
Python
import os
|
|
from threading import Thread
|
|
from rscder.gui.actions import ActionManager
|
|
from rscder.gui.layercombox import RasterLayerCombox, ResultPointLayerCombox
|
|
from rscder.plugins.basic import BasicPlugin
|
|
from PyQt5.QtWidgets import QAction, QDialog, QLabel, QHBoxLayout, QVBoxLayout, QPushButton
|
|
from PyQt5.QtCore import pyqtSignal
|
|
from PyQt5.QtGui import QIcon
|
|
from rscder.utils.icons import IconInstance
|
|
|
|
from rscder.utils.project import Project, ResultPointLayer, SingleBandRasterLayer
|
|
from osgeo import gdal
|
|
class TableResultDialog(QDialog):
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
|
|
self.setWindowTitle('表格结果')
|
|
self.setWindowIcon(IconInstance().LOGO)
|
|
|
|
self.layer_select = RasterLayerCombox(self)
|
|
hbox = QHBoxLayout()
|
|
hbox.addWidget(QLabel('二值化结果图层:'))
|
|
hbox.addWidget(self.layer_select)
|
|
|
|
self.ok_button = QPushButton('确定', self)
|
|
self.ok_button.setIcon(IconInstance().OK)
|
|
self.ok_button.clicked.connect(self.on_ok)
|
|
|
|
self.cancel_button = QPushButton('取消', self)
|
|
self.cancel_button.setIcon(IconInstance().CANCEL)
|
|
self.cancel_button.clicked.connect(self.on_cancel)
|
|
|
|
self.button_layout = QHBoxLayout()
|
|
self.button_layout.addWidget(self.ok_button)
|
|
self.button_layout.addWidget(self.cancel_button)
|
|
|
|
self.main_layout = QVBoxLayout()
|
|
self.main_layout.addLayout(hbox)
|
|
self.main_layout.addLayout(self.button_layout)
|
|
self.setLayout(self.main_layout)
|
|
|
|
def on_ok(self):
|
|
self.accept()
|
|
|
|
def on_cancel(self):
|
|
self.reject()
|
|
|
|
|
|
class TableResultPlugin(BasicPlugin):
|
|
|
|
@staticmethod
|
|
def info():
|
|
return {
|
|
'name': 'TableResult',
|
|
'author': 'RSC',
|
|
'version': '1.0.0',
|
|
'description': '表格结果'
|
|
}
|
|
|
|
def set_action(self):
|
|
self.action = QAction(IconInstance().VECTOR, '表格结果', self.mainwindow)
|
|
self.action.triggered.connect(self.show_dialog)
|
|
ActionManager().position_menu.addAction(self.action)
|
|
|
|
def run(self, layer:SingleBandRasterLayer):
|
|
self.send_message.emit('正在计算表格结果...')
|
|
if not isinstance(layer, SingleBandRasterLayer):
|
|
self.send_message.emit('请选择一个单波段栅格图层')
|
|
return
|
|
|
|
cell_size = layer.layer_parent.cell_size
|
|
ds = gdal.Open(layer.path)
|
|
xsize = ds.RasterXSize
|
|
ysize = ds.RasterYSize
|
|
geo = ds.GetGeoTransform()
|
|
|
|
out_csv = os.path.join(Project().other_path, f'{layer.name}_table_result.csv')
|
|
yblocks = ysize // cell_size[1] + 1
|
|
xblocks = xsize // cell_size[0] + 1
|
|
with open(out_csv, 'w') as f:
|
|
f.write('x,y,diff,status\n')
|
|
for j in range(yblocks):
|
|
block_xy = (0, j * cell_size[1])
|
|
block_size = (xsize, cell_size[1])
|
|
if block_xy[1] + block_size[1] > ysize:
|
|
block_size = (xsize, ysize - block_xy[1])
|
|
block_data = ds.ReadAsArray(*block_xy, *block_size)
|
|
for i in range(xblocks):
|
|
start_x = i * cell_size[0]
|
|
end_x = start_x + cell_size[0]
|
|
if end_x > xsize:
|
|
end_x = xsize
|
|
block_data_xy = block_data[:, start_x:end_x]
|
|
if block_data_xy.mean() > 0.5:
|
|
center_x = start_x + cell_size[0] // 2
|
|
center_y = j * cell_size[1] + cell_size[1] // 2
|
|
center_x = center_x * geo[1] + geo [0]
|
|
center_y = center_y * geo[5] + geo [3]
|
|
f.write(f'{center_x},{center_y},{block_data_xy.mean() * 100},1\n')
|
|
|
|
result_layer = ResultPointLayer(out_csv, enable=True, proj=layer.proj, geo=layer.geo)
|
|
layer.layer_parent.add_result_layer(result_layer)
|
|
self.send_message.emit('计算完成')
|
|
|
|
|
|
def show_dialog(self):
|
|
dialog = TableResultDialog()
|
|
if dialog.exec_() == QDialog.Accepted:
|
|
if dialog.layer_select.current_layer is not None:
|
|
t = Thread(target=self.run, args=(dialog.layer_select.current_layer,))
|
|
t.start()
|