Merge remote-tracking branch 'origin/dev-pyramid'

This commit is contained in:
copper 2022-08-02 15:34:36 +08:00
commit e8e7dba935
5 changed files with 171 additions and 31 deletions

View File

@ -241,6 +241,7 @@ class InOnePlugin(BasicPlugin):
pth2=Meanfilter(w.x_size_input.text(),w.y_size_input.text(),w.layer_combox.layer2) 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)) self.send_message.emit('均值滤波图像{}'.format(w.layer_combox.layer2.name))
name=name+'_mean_filter' name=name+'_mean_filter'
dict['预处理']=['均值滤波','|'.format(pth1,pth2)]
else: else:
pass pass
@ -248,18 +249,18 @@ class InOnePlugin(BasicPlugin):
if w.cd_select.choose==self.cd[0]: if w.cd_select.choose==self.cd[0]:
cdpth=basic_cd(pth1,pth2,w.layer_combox.layer1.layer_parent,self.send_message) cdpth=basic_cd(pth1,pth2,w.layer_combox.layer1.layer_parent,self.send_message)
name += '_basic_cd' name += '_basic_cd'
#dict[name]=cdpth dict['变化检测算法']=['差分法',cdpth]
else: else:
pass pass
thpth=None thpth=None
if w.threshold_select.choose==self.threshold[0]: if w.threshold_select.choose==self.threshold[0]:
thpth=otsu(cdpth,w.layer_combox.layer1.layer_parent.name,self.send_message) thpth,gap=otsu(cdpth,w.layer_combox.layer1.layer_parent.name,self.send_message)
name+='_otsu' name+='_otsu'
dict[name]=thpth dict['后处理']=['OTSU阈值',gap,cdpth]
elif w.threshold_select.choose=='手动阈值': elif w.threshold_select.choose=='手动阈值':
thpth=thresh(cdpth,float(w.threshold_input.text()),w.layer_combox.layer1.layer_parent.name,self.send_message) thpth=thresh(cdpth,float(w.threshold_input.text()),w.layer_combox.layer1.layer_parent.name,self.send_message)
dict[name+'_thresh_{:.1f}'.format(float(w.threshold_input.text()))] dict['后处理']=['手动阈值',[float(w.threshold_input.text())],thpth]
else: else:
pass pass
@ -417,7 +418,7 @@ def otsu(pth,name,send_message):
out_ds = None out_ds = None
ds = None ds = None
send_message.emit('OTSU阈值完成') send_message.emit('OTSU阈值完成')
return out_th return out_th,gap
#otsu_layer = SingleBandRasterLayer(path = out_th, style_info={}) #otsu_layer = SingleBandRasterLayer(path = out_th, style_info={})
#layer.layer_parent.add_result_layer(otsu_layer) #layer.layer_parent.add_result_layer(otsu_layer)
@ -496,8 +497,7 @@ def table_layer(pth,layer,name,send_message,dict):
center_y = center_y * geo[5] + geo [3] center_y = center_y * geo[5] + geo [3]
f.write(f'{center_x},{center_y},{block_data_xy.mean() * 100},{int(block_data_xy.mean() > 0.5)}\n') f.write(f'{center_x},{center_y},{block_data_xy.mean() * 100},{int(block_data_xy.mean() > 0.5)}\n')
result_layer = ResultPointLayer(out_csv, enable=True, proj=layer.proj, geo=layer.geo) result_layer = ResultPointLayer(out_csv, enable=True, proj=layer.proj, geo=layer.geo,result_path=dict)
result_layer.result_path=dict
# print(result_layer.result_path) # print(result_layer.result_path)
layer.layer_parent.add_result_layer(result_layer) layer.layer_parent.add_result_layer(result_layer)
send_message.emit('计算完成') send_message.emit('计算完成')

View File

@ -57,7 +57,8 @@ class eagleEye(QgsMapCanvas):
self.setLayers(layer_list_1) self.setLayers(layer_list_1)
if len(layer_list_1) > 0: if len(layer_list_1) > 0:
self.zoomToFeatureExtent(layer_list_1[0].extent()) self.zoomToFeatureExtent(layer_list_1[0].extent())
def zoom(self,layer):
self.zoomToFeatureExtent(layer.extent())
def draw_extent(self,extent): def draw_extent(self,extent):
self.Extent=extent self.Extent=extent
self.rubber.draw_extent(self.Extent) self.rubber.draw_extent(self.Extent)

