# -*- coding: utf-8 -*- """ Module implementing MainWindow. """ import os from .RadarUI import Ui_MainWindow from PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5 import QtWidgets from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QMainWindow from ..io import read_auto from ..io.util import radar_format from ..draw.SingleRadarPlot import RadarGraph from ..draw.SingleRadarPlotMap import RadarGraphMap from ..configure.location_config import last_open_dir from glob import glob import json import sys from .station_info import Ui_Dialog from ..draw.VerticalSectionPlot import VerticalSection from matplotlib.figure import Figure from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas field_name = ["dBZ", "V", "W", "ZDR", "KDP", "CC"] class LineBuilder: def __init__(self, fig, ax, radar_data, product, map_bool): self.ax = ax self.xs = [] self.ys = [] self.fig = fig self.map = map_bool self.cid = self.fig.canvas.mpl_connect('button_press_event', self) self.cursor = self.fig.canvas.mpl_connect('motion_notify_event', self.mouse_move) self.radar_dat = radar_data self.product = product def __call__(self, event): if len(self.xs) < 2: self.xs.append(event.xdata) self.ys.append(event.ydata) if len(self.xs) == 1: self.start = self.ax.scatter(event.xdata, event.ydata, color="r", marker="+", s=60, zorder=len(self.xs)+10) else: self.end = self.ax.scatter(event.xdata, event.ydata, color="r", marker="+", s=60, zorder=len(self.xs) + 10) self.rline = self.ax.plot(self.xs, self.ys, color="r", linewidth=1, zorder=13) cv = FigureCanvas(Figure(figsize=(8, 6))) ax = cv.figure.add_axes([0.1, 0.3, 0.8, 0.6]) cax = cv.figure.add_axes([0.1, 0.1, 0.8, 0.06]) if not self.map: VerticalSection.GUI_section(cv.figure, ax, cax, self.radar_dat, [self.xs[0]*1000, self.ys[0]*1000],\ [self.xs[1]*1000, self.ys[1]*1000], field_name[self.product]) else: VerticalSection.GUI_section_map(cv.figure, ax, cax, self.radar_dat, [self.xs[0], self.ys[0]], \ [self.xs[1], self.ys[1]], field_name[self.product]) cv.show() self.fig.canvas.draw() else: self.rline[0].remove() self.start.remove() self.end.remove() self.xs = [] self.ys = [] self.xs.append(event.xdata) self.ys.append(event.ydata) self.start = self.ax.scatter(event.xdata, event.ydata, color="r", marker="+", s=60, zorder=len(self.xs) + 10) self.fig.canvas.draw() def mouse_move(self, event): try: self.move_line[0].remove() except Exception: pass if len(self.xs) == 1: self.move_line = self.ax.plot([self.xs[0], event.xdata], [self.ys[0], event.ydata], color="r", linewidth=1, linestyle="--", zorder=100) self.fig.canvas.draw() class Dialog(QDialog, Ui_Dialog): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget @type QWidget """ super(Dialog, self).__init__(parent) self.setupUi(self) @pyqtSlot() def on_pushButton_clicked(self): """ Slot documentation goes here. """ self.lon = float(self.lineEdit.text()) self.lat = float(self.lineEdit_2.text()) self.height = float(self.lineEdit_3.text()) self.close() @pyqtSlot() def on_pushButton_2_clicked(self): """ Slot documentation goes here. """ self.close() @pyqtSlot() def on_toolButton_clicked(self): """ Slot documentation goes here. """ lon, LonTrue = QInputDialog.getDouble(self, r"经度", "雷达站点经度(单位:度)", 131.3, -180, 180) if LonTrue: self.lineEdit.setText(str(lon)) @pyqtSlot() def on_toolButton_2_clicked(self): """ Slot documentation goes here. """ # TODO: not implemented yet lat, LatTrue = QInputDialog.getDouble(self, r"纬度", "雷达站点纬度(单位:度)", 23, -90, 90) if LatTrue: self.lineEdit.setText(str(lat)) @pyqtSlot() def on_toolButton_3_clicked(self): """ Slot documentation goes here. """ # TODO: not implemented yet height, HeightTrue = QInputDialog.getDouble(self, r"高度", "雷达站点高度(单位:米)", 57, -2000, 5000) if HeightTrue: self.lineEdit.setText(str(height)) class MainWindow(QMainWindow, Ui_MainWindow): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget @type QWidget """ super(MainWindow, self).__init__(parent) self.setupUi(self) self.lastOpenDir = self.open_last_opendir() self.radar_dat = None self.dualPOL = False self.openbasename = None self.files = None self.radar_type = None self.org_lat = 131.3 self.org_lon = 23 self.org_height = 57 def open_last_opendir(self): """打开上次关闭文件的位置""" with open(last_open_dir, "r") as f: dir_dict = json.load(f) return dir_dict["lastOpenDir"] def write_last_opendir(self, filedir): """将打开的位置写入json文件中""" with open(last_open_dir, "w") as f: json.dump({"lastOpenDir":filedir}, f) @pyqtSlot() def on_actionvertical_changed(self): """垂直剖面的绘制""" if self.actionvertical.isChecked(): try: self.linebuilder = LineBuilder(self.fig, self.ax, self.radar_dat, self.find_var_in_groupBox(),\ self.actionwithmap.isChecked()) self.clickevent = True except AttributeError: pass else: self.fig.canvas.mpl_disconnect(self.linebuilder.cid) self.fig.canvas.mpl_disconnect(self.linebuilder.cursor) self.linebuilder.rline[0].remove() self.linebuilder.start.remove() self.linebuilder.end.remove() self.fig.canvas.draw() @pyqtSlot() def on_actionwithmap_changed(self): """ Slot documentation goes here. """ pass @pyqtSlot() def on_actioncontinuous_changed(self): """ Slot documentation goes here. """ pass def Read_radar(self, filename): if radar_format(filename) is not None: NRadar = read_auto(filename) self.org_lat = NRadar.scan_info.latitude.values self.org_lon = NRadar.scan_info.longitude.values self.org_height = NRadar.scan_info.altitude.values if "KDP" in NRadar.fields[0].keys(): self.open_dual() else: self.close_non_dual() return NRadar else: QMessageBox.warning(self, "数据错误警告", "非SA/SB/CA/CB/98D/CC/CCJ/SC/CD数据", QMessageBox.Yes) return 0 def close_non_dual(self): """关闭非双偏振雷达变量""" self.radioButton_13.hide() self.radioButton_14.hide() self.radioButton_15.hide() def open_dual(self): """关闭非双偏振雷达变量""" self.radioButton_13.show() self.radioButton_14.show() self.radioButton_15.show() def setSelected(self, filename): """将选中数据高亮""" basename = os.path.basename(filename) self.openbasename = basename items = self.listWidget.findItems(basename, Qt.MatchExactly) if len(items) > 0: for item in items: self.listWidget.setCurrentItem(item) def import_basedat(self, direc): """查找文件夹中的所有雷达文件名,并以list返回""" self.lastOpenDir = direc self.write_last_opendir(direc) extensions = ["*.*A", "*.*V", "*.bz2", "*.bin", "*.AR2", "*.gz", ".GZ"] files = [] for iextend in extensions: file = glob(os.path.join(direc, iextend)) files.extend(file) return [os.path.basename(ifile) for ifile in files] def add_listwidget(self, files): """将files添加到listWidget""" self.listWidget.clear() for item in files: self.listWidget.addItem(item) @pyqtSlot(QListWidgetItem) def on_listWidget_itemDoubleClicked(self, item): """ Slot documentation goes here. @param item DESCRIPTION @type QListWidgetItem """ filename = self.lastOpenDir + os.sep + item.text() self.radar_dat = self.Read_radar(filename) if self.radar_dat != 0: self.setSelected(filename) self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_actionopen_2_triggered(self): """ Slot documentation goes here. """ if self.lastOpenDir and os.path.exists(self.lastOpenDir): defaultOpenDirPath = self.lastOpenDir else: defaultOpenDirPath = '.' filename = QFileDialog.getOpenFileName(self, "打开一个雷达基数据", defaultOpenDirPath, "天气雷达基数据(*bin *bz2 *A *V *BIN *BZ2 *AR2 *GZ *gz)") ReadFile = filename[0] if ReadFile.strip() == "": return PathDir = os.path.dirname(ReadFile) self.files = self.import_basedat(PathDir) self.add_listwidget(self.files) self.radar_dat = self.Read_radar(ReadFile) if self.radar_dat != 0: self.setSelected(ReadFile) self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_actionopendir_2_triggered(self): """ Slot documentation goes here. """ if self.lastOpenDir and os.path.exists(self.lastOpenDir): defaultOpenDirPath = self.lastOpenDir else: defaultOpenDirPath = '.' self.targetDirPath = QFileDialog.getExistingDirectory(self, "打开新一代天气雷达数据文件夹", defaultOpenDirPath, QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) if self.targetDirPath.strip() == '': return self.files = self.import_basedat(self.targetDirPath) self.add_listwidget(self.files) @pyqtSlot() def on_actionquit_2_triggered(self): """ Slot documentation goes here. """ sys.exit(0) @pyqtSlot() def on_actionstation_triggered(self): """ Slot documentation goes here. """ self.my_info = Dialog() self.my_info.lineEdit.setText(str(self.org_lon)) self.my_info.lineEdit_2.setText(str(self.org_lat)) self.my_info.lineEdit_3.setText(str(self.org_height)) self.my_info.lat = self.org_lat self.my_info.lon = self.org_lon self.my_info.height = self.org_height self.my_info.exec_() self.org_lat = self.my_info.lat self.org_lon = self.my_info.lon self.org_height = self.my_info.height def find_checked_radiobutton(self, radiobuttons): ''' find the checked radiobutton ''' for items in radiobuttons: if items.isChecked(): checked_radiobutton = items.text() return checked_radiobutton def find_level_in_groupBox(self): """查找仰角""" level = self.find_checked_radiobutton(self.groupBox.findChildren(QtWidgets.QRadioButton)) levels = ["第1层", "第2层", "第3层", "第4层", "第5层", "第6层", "第7层", "第8层", "第9层"] for i in range(9): if level == levels[i]: return i return 0 def find_var_in_groupBox(self): """查找变量""" var = self.find_checked_radiobutton(self.groupBox_2.findChildren(QtWidgets.QRadioButton)) vars = ["反射率因子", "径向速度", "谱宽", "差分反射率", "差分相位比", "相关系数"] for i in range(6): if var == vars[i]: return i return 0 def plot_graph_PPI(self, radar, level, product, map, continuously): self.MplWidget.canvas.update() self.MplWidget.canvas.flush_events() try: self.fig.clf() self.ax.clear() self.cax.clear() except AttributeError: pass if not map: self.fig, self.ax, self.cax = self.MplWidget.canvas.get_fig_ax() self.ax.set_facecolor((0.95, 0.95, 0.95)) self.pm = RadarGraph.GUI_plot(radar, self.fig, self.ax, self.cax, level, \ field_name[product], continuously=continuously) else: self.fig, self.ax, self.cax = self.MplWidget.canvas.get_fig_ax_map() self.ax.set_facecolor((0.95, 0.95, 0.95)) self.pm = RadarGraphMap.GUI_plot(radar, self.fig, self.ax, self.cax, level, \ field_name[product], continuously=continuously) self.ax.tick_params(axis="y", which="both", direction='in') self.ax.tick_params(axis="x", which="both", direction='in') self.MplWidget.canvas.draw() if self.actionvertical.isChecked(): #尝试重新绑定 try: self.fig.canvas.mpl_disconnect(self.linebuilder.cid) self.fig.canvas.mpl_disconnect(self.linebuilder.cursor) self.linebuilder = LineBuilder(self.fig, self.ax, self.radar_dat, self.find_var_in_groupBox(), \ self.actionwithmap.isChecked()) self.clickevent = True except AttributeError: pass @pyqtSlot() def on_pushButton_clicked(self): """ Slot documentation goes here. """ if self.files is not None: items = self.listWidget.findItems(self.openbasename, Qt.MatchExactly) row = self.listWidget.row(items[0]) nrows = len(self.files) res_row = row - 1 if res_row < 0: res_row = nrows - 1 self.radar_dat = self.Read_radar(self.lastOpenDir + os.sep + self.files[res_row]) if self.radar_dat != 0: self.setSelected(self.lastOpenDir + os.sep + self.files[res_row]) self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_pushButton_2_clicked(self): """ Slot documentation goes here. 动画播放部分 """ if self.files is not None: items = self.listWidget.findItems(self.openbasename, Qt.MatchExactly) row = self.listWidget.row(items[0]) nrows = len(self.files) for irow in range(row, nrows): self.radar_dat = self.Read_radar(os.path.join(self.lastOpenDir, self.files[irow])) if self.radar_dat != 0: self.setSelected(self.lastOpenDir + os.sep + self.files[irow]) self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_pushButton_3_clicked(self): """ Slot documentation goes here. """ if self.files is not None: items = self.listWidget.findItems(self.openbasename, Qt.MatchExactly) row = self.listWidget.row(items[0]) nrows = len(self.files) res_row = row + 1 if res_row == nrows: res_row = 0 self.radar_dat = self.Read_radar(self.lastOpenDir + os.sep + self.files[res_row]) if self.radar_dat != 0: self.setSelected(self.lastOpenDir + os.sep + self.files[res_row]) self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_15_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_12_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_14_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_10_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_13_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_11_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_2_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_4_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_5_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_3_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_1_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_7_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_8_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_6_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) @pyqtSlot() def on_radioButton_9_clicked(self): """ Slot documentation goes here. """ if self.radar_dat is not None: self.plot_graph_PPI(self.radar_dat, self.find_level_in_groupBox(), self.find_var_in_groupBox(), self.actionwithmap.isChecked(), self.actioncontinuous.isChecked()) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) ui = MainWindow() ui.show() sys.exit(app.exec_())