更新了不同尺度图像的变化检测

This commit is contained in:
石沈昊 2022-08-12 17:14:29 +08:00
parent 0d566b2618
commit 872e45937a
11 changed files with 527 additions and 427 deletions

View File

@ -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)

View File

@ -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('设置阈值'))

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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 = {}

View File

@ -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)

View File

@ -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):

View File

@ -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)

19
rscder/utils/geomath.py Normal file
View File

@ -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]

View File

@ -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]<map2xx[0])or(map1yy[0]>map2yy[1] or map1yy[1]<map2yy[0] ):
Project().message_box.error('图层无重叠区域')
return -1
elif ds1.RasterXSize == ds2.RasterXSize and ds1.RasterYSize == ds2.RasterYSize and geo1==geo2:
# Project().message_box.error('两图一致')
return 1
#图层尺寸相同
Project().message_box.warning('图层不完全重叠')
del ds1
del ds2
return 0
def overlap(self,other:'RasterLayer'):
'''
与其他图像比较看是否处于同一投影,有无重叠区域,能否进行变化检测
other:其它同类图层
return:[重叠区域左上点xy,重叠区域右下点xy]
'''
ds1:gdal.Dataset = gdal.Open(self.path)
ds2 :gdal.Dataset = gdal.Open(other.path)
geo1=ds1.GetGeoTransform()
geo2=ds2.GetGeoTransform()
#地理投影坐标y向下变小
map1xy=[imageRC2geo(geo1,0,0),imageRC2geo(geo1,ds1.RasterXSize,ds1.RasterYSize)]
map2xy=[imageRC2geo(geo2,0,0),imageRC2geo(geo2,ds2.RasterXSize,ds2.RasterYSize)]
xx=[map1xy[0][0],map1xy[1][0],map2xy[0][0],map2xy[1][0]]
yy=[map1xy[0][1],map1xy[1][1],map2xy[0][1],map2xy[1][1]]
xx.sort()
yy.sort()
return [xx[1],yy[2],xx[2],yy[1]]
@property
def band(self):
ds:gdal.Dataset = gdal.Open(self.path)
if ds is None:
return None
band = ds.RasterCount
del ds
return band
@property
def geo(self):
ds = gdal.Open(self.path)
@ -490,6 +544,13 @@ class RasterLayer(BasicLayer):
'prewmap':self.preview
}
return mapinfo
def previewAsPixmapo(self,width,height=None):
w=self.layer.width()
h=self.layer.height()
if height:
return QPixmap.fromImage(self.layer.previewAsImage(QSize(width,height)))
return QPixmap.fromImage(self.layer.previewAsImage(QSize(width,int(width*h/w))))
@property
def preview(self,width=400):
w=self.layer.width()
@ -502,16 +563,30 @@ class MultiBandRasterLayer(RasterLayer):
renderer=QgsMultiBandColorRenderer(self.layer.dataProvider(),self.style_info['r'],self.style_info['g'],self.style_info['b'])
self.layer.setRenderer(renderer)
self.layer.triggerRepaint()
# @property
# def info(self):
# mapinfo=super().info
# mapinfo['渲染属性']['波段']='单波段'
def toArray(self,mask=None,band:list=None):
ds:gdal.Dataset=gdal.Open(self.path)
res=None
startx=0
starty=0
xsize=ds.RasterXSize
ysize=ds.RasterYSize
if mask:
#转为图像坐标
startx,starty=geo2imageRC(self.geo,mask[0],mask[1])
x2,y2=geo2imageRC(self.geo,mask[2],mask[3])
xsize=x2-startx
ysize=y2-starty
res=ds.ReadAsArray(startx,starty,xsize,ysize,band_list=band)
del ds
return res
def readAsArray(self,xoff: int = 0, yoff: int = 0, xsize= None, ysize = None, buf_obj= None, buf_xsize= None, buf_ysize = None, buf_type= None, callback = None, callback_data = None, interleave = 'band', band_list = None):
ds:gdal.Dataset = gdal.Open(self.path)
array=ds.ReadAsArray(xoff= 0, yoff= 0, xsize= None, ysize = None, buf_obj= None, buf_xsize= None, buf_ysize = None, buf_type= None, callback = None, callback_data = None, interleave= 'band', band_list = None)
return array
class SingleBandRasterLayer(RasterLayer):
def apply_style(self):
pass
class VectorLayer(BasicLayer):
pass
@ -693,7 +768,7 @@ class ResultPointLayer(BasicLayer):
return {'基础属性':basic,'渲染属性':render}
class PairLayer(BasicLayer):
def __init__(self, pth1, pth2,style_info1,style_info2) -> 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'])