29
rscder/gui/info.py Normal file
View File

@ -0,0 +1,29 @@
from distutils.log import info
from PyQt5.QtWidgets import QHBoxLayout,QDialog,QLabel,QVBoxLayout
from PyQt5.QtGui import QColor, QDragEnterEvent, QDropEvent,QPixmap
from PyQt5.QtCore import QSize,Qt
import yaml
class InfoBox(QDialog):
def __init__(self,infodic:dict,parent=None):
super(InfoBox,self).__init__(parent=parent)
v=QVBoxLayout()
if 'prewmap' in infodic.keys():
pmap=infodic.pop('prewmap')
label=QLabel(yaml.dump(infodic,allow_unicode=True,sort_keys=False))
label.setWordWrap(True)#过长自动换行主要是wkt过长
v.addWidget(label)
maplabel=QLabel()
maplabel.setPixmap(QPixmap.fromImage(pmap))
v.addWidget(maplabel,0,Qt.AlignHCenter)
else:
label=QLabel(yaml.dump(infodic,allow_unicode=True,sort_keys=False))
label.setWordWrap(True)#过长自动换行主要是wkt过长
v.addWidget(label)
self.setLayout(v)
self.show()

View File

@ -148,8 +148,8 @@ class loader(QDialog):
button_layout = QHBoxLayout() button_layout = QHBoxLayout()
button_layout.setDirection(QHBoxLayout.RightToLeft) button_layout.setDirection(QHBoxLayout.RightToLeft)
button_layout.addWidget(ok_button, 0, Qt.AlignRight)
button_layout.addWidget(cancel_button, 0, Qt.AlignRight) button_layout.addWidget(cancel_button, 0, Qt.AlignRight)
button_layout.addWidget(ok_button, 0, Qt.AlignRight)
main_layout = QVBoxLayout() main_layout = QVBoxLayout()
main_layout.addLayout(path1_layout) main_layout.addLayout(path1_layout)
@ -169,14 +169,14 @@ class loader(QDialog):
self.path1_input.setText(self.path1) self.path1_input.setText(self.path1)
result=QMessageBox.question(self, '提示', '是否创建图像金字塔', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) #默认关闭界面选择No result=QMessageBox.question(self, '提示', '是否创建图像金字塔', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) #默认关闭界面选择No
if result==QMessageBox.Yes: if result==QMessageBox.Yes:
progress1=progressDialog(self,'加载时相一') progress1:QDialog=progressDialog(self,'加载时相一')
progress1.setModal(False) progress1.setModal(False)
self.temp1=os.path.join(Project().other_path,'temp1.tif') self.temp1=os.path.join(Project().other_path,'temp1.tif')
t1=GdalPreviewImage(self.path1,self.temp1,1024,self) t1=GdalPreviewImage(self.path1,self.temp1,1024,self.parent())
# t1.started.connect(progress1.show) # t1.started.connect(progress1.show)
t1.finished.connect(self.loadfile1) t1.finished.connect(self.loadfile1)
t1.finished.connect(lambda :progress1.setlabel('创建影像金字塔..')) t1.finished.connect(lambda :self.setlabel(progress1) )
t2=build_pyramids_overviews(self.path1,self) t2=build_pyramids_overviews(self.path1,self.parent())
t2.finished.connect(progress1.hide) t2.finished.connect(progress1.hide)
t1.start() t1.start()
t1.finished.connect(t2.start) t1.finished.connect(t2.start)
@ -186,7 +186,7 @@ class loader(QDialog):
progress1=progressDialog(self,'加载时相一') progress1=progressDialog(self,'加载时相一')
progress1.setModal(False) progress1.setModal(False)
self.temp1=os.path.join(Project().other_path,'temp1.tif') self.temp1=os.path.join(Project().other_path,'temp1.tif')
t1=GdalPreviewImage(self.path1,self.temp1,1024) t1=GdalPreviewImage(self.path1,self.temp1,1024,self.parent())
# t1.started.connect(progress1.show) # t1.started.connect(progress1.show)
t1.finished.connect(self.loadfile1) t1.finished.connect(self.loadfile1)
t1.finished.connect(progress1.hide) t1.finished.connect(progress1.hide)
@ -217,11 +217,12 @@ class loader(QDialog):
progress2.setModal(False) progress2.setModal(False)
# progress1.show # progress1.show
self.temp2=os.path.join(Project().other_path,'temp2.tif') self.temp2=os.path.join(Project().other_path,'temp2.tif')
t1=GdalPreviewImage(self.path2,self.temp2,1024,self) t1=GdalPreviewImage(self.path2,self.temp2,1024,self.parent())
# t1.started.connect(progress1.show) # t1.started.connect(progress1.show)
t1.finished.connect(self.loadfile2) t1.finished.connect(self.loadfile2)
t1.finished.connect(lambda :progress2.setlabel('创建影像金字塔..')) t1.finished.connect(lambda :self.setlabel(progress2))
t2=build_pyramids_overviews(self.path2,self) t2=build_pyramids_overviews(self.path2,self.parent())
t2.finished.connect(progress2.hide) t2.finished.connect(progress2.hide)
t1.start() t1.start()
t1.finished.connect(t2.start) t1.finished.connect(t2.start)
@ -230,7 +231,7 @@ class loader(QDialog):
progress2=progressDialog(self,'加载时相二') progress2=progressDialog(self,'加载时相二')
progress2.setModal(False) progress2.setModal(False)
self.temp2=os.path.join(Project().other_path,'temp2.tif') self.temp2=os.path.join(Project().other_path,'temp2.tif')
t1=GdalPreviewImage(self.path2,self.temp2,1024) t1=GdalPreviewImage(self.path2,self.temp2,1024,self.parent())
# t1.started.connect(progress1.show) # t1.started.connect(progress1.show)
t1.finished.connect(self.loadfile2) t1.finished.connect(self.loadfile2)
t1.finished.connect(progress2.hide) t1.finished.connect(progress2.hide)
@ -266,7 +267,11 @@ class loader(QDialog):
def open_alg(self,path): def open_alg(self,path):
pass pass
def setlabel(self,s):
try:
s.setlabel('创建影像金字塔..')
except:
pass
def set_style1(self): def set_style1(self):
self.bandsorder1=[int(q.text()) for q in self.style1_inputs ] 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.style1={'r':self.bandsorder1[0],'g':self.bandsorder1[1],'b':self.bandsorder1[2],'NIR':self.bandsorder1[3]}
@ -335,6 +340,7 @@ class GdalPreviewImage(QThread):
del outDataset del outDataset
except: except:
pass pass
# return outFilePath # return outFilePath
@ -346,11 +352,9 @@ class build_pyramids_overviews(QThread):
try: try:
filename=self.filename filename=self.filename
image:gdal.Dataset = gdal.Open(filename, 0) image:gdal.Dataset = gdal.Open(filename, 0)
# 如果第二个参数设置为0则金字塔文件建立在外面
# 如果第二个参数缺省或者为1则金字塔文件建立在文件内
gdal.SetConfigOption('COMPRESS_OVERVIEW', 'DEFLATE') gdal.SetConfigOption('COMPRESS_OVERVIEW', 'DEFLATE')
ov_list = [2, 4,6, 8, 12,16,24, 32, 48,64,96,128] ov_list = [2, 4,6, 8, 12,16,24, 32, 48,64,96,128]
image.BuildOverviews("NEAREST", len(ov_list),overviewlist=ov_list) image.BuildOverviews("NEAREST",overviewlist=ov_list)
del image del image
except: except:
pass pass

