import numpy as np
import netCDF4 as nc
import gdal,osr,ogr
import os
from PyQt5.QtWidgets import QApplication,QMainWindow,QHBoxLayout,QVBoxLayout,\
QLineEdit,QPushButton,QPlainTextEdit,QProgressBar,QWidget,QMessageBox,QFileDialog,QLabel
from PyQt5.QtGui import *
class FirstMainWin(QMainWindow):
def __init__(self,parent=None):
super(FirstMainWin,self).__init__(parent)
self.initWin()
self.btnOk.clicked.connect(self.onBtnOk)
self.btnOkOutput.clicked.connect(self.onBtnOkOutput)
self.btnCal.clicked.connect(self.onBtnCal)
def initWin(self):
self.setWindowTitle("NC文件转TIF工具")
self.setWindowIcon(QIcon("./resources/win.ico"))
self.lablein = QLabel(self.centralWidget())
self.lablein.setText("输入文件路径")
self.lineEdit = QLineEdit(self.centralWidget());
self.btnOk = QPushButton("确定", self);
self.lableout = QLabel(self.centralWidget())
self.lableout.setText("输出文件路径")
self.lineEditOutput = QLineEdit(self.centralWidget());
self.btnOkOutput = QPushButton("确定", self);
self.labelField = QLabel(self.centralWidget())
self.labelField.setText("所提取的字段")
self.lineEditField = QLineEdit(self.centralWidget());
self.labelLon = QLabel(self.centralWidget())
self.labelLon.setText("经度字段")
self.lineEditLon = QLineEdit(self.centralWidget());
self.labelLat = QLabel(self.centralWidget())
self.labelLat.setText("纬度字段")
self.lineEditLat = QLineEdit(self.centralWidget());
self.labelResLon = QLabel(self.centralWidget())
self.labelResLon.setText("经度像元大小(可选)")
self.lineEditResLon = QLineEdit(self.centralWidget());
self.labelResLat = QLabel(self.centralWidget())
self.labelResLat.setText("纬度像元大小(可选)")
self.lineEditResLat = QLineEdit(self.centralWidget());
self.plainEdit = QPlainTextEdit(self);
self.btnCancel = QPushButton("取消", self);
self.btnCal = QPushButton("转换", self);
self.progressBar = QProgressBar(self);
self.h = QHBoxLayout();
self.h2 = QHBoxLayout();
self.h3 = QHBoxLayout();
self.h4 = QHBoxLayout();
self.h5 = QHBoxLayout();
self.v = QVBoxLayout();
self.h.addWidget(self.lablein);
self.h.addWidget(self.lineEdit);
self.h.addWidget(self.btnOk);
self.h2.addWidget(self.lableout)
self.h2.addWidget(self.lineEditOutput)
self.h2.addWidget(self.btnOkOutput)
self.h3.addStretch()
self.h3.addWidget(self.btnCancel)
self.h3.addWidget(self.btnCal)
self.h4.addWidget(self.labelField)
self.h4.addWidget(self.lineEditField)
self.h4.addWidget(self.labelLon)
self.h4.addWidget(self.lineEditLon)
self.h4.addWidget(self.labelLat)
self.h4.addWidget(self.lineEditLat)
self.h5.addWidget(self.labelResLon)
self.h5.addWidget(self.lineEditResLon)
self.h5.addWidget(self.labelResLat)
self.h5.addWidget(self.lineEditResLat)
self.v.addLayout(self.h);
self.v.addLayout(self.h4)
self.v.addLayout(self.h5)
self.v.addLayout(self.h2)
self.v.addWidget(self.plainEdit);
self.v.addLayout(self.h3)
self.v.addWidget(self.progressBar);
self.central = QWidget()
self.central.setLayout(self.v)
self.setCentralWidget(self.central)
def onBtnOk(self):
fileName, fileType = QFileDialog.getOpenFileName(self, '选择文件', 'G:/chinaT', 'Text files(*.nc *.NC)')
if (fileName == ''):
return
NC_DS = nc.Dataset(fileName)
print(NC_DS.variables.keys())
print(len(NC_DS.variables.keys()))
timeExist = True
if len(NC_DS.variables.keys()) == 3:
timeExist= False
self.lineEdit.setText(fileName)
self.plainEdit.setPlainText('输入文件名称:'+fileName)
self.plainEdit.appendPlainText('波段个数:' +str(self.bandCount(fileName,timeExist)))
self.plainEdit.appendPlainText(str(NC_DS.variables.keys()))
# 计算像元大小
def onBtnOkOutput(self):
if self.lineEditField.text()=='' or self.lineEditLon.text()=='' or self.lineEditLat.text()=='' or self.lineEdit.text()=='':
QMessageBox.information(None,"提示","输入路径或提取字段与经纬度像元大小没有填写")
return
fileName= QFileDialog.getExistingDirectory(self,'选择文件','')
if (fileName == ''):
return
self.lineEditOutput.setText(fileName)
self.plainEdit.appendPlainText('输出路径:' + fileName)
# print(str(self.getRes(self.lineEdit.text(),str(self.lineEditLon.text()),str(self.lineEditLat.text()))))
self.plainEdit.appendPlainText("像元大小(由于程序读取数值精度原因导致与实际大小有一定的相差,最好手动填写像元大小)\n\t"+str(self.getRes(self.lineEdit.text(),self.lineEditLon.text(),self.lineEditLat.text())))
def onBtnCal(self):
if self.lineEditOutput.text() == '':
QMessageBox.information(None,"提示","输入信息不完整,无法转换")
return
self.progressBar.setValue(0)
self.NC_to_tiffs(self.lineEdit.text(),self.lineEditOutput.text(),self.lineEditField.text(),\
self.lineEditLon.text(),self.lineEditLat.text(),self.lineEditResLon.text(),self.lineEditResLat.text())
def getRes(self,infilename,lonField,latField):
NC_DS = nc.Dataset(infilename)
Lon = NC_DS.variables[lonField][:]
Lat = NC_DS.variables[latField][:]
LonMin, LatMax, LonMax, LatMin = [Lon.min(), Lat.max(), Lon.max(), Lat.min()]
N_Lat = Lat.shape[0] ###行数计算
N_Lon = Lon.shape[0] ####列数
Lon_Res = (LonMax - LonMin) / (float(N_Lon))
Lat_Res = (LatMax - LatMin) / (float(N_Lat))
return ([Lon_Res,Lat_Res])
def bandCount(self,infilename, multiBand,field="time"):
NC_DS = nc.Dataset(infilename)
count = 0
if multiBand == True:
timVar = NC_DS.variables[field][:]
count = timVar.size
else:
count = 1
return count
def NC_to_tiffs(self,infilename, outfilename, field, lonField, latField, lonRes,latRes,crsID="4326"):
self.plainEdit.appendPlainText("-------------------处理中------------------")
NC_DS = nc.Dataset(infilename)
print(lonField)
print(latField)
Lon = NC_DS.variables[lonField][:]
Lat = NC_DS.variables[latField][:]
TSK = np.asarray(NC_DS.variables[field]) ####提取TSK信息
bandCount = 0
if len(TSK.shape) == 2:
bandCount = 1
else:
bandCount = len(TSK[:])
print(bandCount)
self.progressBar.setMaximum(bandCount)
LonMin, LatMax, LonMax, LatMin = [Lon.min(), Lat.max(), Lon.max(), Lat.min()]
print("最大经度:", LonMax, "最小经度:", LonMin, "最大纬度:", LatMax, "最小纬度:", LatMin)
print(Lat.shape)
N_Lat = Lat.shape[0] ###行数计算
N_Lon = Lon.shape[0] ####列数
Lon_Res= 0
Lat_Res = 0
if lonRes =='' or latRes=='':
Lon_Res = (LonMax - LonMin) / (float(N_Lon))
Lat_Res = (LatMax - LatMin) / (float(N_Lat))
else:
Lon_Res = float(lonRes)
Lat_Res = float(latRes)
print("水平方向上的像元大小:", Lon_Res, "竖直方向上像元大小:", Lat_Res)
outputFilePrefix = (os.path.basename(infilename).