From 872e45937ab942aabea9a08f442ea445efe2635a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E6=B2=88=E6=98=8A?= Date: Fri, 12 Aug 2022 17:14:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E4=B8=8D=E5=90=8C?= =?UTF-8?q?=E5=B0=BA=E5=BA=A6=E5=9B=BE=E5=83=8F=E7=9A=84=E5=8F=98=E5=8C=96?= =?UTF-8?q?=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/In_one/main.py | 575 +++++++++++++++++++----------------- plugins/change_rate/main.py | 9 +- plugins/evaluation/main.py | 5 +- plugins/export_to/main.py | 7 +- plugins/some_filter/main.py | 4 +- rscder/gui/actions.py | 12 +- rscder/gui/keygen.py | 4 +- rscder/gui/load.py | 151 +++------- rscder/gui/project.py | 4 +- rscder/utils/geomath.py | 19 ++ rscder/utils/project.py | 164 +++++++--- 11 files changed, 527 insertions(+), 427 deletions(-) create mode 100644 rscder/utils/geomath.py diff --git a/plugins/In_one/main.py b/plugins/In_one/main.py index f2ccb3f..f8174cc 100644 --- a/plugins/In_one/main.py +++ b/plugins/In_one/main.py @@ -1,5 +1,7 @@ +import copy as cp from asyncio.windows_events import NULL from concurrent.futures import thread +from copy import copy from email.policy import default import os import pdb @@ -13,260 +15,16 @@ from PyQt5.QtGui import QIcon,QPixmap from PyQt5.QtCore import Qt from rscder.gui.layercombox import LayerCombox,PairLayerCombox from rscder.utils.icons import IconInstance -from rscder.utils.project import Project, RasterLayer, SingleBandRasterLayer,ResultPointLayer +from rscder.utils.geomath import geo2imageRC, imageRC2geo +from rscder.utils.project import Project, RasterLayer, PairLayer,ResultPointLayer,MultiBandRasterLayer from In_one.otsu import OTSU from osgeo import gdal from plugins.In_one import pic import math from skimage.filters import rank from skimage.morphology import disk, rectangle -class LockerButton(QPushButton): - def __init__(self,parent=NULL): - super(LockerButton,self).__init__(parent) - m_imageLabel = QLabel(self) - m_imageLabel.setFixedWidth(20) - m_imageLabel.setScaledContents(True) - m_imageLabel.setStyleSheet("QLabel{background-color:transparent;}") - m_textLabel = QLabel(self) - m_textLabel.setStyleSheet("QLabel{background-color:transparent;}") - self.m_imageLabel=m_imageLabel - self.m_textLabel=m_textLabel - self.hide_=1 - mainLayout = QHBoxLayout() - - mainLayout.addWidget(self.m_imageLabel) - mainLayout.addWidget(self.m_textLabel) - mainLayout.setContentsMargins(0,0,0,0) - mainLayout.setSpacing(0) - self.setLayout(mainLayout) - def SetImageLabel(self, pixmap:QPixmap): - self.m_imageLabel.setPixmap(pixmap) - def SetTextLabel(self, text): - self.m_textLabel.setText(text) -class selectCombox(QComboBox): - def __init__(self, parent,list:list,default='--') : - super(selectCombox,self).__init__(parent) - self.choose=None - self.list=list - self.default=default - self.addItem(default, None) - self.addItems(list) - self.currentIndexChanged.connect(self.on_change) - - def on_change(self,index): - if index == 0: - self.choose=self.default - else: - self.choose=self.list[index-1] - # print(self.choose) - -class AllInOne(QDialog): - def __init__(self, pre,cd,threshold,parent=None): - super(AllInOne, self).__init__(parent) - self.setWindowTitle('变化检测') - self.setWindowIcon(IconInstance().LOGO) - self.pre=pre#['均值滤波','test滤波'] - self.cd=cd#['差分法','test法'] - self.threshold=threshold#['OTSU'] - self.initUI() - - def initUI(self): - #图层 - self.layer_combox = PairLayerCombox(self) - layerbox = QHBoxLayout() - layerbox.addWidget(self.layer_combox) - - #预处理 - filterWeight=QWidget(self) - filterlayout=QVBoxLayout() - filerButton =LockerButton(filterWeight) - filerButton.setObjectName("filerButton") - filerButton.SetTextLabel("预处理") - filerButton.SetImageLabel(QPixmap('plugins/In_one/pic/箭头_列表展开.png')) - filerButton.setStyleSheet("#filerButton{background-color:transparent;border:none;}" - "#filerButton:hover{background-color:rgba(195,195,195,0.4);border:none;}") - self.pre_select=selectCombox(self,self.pre) - - x_size_input = QLineEdit(self) - x_size_input.setText('3') - y_size_input = QLineEdit(self) - y_size_input.setText('3') - size_label = QLabel(self) - size_label.setText('窗口大小:') - time_label = QLabel(self) - time_label.setText('X') - self.x_size_input = x_size_input - self.y_size_input = y_size_input - hlayout1 = QHBoxLayout() - hlayout1.addWidget(size_label) - hlayout1.addWidget(x_size_input) - hlayout1.addWidget(time_label) - hlayout1.addWidget(y_size_input) - vlayout = QVBoxLayout() - vlayout.addWidget(self.pre_select) - vlayout.addLayout(hlayout1) - filterWeight.setLayout(vlayout) - filterlayout.addWidget(filerButton) - filterlayout.addWidget(filterWeight) - #变化检测 - changelayout=QVBoxLayout() - changeWeight=QWidget(self) - changeButton =LockerButton(changeWeight) - changeButton.setObjectName("changeButton") - changeButton.SetTextLabel("变化检测") - changeButton.SetImageLabel(QPixmap('plugins/In_one/pic/箭头_列表展开.png')) - changeButton.setStyleSheet("#changeButton{background-color:transparent;border:none;}" - "#changeButton:hover{background-color:rgba(195,195,195,0.4);border:none;}") - changeWeightlayout=QVBoxLayout() - self.cd_select=selectCombox(self,self.cd) - changeWeightlayout.addWidget(self.cd_select) - changeWeight.setLayout(changeWeightlayout) - changelayout.addWidget(changeButton) - changelayout.addWidget(changeWeight) - - #阈值处理 - thresholdlayout=QVBoxLayout() - thresholdWeight=QWidget(self) - thresholdButton =LockerButton(thresholdWeight) - thresholdButton.setObjectName("thresholdButton") - thresholdButton.SetTextLabel("阈值处理") - thresholdButton.SetImageLabel(QPixmap('plugins/In_one/pic/箭头_列表展开.png')) - thresholdButton.setStyleSheet("#thresholdButton{background-color:transparent;border:none;}" - "#thresholdButton:hover{background-color:rgba(195,195,195,0.4);border:none;}") - self.threshold_select=selectCombox(self,self.threshold,default='手动阈值') - self.threshold_input=QLineEdit(self) - self.threshold_input.setText('0.5') - self.threshold_select.currentIndexChanged.connect(lambda index:self.hide_(self.threshold_input,index==0)) - thresholdWeightlayout=QVBoxLayout() - thresholdWeightlayout.addWidget(self.threshold_select) - thresholdWeightlayout.addWidget(self.threshold_input) - - thresholdWeight.setLayout(thresholdWeightlayout) - thresholdlayout.addWidget(thresholdButton) - thresholdlayout.addWidget(thresholdWeight) - - #确认 - oklayout=QHBoxLayout() - self.ok_button = QPushButton('确定', self) - self.ok_button.setIcon(IconInstance().OK) - self.ok_button.clicked.connect(self.accept) - - self.cancel_button = QPushButton('取消', self) - self.cancel_button.setIcon(IconInstance().CANCEL) - self.cancel_button.clicked.connect(self.reject) - oklayout.addWidget(self.ok_button) - oklayout.addWidget(self.cancel_button) - - totalvlayout=QVBoxLayout() - totalvlayout.addLayout(layerbox) - totalvlayout.addLayout(filterlayout) - totalvlayout.addLayout(changelayout) - totalvlayout.addLayout(thresholdlayout) - totalvlayout.addLayout(oklayout) - totalvlayout.addStretch() - - self.setLayout(totalvlayout) - - - filerButton.clicked.connect(lambda: self.hide(filerButton,filterWeight)) - changeButton.clicked.connect(lambda: self.hide(changeButton,changeWeight)) - thresholdButton.clicked.connect(lambda: self.hide(thresholdButton,thresholdWeight)) - - - - def hide(self,button:LockerButton,weight:QWidget): - if ((button.hide_)%2)==1: - weight.setVisible(False) - button.SetImageLabel(QPixmap('plugins/In_one/pic/箭头_列表向右.png')) - else: - weight.setVisible(True) - button.SetImageLabel(QPixmap('plugins/In_one/pic/箭头_列表展开.png')) - button.hide_=(button.hide_)%2+1 - def hide_(self,widget:QWidget,h:bool): - if h: - widget.setVisible(True) - else: - widget.setVisible(False) - def hideWidget(self,widget:QWidget): - if widget.isVisible: - widget.setVisible(False) - else: - widget.setVisible(True) -class InOnePlugin(BasicPlugin): - pre=['均值滤波'] - cd=['差分法'] - threshold=['OTSU阈值'] - - - @staticmethod - def info(): - return { - 'name': 'AllinOne', - 'description': 'AllinOne', - 'author': 'RSCDER', - 'version': '1.0.0', - } - - def set_action(self): - - basic_diff_method_in_one = QAction('差分法') - # ActionManager().change_detection_menu.addAction(basic_diff_method_in_one) - ActionManager().unsupervised_menu.addAction(basic_diff_method_in_one) - self.basic_diff_method_in_one = basic_diff_method_in_one - basic_diff_method_in_one.triggered.connect(self.run) - - - def run(self): - myDialog=AllInOne(self.pre,self.cd,self.threshold,self.mainwindow) - myDialog.show() - if myDialog.exec_()==QDialog.Accepted: - t=Thread(target=self.run_alg,args=(myDialog,)) - t.start() - - def run_alg(self,w:AllInOne): - dict={} - layer1=w.layer_combox.layer1 - layer2=w.layer_combox.layer2 - if not layer1.compare(layer2): - self.send_message.emit('两个图层的尺寸不同') - return - pth1 = w.layer_combox.layer1.path - pth2 = w.layer_combox.layer2.path - name=layer1.layer_parent.name - if w.pre_select.choose==self.pre[0]: - - pth1=Meanfilter(w.x_size_input.text(),w.y_size_input.text(),w.layer_combox.layer1) - self.send_message.emit('均值滤波图像{}'.format(w.layer_combox.layer1.name)) - pth2=Meanfilter(w.x_size_input.text(),w.y_size_input.text(),w.layer_combox.layer2) - self.send_message.emit('均值滤波图像{}'.format(w.layer_combox.layer2.name)) - name=name+'_mean_filter' - dict['预处理']=['均值滤波','|'.format(pth1,pth2)] - else: - pass - - cdpth=None - if w.cd_select.choose==self.cd[0]: - cdpth=basic_cd(pth1,pth2,w.layer_combox.layer1.layer_parent,self.send_message) - name += '_basic_cd' - dict['变化检测算法']=['差分法',cdpth] - else: - pass - - thpth=None - if w.threshold_select.choose==self.threshold[0]: - thpth,gap=otsu(cdpth,w.layer_combox.layer1.layer_parent.name,self.send_message) - name+='_otsu' - dict['后处理']=['OTSU阈值',gap,cdpth] - elif w.threshold_select.choose=='手动阈值': - thpth=thresh(cdpth,float(w.threshold_input.text()),w.layer_combox.layer1.layer_parent.name,self.send_message) - dict['后处理']=['手动阈值',[float(w.threshold_input.text())],thpth] - else: - pass - - table_layer(thpth,layer1,name,self.send_message,dict) - -def Meanfilter(x_size,y_size,layer:RasterLayer): +def Meanfilter(x_size,y_size,layer:MultiBandRasterLayer): x_size = int(x_size) y_size = int(y_size) pth = layer.path @@ -294,34 +52,53 @@ def Meanfilter(x_size,y_size,layer:RasterLayer): del ds return out_path -def basic_cd(pth1,pth2,layer_parent,send_message): - - ds1 = gdal.Open(pth1) - ds2 = gdal.Open(pth2) +def basic_cd(pth1:str,pth2:str,layer_parent:PairLayer,send_message): + ds1:gdal.Dataset=gdal.Open(pth1) + ds2:gdal.Dataset=gdal.Open(pth2) + cell_size = layer_parent.cell_size - xsize = ds1.RasterXSize - ysize = ds1.RasterYSize + xsize = layer_parent.size[0] + ysize = layer_parent.size[1] + band = ds1.RasterCount yblocks = ysize // cell_size[1] driver = gdal.GetDriverByName('GTiff') out_tif = os.path.join(Project().cmi_path, 'temp.tif') out_ds = driver.Create(out_tif, xsize, ysize, 1, gdal.GDT_Float32) - out_ds.SetGeoTransform(ds1.GetGeoTransform()) - out_ds.SetProjection(ds1.GetProjection()) + geo=layer_parent.grid.geo + proj=layer_parent.grid.proj + out_ds.SetGeoTransform(geo) + out_ds.SetProjection(proj) + max_diff = 0 min_diff = math.inf - for j in range(yblocks + 1): + + start1x,start1y=geo2imageRC(ds1.GetGeoTransform(),layer_parent.mask.xy[0],layer_parent.mask.xy[1]) + end1x,end1y=geo2imageRC(ds1.GetGeoTransform(),layer_parent.mask.xy[2],layer_parent.mask.xy[3]) + + start2x,start2y=geo2imageRC(ds2.GetGeoTransform(),layer_parent.mask.xy[0],layer_parent.mask.xy[1]) + end2x,end2y=geo2imageRC(ds2.GetGeoTransform(),layer_parent.mask.xy[2],layer_parent.mask.xy[3]) + + for j in range(yblocks + 1):#该改这里了 send_message.emit(f'计算{j}/{yblocks}') - block_xy = (0, j * cell_size[1]) - if block_xy[1] > ysize: + block_xy1 = (start1x, start1y+j * cell_size[1]) + block_xy2 = (start2x,start2y+j*cell_size[1]) + block_xy=(0,j * cell_size[1]) + if block_xy1[1] > end1y or block_xy2[1] > end2y: break - block_size = (xsize, cell_size[1]) + block_size=(xsize, cell_size[1]) + block_size1 = (xsize, cell_size[1]) + block_size2 = (xsize,cell_size[1]) if block_xy[1] + block_size[1] > ysize: block_size = (xsize, ysize - block_xy[1]) - block_data1 = ds1.ReadAsArray(*block_xy, *block_size) - block_data2 = ds2.ReadAsArray(*block_xy, *block_size) + if block_xy1[1] + block_size1[1] > end1y: + block_size1 = (xsize,end1y - block_xy1[1]) + if block_xy2[1] + block_size2[1] > end2y: + block_size2 = (xsize, end2y - block_xy2[1]) + block_data1 = ds1.ReadAsArray(*block_xy1, *block_size1) + block_data2 = ds2.ReadAsArray(*block_xy2, *block_size2) if band == 1: block_data1 = block_data1[None, ...] @@ -336,16 +113,17 @@ def basic_cd(pth1,pth2,layer_parent,send_message): out_ds.GetRasterBand(1).WriteArray(block_diff, *block_xy) send_message.emit(f'完成{j}/{yblocks}') - + del ds2 + del ds1 out_ds.FlushCache() del out_ds send_message.emit('归一化概率中...') temp_in_ds = gdal.Open(out_tif) - + out_normal_tif = os.path.join(Project().cmi_path, '{}_{}_cmi.tif'.format(layer_parent.name, int(np.random.rand() * 100000))) out_normal_ds = driver.Create(out_normal_tif, xsize, ysize, 1, gdal.GDT_Byte) - out_normal_ds.SetGeoTransform(ds1.GetGeoTransform()) - out_normal_ds.SetProjection(ds1.GetProjection()) + out_normal_ds.SetGeoTransform(geo) + out_normal_ds.SetProjection(proj) # hist = np.zeros(256, dtype=np.int32) for j in range(yblocks+1): block_xy = (0, j * cell_size[1]) @@ -501,3 +279,270 @@ def table_layer(pth,layer,name,send_message,dict): # print(result_layer.result_path) layer.layer_parent.add_result_layer(result_layer) send_message.emit('计算完成') + +class LockerButton(QPushButton): + def __init__(self,parent=NULL): + super(LockerButton,self).__init__(parent) + m_imageLabel = QLabel(self) + m_imageLabel.setFixedWidth(20) + m_imageLabel.setScaledContents(True) + m_imageLabel.setStyleSheet("QLabel{background-color:transparent;}") + m_textLabel = QLabel(self) + m_textLabel.setStyleSheet("QLabel{background-color:transparent;}") + self.m_imageLabel=m_imageLabel + self.m_textLabel=m_textLabel + self.hide_=1 + mainLayout = QHBoxLayout() + + mainLayout.addWidget(self.m_imageLabel) + mainLayout.addWidget(self.m_textLabel) + mainLayout.setContentsMargins(0,0,0,0) + mainLayout.setSpacing(0) + self.setLayout(mainLayout) + def SetImageLabel(self, pixmap:QPixmap): + self.m_imageLabel.setPixmap(pixmap) + def SetTextLabel(self, text): + self.m_textLabel.setText(text) + + +class selectCombox(QComboBox): + def __init__(self, parent,list:list,default='--') : + super(selectCombox,self).__init__(parent) + self.choose=None + self.list=list + self.default=default + self.addItem(default, None) + self.addItems(list) + self.currentIndexChanged.connect(self.on_change) + + def on_change(self,index): + if index == 0: + self.choose=self.default + else: + self.choose=self.list[index-1] + # print(self.choose) + +class AllInOne(QDialog): + def __init__(self, pre,cd,threshold,parent=None): + super(AllInOne, self).__init__(parent) + self.setWindowTitle('变化检测') + self.setWindowIcon(IconInstance().LOGO) + self.pre=pre#['均值滤波','test滤波'] + self.cd=cd#['差分法','test法'] + self.threshold=threshold#['OTSU'] + self.initUI() + + def initUI(self): + #图层 + self.layer_combox = PairLayerCombox(self) + layerbox = QHBoxLayout() + layerbox.addWidget(self.layer_combox) + + #预处理 + filterWeight=QWidget(self) + filterlayout=QVBoxLayout() + filerButton =LockerButton(filterWeight) + filerButton.setObjectName("filerButton") + filerButton.SetTextLabel("预处理") + filerButton.SetImageLabel(QPixmap('plugins/In_one/pic/箭头_列表展开.png')) + filerButton.setStyleSheet("#filerButton{background-color:transparent;border:none;}" + "#filerButton:hover{background-color:rgba(195,195,195,0.4);border:none;}") + self.pre_select=selectCombox(self,self.pre) + + x_size_input = QLineEdit(self) + x_size_input.setText('3') + y_size_input = QLineEdit(self) + y_size_input.setText('3') + size_label = QLabel(self) + size_label.setText('窗口大小:') + time_label = QLabel(self) + time_label.setText('X') + self.x_size_input = x_size_input + self.y_size_input = y_size_input + hlayout1 = QHBoxLayout() + hlayout1.addWidget(size_label) + hlayout1.addWidget(x_size_input) + hlayout1.addWidget(time_label) + hlayout1.addWidget(y_size_input) + vlayout = QVBoxLayout() + vlayout.addWidget(self.pre_select) + vlayout.addLayout(hlayout1) + filterWeight.setLayout(vlayout) + filterlayout.addWidget(filerButton) + filterlayout.addWidget(filterWeight) + #变化检测 + changelayout=QVBoxLayout() + changeWeight=QWidget(self) + changeButton =LockerButton(changeWeight) + changeButton.setObjectName("changeButton") + changeButton.SetTextLabel("变化检测") + changeButton.SetImageLabel(QPixmap('plugins/In_one/pic/箭头_列表展开.png')) + changeButton.setStyleSheet("#changeButton{background-color:transparent;border:none;}" + "#changeButton:hover{background-color:rgba(195,195,195,0.4);border:none;}") + changeWeightlayout=QVBoxLayout() + self.cd_select=selectCombox(self,self.cd) + changeWeightlayout.addWidget(self.cd_select) + changeWeight.setLayout(changeWeightlayout) + changelayout.addWidget(changeButton) + changelayout.addWidget(changeWeight) + + #阈值处理 + thresholdlayout=QVBoxLayout() + thresholdWeight=QWidget(self) + thresholdButton =LockerButton(thresholdWeight) + thresholdButton.setObjectName("thresholdButton") + thresholdButton.SetTextLabel("阈值处理") + thresholdButton.SetImageLabel(QPixmap('plugins/In_one/pic/箭头_列表展开.png')) + thresholdButton.setStyleSheet("#thresholdButton{background-color:transparent;border:none;}" + "#thresholdButton:hover{background-color:rgba(195,195,195,0.4);border:none;}") + self.threshold_select=selectCombox(self,self.threshold,default='手动阈值') + self.threshold_input=QLineEdit(self) + self.threshold_input.setText('0.5') + self.threshold_select.currentIndexChanged.connect(lambda index:self.hide_(self.threshold_input,index==0)) + thresholdWeightlayout=QVBoxLayout() + thresholdWeightlayout.addWidget(self.threshold_select) + thresholdWeightlayout.addWidget(self.threshold_input) + + thresholdWeight.setLayout(thresholdWeightlayout) + thresholdlayout.addWidget(thresholdButton) + thresholdlayout.addWidget(thresholdWeight) + + #确认 + oklayout=QHBoxLayout() + self.ok_button = QPushButton('确定', self) + self.ok_button.setIcon(IconInstance().OK) + self.ok_button.clicked.connect(self.accept) + + self.cancel_button = QPushButton('取消', self) + self.cancel_button.setIcon(IconInstance().CANCEL) + self.cancel_button.clicked.connect(self.reject) + oklayout.addWidget(self.ok_button,0,alignment=Qt.AlignHCenter) + oklayout.addWidget(self.cancel_button,0,alignment=Qt.AlignHCenter) + + + totalvlayout=QVBoxLayout() + totalvlayout.addLayout(layerbox) + totalvlayout.addLayout(filterlayout) + totalvlayout.addLayout(changelayout) + totalvlayout.addLayout(thresholdlayout) + totalvlayout.addLayout(oklayout) + totalvlayout.addStretch() + + self.setLayout(totalvlayout) + + + filerButton.clicked.connect(lambda: self.hide(filerButton,filterWeight)) + changeButton.clicked.connect(lambda: self.hide(changeButton,changeWeight)) + thresholdButton.clicked.connect(lambda: self.hide(thresholdButton,thresholdWeight)) + + + + def hide(self,button:LockerButton,weight:QWidget): + if ((button.hide_)%2)==1: + weight.setVisible(False) + button.SetImageLabel(QPixmap('plugins/In_one/pic/箭头_列表向右.png')) + else: + weight.setVisible(True) + button.SetImageLabel(QPixmap('plugins/In_one/pic/箭头_列表展开.png')) + button.hide_=(button.hide_)%2+1 + def hide_(self,widget:QWidget,h:bool): + if h: + widget.setVisible(True) + else: + widget.setVisible(False) + def hideWidget(self,widget:QWidget): + if widget.isVisible: + widget.setVisible(False) + else: + widget.setVisible(True) + @property + def param(self): + class param(object): + pass + p=param() + p.pre=self.pre + p.cd=self.cd + p.threshold=self.threshold + p.layer_combox=self.layer_combox + p.pre_select=self.pre_select + p.x_size_input=self.x_size_input + p.y_size_input=self.y_size_input + p.threshold_select=self.threshold_select + p.threshold_input=self.threshold_input + p.cd_select=self.cd_select + return p +class InOnePlugin(BasicPlugin): + pre={"均值滤波":Meanfilter}#可添加其他方法 + cd={'差分法':basic_cd}#可添加其他方法 + threshold={'OTSU阈值':otsu}#可添加其他方法 + + + @staticmethod + def info(): + return { + 'name': 'AllinOne', + 'description': 'AllinOne', + 'author': 'RSCDER', + 'version': '1.0.0', + } + + def set_action(self): + + basic_diff_method_in_one = QAction('差分法') + # ActionManager().change_detection_menu.addAction(basic_diff_method_in_one) + ActionManager().unsupervised_menu.addAction(basic_diff_method_in_one) + self.basic_diff_method_in_one = basic_diff_method_in_one + basic_diff_method_in_one.triggered.connect(self.run) + + + def run(self): + myDialog=AllInOne(list(self.pre.keys()),list(self.cd.keys()),list(self.threshold.keys()),self.mainwindow) + myDialog.show() + if myDialog.exec_()==QDialog.Accepted: + w=myDialog.param + t=Thread(target=self.run_alg,args=(w,)) + t.start() + + def run_alg(self,w:AllInOne): + dict={} + layer1=w.layer_combox.layer1 + + + pth1 = w.layer_combox.layer1.path + pth2 = w.layer_combox.layer2.path + name=layer1.layer_parent.name + # 预处理 + # 若添加的预处理函数接口相同,则无需判断是哪种方法 + # if w.pre_select.choose==self.pre.keys()[0]: + # pass + # el + preKey=w.pre_select.choose + pth1=self.pre[preKey](w.x_size_input.text(),w.y_size_input.text(),w.layer_combox.layer1) + self.send_message.emit('{}图像{}'.format(preKey,w.layer_combox.layer1.name)) + pth2=self.pre[preKey](w.x_size_input.text(),w.y_size_input.text(),w.layer_combox.layer2) + self.send_message.emit('{}图像{}'.format(preKey,w.layer_combox.layer2.name)) + name=name+'_mean_filter' + dict['预处理']=[preKey,'|'.format(pth1,pth2)] + + + cdpth=None + #变化检测 + # if w.cd_select.choose==self.cd[0]: + cdKey=w.cd_select.choose + cdpth=self.cd[cdKey](pth1,pth2,w.layer_combox.layer1.layer_parent,self.send_message) + name += '_basic_cd' + dict['变化检测算法']=[cdKey,cdpth] + + #阈值处理 + #例如手动阈值和otsu参数不同,则要做区分 + thpth=None + if w.threshold_select.choose=='手动阈值': + thpth=thresh(cdpth,float(w.threshold_input.text()),w.layer_combox.layer1.layer_parent.name,self.send_message) + dict['后处理']=['手动阈值',[float(w.threshold_input.text())],thpth] + else: + thpth,gap=otsu(cdpth,w.layer_combox.layer1.layer_parent.name,self.send_message) + name+='_otsu' + dict['后处理']=['OTSU阈值',gap,cdpth] + + table_layer(thpth,layer1,name,self.send_message,dict) + diff --git a/plugins/change_rate/main.py b/plugins/change_rate/main.py index e968ffe..55fcf2d 100644 --- a/plugins/change_rate/main.py +++ b/plugins/change_rate/main.py @@ -42,8 +42,13 @@ class RateSetdialog(QDialog): 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) + okl=QHBoxLayout() + okl.addWidget(self.ok_button,alignment=Qt.AlignCenter) + cll=QHBoxLayout() + cll.addWidget(self.cancel_button,alignment=Qt.AlignCenter) + self.button_layout.addLayout(okl) + self.button_layout.addLayout(cll) + vlayout=QVBoxLayout() vlayout.addLayout(h1) vlayout.addWidget(QLabel('设置阈值')) diff --git a/plugins/evaluation/main.py b/plugins/evaluation/main.py index 5137f0d..c22e687 100644 --- a/plugins/evaluation/main.py +++ b/plugins/evaluation/main.py @@ -53,10 +53,9 @@ class EvalutationDialog(QDialog): 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.button_layout.addWidget(self.ok_button,0,alignment=Qt.AlignHCenter) + self.button_layout.addLayout(self.cancel_button,0,alignment=Qt.AlignHCenter) self.main_layout = QVBoxLayout() self.main_layout.addLayout(hbox1) diff --git a/plugins/export_to/main.py b/plugins/export_to/main.py index 3eb1f15..5161dcf 100644 --- a/plugins/export_to/main.py +++ b/plugins/export_to/main.py @@ -5,6 +5,7 @@ from rscder.utils.project import Project, PairLayer, ResultPointLayer from rscder.plugins.basic import BasicPlugin from PyQt5.QtWidgets import QDialog, QHBoxLayout, QFileDialog, QComboBox, QVBoxLayout, QPushButton, QLabel, QLineEdit, QAction from PyQt5.QtGui import QIcon +from PyQt5.QtCore import Qt class ExportDialog(QDialog): def __init__(self, parent=None): @@ -60,9 +61,9 @@ class ExportDialog(QDialog): hbox2.addWidget(out_path_btn) hbox3 = QHBoxLayout() - hbox3.addWidget(ok_btn) - hbox3.addWidget(cancel_btn) - + hbox3.addWidget(ok_btn,0,alignment=Qt.AlignHCenter) + hbox3.addWidget(cancel_btn,0,alignment=Qt.AlignHCenter) + vbox = QVBoxLayout() vbox.addLayout(hbox1) vbox.addLayout(hbox2) diff --git a/plugins/some_filter/main.py b/plugins/some_filter/main.py index 8a3342b..a6523cd 100644 --- a/plugins/some_filter/main.py +++ b/plugins/some_filter/main.py @@ -61,8 +61,8 @@ class FilterSetting(QDialog): cancel_button.clicked.connect(self.reject) hlayout2 = QtWidgets.QHBoxLayout() - hlayout2.addWidget(ok_button) - hlayout2.addWidget(cancel_button) + hlayout2.addWidget(ok_button,0,alignment=Qt.AlignHCenter) + hlayout2.addWidget(cancel_button,0,alignment=Qt.AlignHCenter) vlayout = QtWidgets.QVBoxLayout() vlayout.addLayout(hbox) diff --git a/rscder/gui/actions.py b/rscder/gui/actions.py index a0d50b0..a13b031 100644 --- a/rscder/gui/actions.py +++ b/rscder/gui/actions.py @@ -20,12 +20,12 @@ class ActionManager(QtCore.QObject): instance = None def __init__(self, - double_map, - layer_tree, - follow_box, - result_box, - message_box, - parent=None): + double_map, + layer_tree, + follow_box, + result_box, + message_box, + parent=None): super().__init__(parent) self.w_parent = parent self.actions = {} diff --git a/rscder/gui/keygen.py b/rscder/gui/keygen.py index 6fd1298..ab26f78 100644 --- a/rscder/gui/keygen.py +++ b/rscder/gui/keygen.py @@ -47,8 +47,8 @@ class LicenseGen(QDialog): self.btn_cancel.clicked.connect(self.reject) hbox4 = QHBoxLayout() - hbox4.addWidget(self.btn_generate, alignment = QtCore.Qt.AlignRight, stretch= 0) - hbox4.addWidget(self.btn_cancel, alignment = QtCore.Qt.AlignRight, stretch= 0) + hbox4.addWidget(self.btn_generate, alignment = QtCore.Qt.AlignCenter, stretch= 0) + hbox4.addWidget(self.btn_cancel, alignment = QtCore.Qt.AlignCenter, stretch= 0) vbox = QVBoxLayout() vbox.addLayout(hbox1) diff --git a/rscder/gui/load.py b/rscder/gui/load.py index fc5468f..1bfab0f 100644 --- a/rscder/gui/load.py +++ b/rscder/gui/load.py @@ -1,10 +1,11 @@ from colorsys import hls_to_rgb import os +from turtle import width from osgeo import gdal from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow, QToolBox from PyQt5.QtWidgets import QDialog, QFileDialog, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QLabel, QMessageBox,QSpacerItem from PyQt5.QtCore import Qt, QSize,QSettings,pyqtSignal,QThread -from PyQt5.QtGui import QIcon,QColor +from PyQt5.QtGui import QIcon,QColor,QPalette,QPixmap from PyQt5 import QtGui from threading import Thread from rscder.utils.icons import IconInstance @@ -38,6 +39,8 @@ class loader(QDialog): signal1=pyqtSignal(str) def __init__(self, parent=None) -> None: super().__init__(parent) + self.left_layer=None + self.right_layer=None self.setWindowTitle('载入数据') self.setWindowIcon(IconInstance().DATA_LOAD) self.pyramid:bool=False @@ -46,18 +49,20 @@ class loader(QDialog): self.path1='' self.path2='' self.bands=['red:','green:','blue:','NIR:'] - self.bandsorder=[3,2,1,4] - self.mapcanva1 = QgsMapCanvas(self) - self.mapcanva2 = QgsMapCanvas(self) - self.mapcanva1.setCanvasColor(QColor(0, 0, 0)) - self.mapcanva2.setCanvasColor(QColor(0, 0, 0)) - self.mapcanva1.setFixedWidth(200) - self.mapcanva1.setFixedHeight(200) - self.mapcanva2.setFixedWidth(200) - self.mapcanva2.setFixedHeight(200) + self.bandsorder=[1,2,3,4] + + self.left_map=QLabel() + self.left_map.setFixedSize(200,200) + self.left_map.setAutoFillBackground(True) + self.left_map.setBackgroundRole(QPalette.Dark) + + self.right_map=QLabel() + self.right_map.setFixedSize(200,200) + self.right_map.setAutoFillBackground(True) + self.right_map.setBackgroundRole(QPalette.Dark) maplayout=QHBoxLayout() - maplayout.addWidget(self.mapcanva1) - maplayout.addWidget(self.mapcanva2) + maplayout.addWidget(self.left_map) + maplayout.addWidget(self.right_map) path1_label = QLabel('时相1影像:') path1_label.setFixedWidth(60) @@ -148,8 +153,8 @@ class loader(QDialog): button_layout = QHBoxLayout() button_layout.setDirection(QHBoxLayout.RightToLeft) - button_layout.addWidget(cancel_button, 0, Qt.AlignRight) - button_layout.addWidget(ok_button, 0, Qt.AlignRight) + button_layout.addWidget(cancel_button, 0, Qt.AlignCenter) + button_layout.addWidget(ok_button, 0, Qt.AlignCenter) main_layout = QVBoxLayout() main_layout.addLayout(path1_layout) @@ -171,24 +176,23 @@ class loader(QDialog): if result==QMessageBox.Yes: progress1:QDialog=progressDialog(self,'加载时相一') progress1.setModal(False) - self.temp1=os.path.join(Project().other_path,'temp1.tif') - t1=GdalPreviewImage(self.path1,self.temp1,1024,self.parent()) - # t1.started.connect(progress1.show) - t1.finished.connect(self.loadfile1) - t1.finished.connect(lambda :self.setlabel(progress1) ) + self.left_layer=MultiBandRasterLayer(path=self.path1) + t1=GdalPreviewImage(self.left_layer,self.left_map,width=200,parent=self.parent()) + t1.finished.connect(lambda :self.setlabel(progress1)) t2=build_pyramids_overviews(self.path1,self.parent()) t2.finished.connect(progress1.hide) - t1.start() t1.finished.connect(t2.start) + t1.finished.connect(lambda : self.open1.setEnabled(True)) + t1.start() # t2.start() progress1.show() else: progress1=progressDialog(self,'加载时相一') progress1.setModal(False) - self.temp1=os.path.join(Project().other_path,'temp1.tif') - t1=GdalPreviewImage(self.path1,self.temp1,1024,self.parent()) + self.left_layer=MultiBandRasterLayer(path=self.path1) + t1=GdalPreviewImage(self.left_layer,self.left_map,width=200,parent=self.parent()) # t1.started.connect(progress1.show) - t1.finished.connect(self.loadfile1) + t1.finished.connect(lambda : self.open1.setEnabled(True)) t1.finished.connect(progress1.hide) t1.start() progress1.show() @@ -196,14 +200,7 @@ class loader(QDialog): except: return - def loadfile1(self): - try: - self.left_layer=MultiBandRasterLayer(path=self.temp1) - self.mapcanva1.setLayers([self.left_layer.layer]) - self.mapcanva1.zoomToFeatureExtent(self.left_layer.layer.extent()) - self.open1.setEnabled(True) - except: - return + def open_file2(self): path2 = QFileDialog.getOpenFileNames(self, '打开数据2', Settings.General().last_path, '*.*') if path2[0]!='': @@ -216,12 +213,14 @@ class loader(QDialog): progress2=progressDialog(self,'加载时相二') progress2.setModal(False) # progress1.show - self.temp2=os.path.join(Project().other_path,'temp2.tif') - t1=GdalPreviewImage(self.path2,self.temp2,1024,self.parent()) - + self.right_layer=MultiBandRasterLayer(path=self.path2) + + t1=GdalPreviewImage(self.right_layer,self.right_map,width=200,parent=self.parent()) + # t1.started.connect(progress1.show) - t1.finished.connect(self.loadfile2) + t1.finished.connect(lambda :self.open2.setEnabled(True)) t1.finished.connect(lambda :self.setlabel(progress2)) + t2=build_pyramids_overviews(self.path2,self.parent()) t2.finished.connect(progress2.hide) t1.start() @@ -230,24 +229,15 @@ class loader(QDialog): else: progress2=progressDialog(self,'加载时相二') progress2.setModal(False) - self.temp2=os.path.join(Project().other_path,'temp2.tif') - t1=GdalPreviewImage(self.path2,self.temp2,1024,self.parent()) + self.right_layer=MultiBandRasterLayer(path=self.path2) + t1=GdalPreviewImage(self.right_layer,self.right_map,width=200,parent=self.parent()) + # t1.started.connect(progress1.show) - t1.finished.connect(self.loadfile2) + t1.finished.connect(lambda :self.open2.setEnabled(True)) t1.finished.connect(progress2.hide) t1.start() progress2.show() - - - def loadfile2(self): - try: - self.right_layer=MultiBandRasterLayer(path=self.temp2) - self.mapcanva2.setLayers([self.right_layer.layer]) - self.mapcanva2.zoomToFeatureExtent(self.right_layer.layer.extent()) - self.open2.setEnabled(True) - except: - return def ok(self): self.bandsorder1=[int(q.text()) for q in self.style1_inputs ] self.style1={'r':self.bandsorder1[0],'g':self.bandsorder1[1],'b':self.bandsorder1[2],'NIR':self.bandsorder1[3]} @@ -265,8 +255,7 @@ class loader(QDialog): def cancel(self): self.reject() - def open_alg(self,path): - pass + def setlabel(self,s): try: s.setlabel('创建影像金字塔..') @@ -276,72 +265,22 @@ class loader(QDialog): self.bandsorder1=[int(q.text()) for q in self.style1_inputs ] self.style1={'r':self.bandsorder1[0],'g':self.bandsorder1[1],'b':self.bandsorder1[2],'NIR':self.bandsorder1[3]} self.left_layer.set_stlye(self.style1) + self.left_map.setPixmap(self.left_layer.previewAsPixmapo(width=200)) def set_style2(self): self.bandsorder2=[int(q.text()) for q in self.style2_inputs ] self.style2={'r':self.bandsorder2[0],'g':self.bandsorder2[1],'b':self.bandsorder2[2],'NIR':self.bandsorder2[3]} self.right_layer.set_stlye(self.style2) + self.right_map.setPixmap(self.right_layer.previewAsPixmapo(width=200)) class GdalPreviewImage(QThread): - def __init__(self,srcFile,tarFilename,width=1024.0,parent=None) -> None: + def __init__(self,layer,map,width=200,parent=None) -> None: super(GdalPreviewImage,self).__init__(parent) - self.srcFile=srcFile - self.tarFilename=tarFilename + self.layer=layer + self.map=map self.width=width def run(self): - try: - srcFile=self.srcFile - tarFilename=self.tarFilename - width=self.width - p=tarFilename - dataset = gdal.Open(srcFile, gdal.GA_ReadOnly) - srcProjection = dataset.GetProjection() - srcGeoTransform = dataset.GetGeoTransform() - srcWidth = dataset.RasterXSize - srcHeight = dataset.RasterYSize - srcBandCount = dataset.RasterCount - # srcNoDatas = [ - # dataset.GetRasterBand(bandIndex).GetNoDataValue() - # for bandIndex in range(1, srcBandCount+1) - # ] - # print(srcNoDatas) - srcBandDataType = dataset.GetRasterBand(1).DataType - # 创建重采样后的栅格 - outFilePath = p - resampleFactor=width/srcWidth - driver = gdal.GetDriverByName('GTiff') - outWidth = int(srcWidth * resampleFactor) - outHeight = int(srcHeight * resampleFactor) - outDataset = driver.Create( - outFilePath, - outWidth, - outHeight, - srcBandCount, - srcBandDataType - ) - print(outDataset) - geoTransforms = list(srcGeoTransform) - geoTransforms[1] = geoTransforms[1]/resampleFactor - geoTransforms[5] = geoTransforms[5]/resampleFactor - outGeoTransform = tuple(geoTransforms) - outDataset.SetGeoTransform(outGeoTransform) - outDataset.SetProjection(srcProjection) - # for bandIndex in range(1, srcBandCount+1): - # band = outDataset.GetRasterBand(bandIndex) - # band.SetNoDataValue(srcNoDatas[bandIndex-1]) - gdal.ReprojectImage( - dataset, - outDataset, - srcProjection, - srcProjection, - gdal.gdalconst.GRA_NearestNeighbour, - 0.0, 0.0, - ) - del outDataset - except: - pass - - # return outFilePath + self.map.setPixmap(self.layer.previewAsPixmapo(width=self.width)) class build_pyramids_overviews(QThread): diff --git a/rscder/gui/project.py b/rscder/gui/project.py index fb28dd5..187db32 100644 --- a/rscder/gui/project.py +++ b/rscder/gui/project.py @@ -92,8 +92,8 @@ class Create(QDialog): button_layout = QHBoxLayout() button_layout.setDirection(QHBoxLayout.RightToLeft) - button_layout.addWidget(ok_button, 0, Qt.AlignRight) - button_layout.addWidget(cancel_button, 0, Qt.AlignRight) + button_layout.addWidget(ok_button, 0, Qt.AlignHCenter) + button_layout.addWidget(cancel_button, 0, Qt.AlignHCenter) main_layout = QVBoxLayout() main_layout.addLayout(file_input_layout) diff --git a/rscder/utils/geomath.py b/rscder/utils/geomath.py new file mode 100644 index 0000000..994a315 --- /dev/null +++ b/rscder/utils/geomath.py @@ -0,0 +1,19 @@ + +def imageRC2geo(geo:list,x,y): + ''' + 根据GDAL的六参数模型将影像图上坐标(行列号)转为投影坐标或地理坐标(根据具体数据的坐标系统转换) + :param geo: GDAL地理数据,getGeotransform + ''' + trans = geo + px = trans[0] + x * trans[1] + y * trans[2] + py = trans[3] + x * trans[4] + y * trans[5] + return [px, py] + +def geo2imageRC(geo:list,px,py): + ''' + 根据GDAL的六 参数模型将给定的投影或地理坐标转为影像图上坐标(行列号),return x,y + ''' + dTemp = geo[1] * geo[5] - geo[2] *geo[4] + x= int((geo[5] * (px - geo[0]) -geo[2] * (py - geo[3])) / dTemp + 0.5) + y = int((geo[1] * (py - geo[3]) -geo[4] * (px - geo[0])) / dTemp + 0.5) + return [x,y] \ No newline at end of file diff --git a/rscder/utils/project.py b/rscder/utils/project.py index 67754c0..680b159 100644 --- a/rscder/utils/project.py +++ b/rscder/utils/project.py @@ -8,6 +8,7 @@ from pathlib import Path from pydoc import render_doc import shutil from statistics import stdev +from tabnanny import check from threading import Thread from time import sleep, time from typing import Dict, List @@ -26,9 +27,9 @@ from qgis.core import (\ QgsGeometry, QgsPointXY, QgsMultiBandColorRenderer) from PyQt5.QtCore import QObject, pyqtSignal, Qt, QThread,QSize from PyQt5.QtWidgets import QTreeWidgetItem, QAction,QMessageBox -from PyQt5.QtGui import QColor, QIcon, QFont +from PyQt5.QtGui import QColor, QIcon, QFont,QPixmap import yaml - +from rscder.utils.geomath import geo2imageRC,imageRC2geo from .misc import singleton def relative_path(path: str, root:str) -> str: return os.path.relpath(path, root) @@ -235,6 +236,7 @@ def from_dict(data:dict): if cls_type is not None and cls_type in globals(): return globals()[cls_type](**data) + class BasicLayer(QObject): LEFT_VIEW=1 @@ -372,13 +374,13 @@ class GridLayer(BasicLayer): self.x_lines = [] for xi in range(self.x_size // self.cell_size[0] +1): self.x_lines.append(self.x_min + self.x_res * xi * self.cell_size[0]) - if self.x_lines[-1] == self.x_max: + if self.x_lines[-1] > self.x_max: self.x_lines.pop() self.x_lines.append(self.x_max) self.y_lines = [] for yi in range(self.y_size // self.cell_size[1]+1): self.y_lines.append(self.y_min + self.y_res * yi * self.cell_size[1]) - if self.y_lines[-1] == self.y_max: + if self.y_lines[-1] < self.y_max: self.y_lines.pop() self.y_lines.append(self.y_max) crs = QgsCoordinateReferenceSystem() @@ -405,11 +407,13 @@ class GridLayer(BasicLayer): self.set_render() - - +class Mask(object): + def __init__(self,geoxy) -> None: + super().__init__() + self.xy=geoxy class RasterLayer(BasicLayer): - def __init__(self, name=None, enable=False, path=None, view_mode=BasicLayer.BOATH_VIEW,style_info={'r':3,'g':2,'b':1,'NIR':0}): + def __init__(self, name=None, enable=False, path=None, view_mode=BasicLayer.BOATH_VIEW,style_info={'r':1,'g':2,'b':3,'NIR':0}): if name is None: name = os.path.splitext(os.path.basename(path))[0] super().__init__(name, enable, IconInstance().RASTER, path, BasicLayer.IN_FILE, view_mode) @@ -417,18 +421,68 @@ class RasterLayer(BasicLayer): self.style_info=style_info self.apply_style() def compare(self, other:'RasterLayer'): - ds1 = gdal.Open(self.path) - ds2 = gdal.Open(other.path) + ''' + 与其他图像比较,看是否处于同一投影,有无重叠区域,能否进行变化检测 + other:其它同类图层 + return:-1,无法进行比较;0,有重叠区域;1,完全重叠。 + ''' + ds1:gdal.Dataset = gdal.Open(self.path) + ds2 :gdal.Dataset = gdal.Open(other.path) + geo1=ds1.GetGeoTransform() + geo2=ds2.GetGeoTransform() + map1xy=[imageRC2geo(geo1,0,0),imageRC2geo(geo1,ds1.RasterXSize,ds1.RasterYSize)] + map2xy=[imageRC2geo(geo2,0,0),imageRC2geo(geo2,ds2.RasterXSize,ds2.RasterYSize)] + map1xx=[map1xy[0][0],map1xy[1][0]] + map1yy=[map1xy[0][1],map1xy[1][1]] + map2xx=[map2xy[0][0],map2xy[1][0]] + map2yy=[map2xy[0][1],map2xy[1][1]] + map1xx.sort() + map1yy.sort() + map2yy.sort() + map2xx.sort() if ds1 is None or ds2 is None: Project().message_box.error('图层打开失败') - return False - - if ds1.RasterXSize != ds2.RasterXSize or ds1.RasterYSize != ds2.RasterYSize: - Project().message_box.error('图层尺寸不一致') - return False - - return True - + return -1 + if not ds1.GetProjection()==ds2.GetProjection(): + Project().message_box.error('投影不一致') + return -1 + elif (map1xx[0]>map2xx[1] or map1xx[1]map2yy[1] or map1yy[1] None: + def __init__(self, pth1, pth2,style_info1,style_info2,mask=None) -> None: self.layers:List[BasicLayer] = [] self.id = str(uuid.uuid1()) @@ -705,26 +780,39 @@ class PairLayer(BasicLayer): self.grid = None self.cell_size = Project().cell_size name = os.path.basename(pth1)[:4] + '-' + os.path.basename(pth2)[:4] + self.mask=mask # self.layer_update.connect(Project().layer_updated) super().__init__(name, True, IconInstance().DOCUMENT) self.layer = self.main_l1.layer if self.check(): - self.geo = self.main_l1.geo - self.proj = self.main_l1.proj - self.size = self.main_l1.size self.layers.append(self.main_l1) self.layers.append(self.main_l2) - self.grid = GridLayer(self.proj, self.geo, self.size[0], self.size[1], cell_size=Project().cell_size) - self.grid.set_layer_parent(self) + # self.layers.append(self.grid) + @property + def l1_geo(self): + return self.main_l1.geo + @property + def l2_geo(self): + return self.main_l2.geo def check(self): if self.checked: return self.checked self.checked = self.main_l1.compare(self.main_l2) - return self.checked - + if not self.checked==-1:#重叠 + self.mask=Mask(self.main_l1.overlap(self.main_l2)) + x1,y1=geo2imageRC(self.l1_geo,*self.mask.xy[0:2]) + x2,y2=geo2imageRC(self.l1_geo,*self.mask.xy[2:]) + self.size=[x2-x1,y2-y1] + self.geo = self.main_l1.geo + self.proj = self.main_l1.proj + gridgeo=[self.mask.xy[0],self.l1_geo[1],self.l1_geo[2],self.mask.xy[1],self.l1_geo[4],self.l1_geo[5]] + self.grid = GridLayer(self.proj, gridgeo , self.size[0], self.size[1], cell_size=Project().cell_size) + self.grid.set_layer_parent(self) + return self.checked!=-1 + def add_result_layer(self, result): result.set_layer_parent(self) self.layers.insert(0, result) @@ -760,13 +848,15 @@ class PairLayer(BasicLayer): pth2=self.main_l2.path, style_info1=self.main_l1.style_info, style_info2=self.main_l2.style_info, - layers=[to_dict(l) for l in self.layers if not (l is self.grid or l is self.main_l1 or l is self.main_l2) ] + layers=[to_dict(l) for l in self.layers if not (l is self.grid or l is self.main_l1 or l is self.main_l2) ], + ) return data - + + @property def info(self): - + ds= gdal.Open(self.main_l1.path) srs= osr.SpatialReference(ds.GetProjectionRef()) metadata={} @@ -788,7 +878,9 @@ class PairLayer(BasicLayer): #公共掩模 maskData={} - + if self.mask: + maskData['左上角坐标']=self.mask.xy[0:2] + maskData['右下角坐标']=self.mask.xy[2:] mapinfo={ '坐标系':metadata, @@ -798,7 +890,7 @@ class PairLayer(BasicLayer): return mapinfo - + @staticmethod def from_dict(data): player = PairLayer(data['pth1'], data['pth2'], data['style_info1'], data['style_info2'])