View File

@ -1,16 +1,21 @@
from cgitb import enable from cgitb import enable
from collections import OrderedDict from collections import OrderedDict
from email.message import Message
import imp
import inspect import inspect
import os import os
from pathlib import Path from pathlib import Path
from pydoc import render_doc
import shutil import shutil
from statistics import stdev
from threading import Thread from threading import Thread
from time import sleep, time from time import sleep, time
from typing import Dict, List from typing import Dict, List
import uuid import uuid
import numpy as np import numpy as np
from osgeo import gdal, gdal_array from osgeo import gdal, gdal_array,osr
from rscder.utils.icons import IconInstance from rscder.utils.icons import IconInstance
from rscder.gui.info import InfoBox
from rscder.utils.setting import Settings from rscder.utils.setting import Settings
from qgis.core import (\ from qgis.core import (\
QgsRasterLayer, QgsMarkerSymbol, QgsUnitTypes, QgsRasterLayer, QgsMarkerSymbol, QgsUnitTypes,
@ -19,12 +24,12 @@ from qgis.core import (\
QgsLineSymbol, QgsSingleSymbolRenderer, QgsSimpleLineSymbolLayer, QgsLineSymbol, QgsSingleSymbolRenderer, QgsSimpleLineSymbolLayer,
QgsVectorLayer, QgsCoordinateReferenceSystem, QgsFeature, QgsVectorLayer, QgsCoordinateReferenceSystem, QgsFeature,
QgsGeometry, QgsPointXY, QgsMultiBandColorRenderer) QgsGeometry, QgsPointXY, QgsMultiBandColorRenderer)
from PyQt5.QtCore import QObject, pyqtSignal, Qt, QThread from PyQt5.QtCore import QObject, pyqtSignal, Qt, QThread,QSize
from PyQt5.QtWidgets import QTreeWidgetItem, QAction from PyQt5.QtWidgets import QTreeWidgetItem, QAction,QMessageBox
from PyQt5.QtGui import QColor, QIcon, QFont from PyQt5.QtGui import QColor, QIcon, QFont
import yaml import yaml
from .misc import singleton
from .misc import singleton
def relative_path(path: str, root:str) -> str: def relative_path(path: str, root:str) -> str:
return os.path.relpath(path, root) return os.path.relpath(path, root)
@ -89,6 +94,7 @@ class Project(QObject):
self.layer_tree = layer_tree self.layer_tree = layer_tree
self.message_box = message_box self.message_box = message_box
self.result_table = result_table self.result_table = result_table
self.eye=eye
IconInstance(self) IconInstance(self)
self.layer_tree_update.connect(layer_tree.update_layer) self.layer_tree_update.connect(layer_tree.update_layer)
self.layer_show_update.connect(pair_canvas.update_layer) self.layer_show_update.connect(pair_canvas.update_layer)
@ -176,6 +182,7 @@ class Project(QObject):
def zoom_to_layer(self, data): def zoom_to_layer(self, data):
self.pair_canvas.zoom_to_layer(data['layer']) self.pair_canvas.zoom_to_layer(data['layer'])
self.eye.zoom(data['layer'])
@property @property
def cmi_path(self): def cmi_path(self):
@ -316,8 +323,22 @@ class BasicLayer(QObject):
del_action.triggered.connect(del_layer) del_action.triggered.connect(del_layer)
actions.append(del_action) actions.append(del_action)
if self.info:
show_info=QAction(IconInstance().HELP,'属性信息')
actions.append(show_info)
def showIofn(info):
#print(info)
a=InfoBox(info)
a.exec_()
show_info.triggered.connect(lambda :showIofn(self.info))
return actions return actions
return actions
@property
def info(self):
return None
class GridLayer(BasicLayer): class GridLayer(BasicLayer):
def set_render(self): def set_render(self):
@ -391,7 +412,7 @@ class GridLayer(BasicLayer):
class RasterLayer(BasicLayer): 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':3}): def __init__(self, name=None, enable=False, path=None, view_mode=BasicLayer.BOATH_VIEW,style_info={'r':3,'g':2,'b':1,'NIR':0}):
if name is None: if name is None:
name = os.path.splitext(os.path.basename(path))[0] name = os.path.splitext(os.path.basename(path))[0]
super().__init__(name, enable, IconInstance().RASTER, path, BasicLayer.IN_FILE, view_mode) super().__init__(name, enable, IconInstance().RASTER, path, BasicLayer.IN_FILE, view_mode)
@ -440,10 +461,43 @@ class RasterLayer(BasicLayer):
def apply_style(self): def apply_style(self):
pass pass
@property
def bandinfo(self):
ds :gdal.Dataset= gdal.Open(self.path)
bands=ds.RasterCount
bandinfo_={}
for i in range(1,bands+1) :
min,max,mean,stdev=ds.GetRasterBand(i).ComputeStatistics(True)
bandinfo_['波段{}'.format(i)]=['最小值:{}'.format(min),'最大值:{}'.format(max),'均值:{}'.format(mean),'方差:{}'.format(stdev)]
ds=None
return bandinfo_
def set_stlye(self,style_info): def set_stlye(self,style_info):
self.style_info=style_info self.style_info=style_info
self.apply_style() self.apply_style()
@property
def info(self):
#基础属性
basic={}
basic['文件名']=self.path
basic['文件大小']="{} Mb".format(os.path.getsize(self.path)//(1024*1024))
basic['波段信息']=self.bandinfo
#渲染属性
render=self.style_info
mapinfo={
'基础属性':basic,
'渲染属性':render,
'prewmap':self.preview
}
return mapinfo
@property
def preview(self,width=400):
w=self.layer.width()
h=self.layer.height()
return self.layer.previewAsImage(QSize(width,int(width*h/w)))
class MultiBandRasterLayer(RasterLayer): class MultiBandRasterLayer(RasterLayer):
@ -451,7 +505,10 @@ class MultiBandRasterLayer(RasterLayer):
renderer=QgsMultiBandColorRenderer(self.layer.dataProvider(),self.style_info['r'],self.style_info['g'],self.style_info['b']) renderer=QgsMultiBandColorRenderer(self.layer.dataProvider(),self.style_info['r'],self.style_info['g'],self.style_info['b'])
self.layer.setRenderer(renderer) self.layer.setRenderer(renderer)
self.layer.triggerRepaint() self.layer.triggerRepaint()
# @property
# def info(self):
# mapinfo=super().info
# mapinfo['渲染属性']['波段']='单波段'
class SingleBandRasterLayer(RasterLayer): class SingleBandRasterLayer(RasterLayer):
def apply_style(self): def apply_style(self):
@ -472,8 +529,8 @@ class ResultPointLayer(BasicLayer):
self.wkt = proj self.wkt = proj
self.geo = geo self.geo = geo
self.dsort=dsort self.dsort=dsort
self.result_path=result_path self.result_path:dict=result_path
# self.methods=
self.load_point_file() self.load_point_file()
def save(self): def save(self):
@ -621,7 +678,22 @@ class ResultPointLayer(BasicLayer):
return actions return actions
# def load_file(self, path): # def load_file(self, path):
@property
def info(self):
#基础属性
basic={}
basic['文件路径']=self.path
#中间算法信息:
methods={ k:v[0] for k ,v in self.result_path.items()}
basic['变化检测算法']=methods
#渲染信息
render={}
render['标注字体大小']=2
render['标注颜色']='#ffff00'
render['阈值']=self.result_path['后处理'][1]
return {'基础属性':basic,'渲染属性':render}
class PairLayer(BasicLayer): class PairLayer(BasicLayer):
def __init__(self, pth1, pth2,style_info1,style_info2) -> None: def __init__(self, pth1, pth2,style_info1,style_info2) -> None:
@ -695,6 +767,40 @@ class PairLayer(BasicLayer):
) )
return data return data
@property
def info(self):
ds= gdal.Open(self.main_l1.path)
srs= osr.SpatialReference(ds.GetProjectionRef())
metadata={}
# 空间参考系统
metadata['proj4'] = srs.ExportToProj4()
metadata['wkt'] = srs.ExportToWkt()
# 地理坐标系
metadata['geocs'] = srs.GetAttrValue('GEOGCS')
metadata['uom'] = srs.GetAttrValue('UNIT')
# 投影坐标系
metadata['projcs'] = srs.GetAttrValue('PROJCS') # if projected
metadata['epsg'] = srs.GetAuthorityCode(None)
ds=None
#格网信息
gridData={}
gridData['格网大小']='{}像素'.format(self.grid.cell_size)
gridData['格网线']=['宽度1像素', '颜色:白色']
#公共掩模
maskData={}
mapinfo={
'坐标系':metadata,
'格网':gridData,
'公共掩膜':maskData
}
return mapinfo
@staticmethod @staticmethod
def from_dict(data): def from_dict(data):