大部分气象数据都是NC、NC4文件格式,因此如何读取NC文件,对于气象数据而言是十分重要的。本章主要涉及NC转TIF计算,以及批量读取TIF,批量计算年累计蒸发。

涉及库包括netCDF4、gdal,安装库的流程内容在本文中不多叙述。

导入库

import glob
import netCDF4 as nc
import numpy as np
from osgeo import gdal,osr,ogr

第一步读取文件夹文件及读取nc文件

glob是一个很好用的读取文件夹中特定文件的库

Input_folder = r'.\nc'
Output_folder = r'.\tif\output'
# 读取所有nc数据
data_list = glob.glob(Input_folder + '/*.nc4')
data_list[:5]
out[2]:
['.\\nc\\GLDAS_NOAH025_M.A202101.021.nc4','.\\nc\\GLDAS_NOAH025_M.A202102.021.nc4','.\\nc\\GLDAS_NOAH025_M.A202103.021.nc4','.\\nc\\GLDAS_NOAH025_M.A202104.021.nc4','.\\nc\\GLDAS_NOAH025_M.A202105.021.nc4']

读取nc文件基本内容,关于注释的两行内容,读者可以自行查看

具体有几项需要说明一下,后续定义NC_to_tiffs函数时需要修改部分内容,包括缺失值missing_value,变量名称variables,dimensions中对于经纬度的名称定义lons,lats

nc_data_obj = nc.Dataset(data_list[0])
print(nc_data_obj, type(nc_data_obj))  # 了解NC_DS的数据类型,<class 'netCDF4._netCDF4.Dataset'>
# print(nc_data_obj.variables)  # 了解变量的基本信息
# print(nc_data_obj)
out[3]:
<class 'netCDF4._netCDF4.Dataset'>
root group (NETCDF4 data model, file format HDF5):missing_value: -9999.0tavg definition:: past 3-hour averageacc definition:: past 3-hour accumulationinst definition:: instantaneoustitle: GLDAS2.1 LIS land surface model output monthly meaninstitution: NASA GSFCsource: Noah_v3.6 forced with GDAS-AGRMET-GPCPv13rA1_202101history: created on date: 2021-04-23T11:19:32.357references: Rodell_etal_BAMS_2004, Kumar_etal_EMS_2006, Peters-Lidard_etal_ISSE_2007conventions: CF-1.6comment: website: https://ldas.gsfc.nasa.gov/gldas, https://lis.gsfc.nasa.gov/MAP_PROJECTION: EQUIDISTANT CYLINDRICALSOUTH_WEST_CORNER_LAT: -59.875SOUTH_WEST_CORNER_LON: -179.875DX: 0.25DY: 0.25dimensions(sizes): lon(1440), lat(600), time(1), bnds(2)variables(dimensions): float32 lat(lat), float32 lon(lon), float64 time(time), float64 time_bnds(time, bnds), float32 Swnet_tavg(time, lat, lon), float32 Lwnet_tavg(time, lat, lon), float32 Qle_tavg(time, lat, lon), float32 Qh_tavg(time, lat, lon), float32 Qg_tavg(time, lat, lon), float32 Snowf_tavg(time, lat, lon), float32 Rainf_tavg(time, lat, lon), float32 Evap_tavg(time, lat, lon), float32 Qs_acc(time, lat, lon), float32 Qsb_acc(time, lat, lon), float32 Qsm_acc(time, lat, lon), float32 AvgSurfT_inst(time, lat, lon), float32 Albedo_inst(time, lat, lon), float32 SWE_inst(time, lat, lon), float32 SnowDepth_inst(time, lat, lon), float32 SoilMoi0_10cm_inst(time, lat, lon), float32 SoilMoi10_40cm_inst(time, lat, lon), float32 SoilMoi40_100cm_inst(time, lat, lon), float32 SoilMoi100_200cm_inst(time, lat, lon), float32 SoilTMP0_10cm_inst(time, lat, lon), float32 SoilTMP10_40cm_inst(time, lat, lon), float32 SoilTMP40_100cm_inst(time, lat, lon), float32 SoilTMP100_200cm_inst(time, lat, lon), float32 PotEvap_tavg(time, lat, lon), float32 ECanop_tavg(time, lat, lon), float32 Tveg_tavg(time, lat, lon), float32 ESoil_tavg(time, lat, lon), float32 RootMoist_inst(time, lat, lon), float32 CanopInt_inst(time, lat, lon), float32 Wind_f_inst(time, lat, lon), float32 Rainf_f_tavg(time, lat, lon), float32 Tair_f_inst(time, lat, lon), float32 Qair_f_inst(time, lat, lon), float32 Psurf_f_inst(time, lat, lon), float32 SWdown_f_tavg(time, lat, lon), float32 LWdown_f_tavg(time, lat, lon)groups:  <class 'netCDF4._netCDF4.Dataset'>

定义NC_to_tiffs函数

继续重复,对于不同nc文件需要注意修改缺失值missing_value,变量名称variables,dimensions中对于经纬度的名称定义lons,lats。

如果lats是从小到大排序,需要设置 u_arr[ i ] [::-1]

另外需要考虑数据单位问题,在本章节中的蒸发量为例,GLDAS对于 “Evap_tavg” 的单位定义为 kg m-2 s-1 ,kg m-2 相当于 mm,所以对于月尺度的GLDAS数据蒸发量而言,只需要乘以时间即可。

def NC_to_tiffs(data, Output_folder, bandname):nc_data_obj = nc.Dataset(data)
#     print(nc_data_obj, type(nc_data_obj))  # 了解NC_DS的数据类型,<class 'netCDF4._netCDF4.Dataset'>
#     print(nc_data_obj.variables)  # 了解变量的基本信息
#     print(nc_data_obj)Lon = nc_data_obj.variables['lon'][:]Lat = nc_data_obj.variables['lat'][:]u_arr = np.asarray(nc_data_obj.variables[bandname])  # 这里根据需求输入想要转换的波段名称# 影像的左上角和右下角坐标LonMin, LatMax, LonMax, LatMin = [Lon.min(), Lat.max(), Lon.max(), Lat.min()]# 分辨率计算N_Lat = len(Lat)N_Lon = len(Lon)Lon_Res = (LonMax - LonMin) / (float(N_Lon) - 1)Lat_Res = (LatMax - LatMin) / (float(N_Lat) - 1)for i in range(len(u_arr[:])):# 创建.tif文件driver = gdal.GetDriverByName('GTiff')out_tif_name = Output_folder + '/' + bandname +'_'  + data.split('\\')[2].split('.')[1][1:] +  '.tif'out_tif = driver.Create(out_tif_name, N_Lon, N_Lat, 1, gdal.GDT_Float32)# 设置影像的显示范围# -Lat_Res一定要是-的geotransform = (LonMin, Lon_Res, 0, LatMax, 0, -Lat_Res)out_tif.SetGeoTransform(geotransform)# 获取地理坐标系统信息,用于选取需要的地理坐标系统srs = osr.SpatialReference()srs.ImportFromEPSG(4326)  # 定义输出的坐标系为"WGS 84",AUTHORITY["EPSG","4326"]out_tif.SetProjection(srs.ExportToWkt())  # 给新建图层赋予投影信息# 去除异常值u_arr[u_arr[:, :] == -9999.0] = np.nan# 数据写出out_tif.GetRasterBand(1).WriteArray(u_arr[i][::-1]*60*60*24*30)# 将数据写入内存,此时没有写入硬盘 此处[::-1]用于图像的垂直镜像对称,避免图像颠倒out_tif.FlushCache()  # 将数据写入硬盘del out_tif  # 注意必须关闭tif文件

导出TIF并保存

for i in range(len(data_list)):data = data_list[i]NC_to_tiffs(data, Output_folder,"Evap_tavg")

裁剪TIF

虽然获得了全球蒸发量数据,换到GIS软件中裁剪也是可以的,但是好麻烦,尤其是遇到需要统计年单位结果时候。

读取TIF数据

Input_folder = './tif/output/'
Output_folder = './tif/clip/'
# 读取所有nc数据
data_list = glob.glob(Input_folder + '/*.tif')
data_list[:5]

定义裁剪函数

def clipTif(data):input_shape = r"shp/Uzb.shp" output_raster= Output_folder + data.split('\\')[1].split('.')[0].split("_")[-1] +".tif"# tif输入路径,打开文件input_raster = data# 矢量文件路径,打开矢量文件input_raster=gdal.Open(input_raster)ds = gdal.Warp(output_raster, # 裁剪图像保存完整路径(包括文件名)input_raster, # 待裁剪的影像# warpMemoryLimit=500 内存大小Mformat='GTiff', # 保存图像的格式cutlineDSName = input_shape, # 矢量文件的完整路径cropToCutline = True,copyMetadata=True,creationOptions=['COMPRESS=LZW',"TILED=True"],cutlineWhere="FIELD = 'whatever'",dstNodata=None)

裁剪

for i in range(len(data_list)):data = data_list[i]clipTif(data)

统计年蒸发总量

定义读取tif函数

def readTif(fileName):dataset = gdal.Open(fileName)im_width = dataset.RasterXSize #栅格矩阵的列数im_height = dataset.RasterYSize #栅格矩阵的行数
#     print(im_width, im_height)im_data = dataset.ReadAsArray(0,0,im_width,im_height)#获取数据im =  im_data[0:im_height,0:im_width]#获取蓝波段return im

读取文件夹

Input_folder = './tif/clip/'
Output_folder = './tif/sum/'
# 读取所有nc数据
data_list = glob.glob(Input_folder + '/*.tif')
data_list[:5]

设置输出的基本格式[方便批处理时候的标准参考]

dataset = gdal.Open(data_list[0])
im_width = dataset.RasterXSize #栅格矩阵的列数
im_height = dataset.RasterYSize #栅格矩阵的行数
im_bands = dataset.RasterCount #波段数
im_data = dataset.ReadAsArray(0,0,im_width,im_height)#获取数据
im_geotrans = dataset.GetGeoTransform()#获取仿射矩阵信息
im_proj = dataset.GetProjection()#获取投影信息

定义写入函数

def writeTiff(im_data,path,im_width,im_height,im_bands,im_geotrans,im_proj):if 'int8' in im_data.dtype.name:datatype = gdal.GDT_Byteelif 'int16' in im_data.dtype.name:datatype = gdal.GDT_UInt16else:datatype = gdal.GDT_Float32if len(im_data.shape) == 3:im_bands, im_height, im_width = im_data.shapeelif len(im_data.shape) == 2:im_data = np.array([im_data])else:im_bands, (im_height, im_width) = 1,im_data.shape#创建文件driver = gdal.GetDriverByName("GTiff")path = Output_folder + "\\" + path.split('\\')[1].split('.')[0][:4] + ".tif"dataset = driver.Create(path, im_width, im_height, im_bands, datatype)if(dataset!= None):dataset.SetGeoTransform(im_geotrans) #写入仿射变换参数dataset.SetProjection(im_proj) #写入投影for i in range(im_bands):dataset.GetRasterBand(i+1).WriteArray(im_data[i])del dataset

输出年结果

需要注意的问题是年单位时候对于降水、蒸发等的定义问题,可以对tmp进行修改

index = 1
tmp = np.zeros(readTif(data_list[0]).shape ,dtype=float)
for i in range(0, len(data_list)):if index % 12 == 0:print(index / 12)writeTiff(tmp,data_list[i -1] ,im_width ,im_height ,im_bands ,im_geotrans ,im_proj)tmp = np.zeros(readTif(data_list[i]).shape ,dtype=float)tmp += np.array(readTif(data_list[i]))index+=1

气象数据NC批量转TIF及月尺度计算年尺度-同理其他指标相关推荐

  1. PythonR | nc批量转tif

    nc批量转tif 1. nc数据介绍: 2. 编程实践 (1) 基于Python (2) 基于R语言 3. nc数据处理再实践(时间维度为:年月日时分秒) 1. nc数据介绍: NetCDF(netw ...

  2. 基于Python的nc批量转tif

    由于做项目需要运用到netCDF格式的气象数据,而ArcGIS中需要用栅格影像进行处理,对于较多的文件,ArcGIS一个个手动转换过于繁琐,因此我们采用Python进行转换,当然也可以采用matlab ...

  3. MSWEP数据nc格式转tif格式

    这里将数据从0.1°重采样到0.25° %% clc; clear;%% fullpath = mfilename('fullpath'); [path, name] = fileparts(full ...

  4. 气象数据下载网站(存档)

    https://www.cnblogs.com/icydengyw/p/12664027.html 1.http://weather.uwyo.edu/upperair/seasia.html 需要提 ...

  5. 批量将NC文件转为tif格式

    批量将多年的NC文件转为tif格式进行处理(来源:https://www.geek-share.com/detail/2763962738.html) 所参考和借鉴的文章的链接如下: https:// ...

  6. Python批量下载CHIRPS气象数据并完成解压裁剪等

    文章目录 前言 一.CHIRPS是什么? 二.实现步骤 1.下载数据 2.解压缩 3.批量裁剪 三.完整代码如下 四.代码结果 前言   最近需要下载气象数据--CHIRPS,借助之前学的批量下载哨兵 ...

  7. matlab实现nc文件批量转tif文件

    (1)成功运行例子:(PM1) MATLAB:读取nc文件并将nc文件转为tif文件输出_BetterQ.的博客-CSDN博客_nc文件转tif clc clear %% 批读取NC文件的准备工作 d ...

  8. MODIS数据批量裁剪并合成月尺度数据:以MOD13A1为例

    1 excel表里列举全部[栅格计算器] 指令. 其中MODIS文件名可利用python代码全部输出 代码(注意更改路径): import os import glob path = "E: ...

  9. 1、EC气象数据批量下载

    EC气象数据批量下载 前言 一.前期准备 1. 配置Python环境 2. 安装依赖库: 3. 注册EC账户并获得Key 3.1 注册账户 3.2 获取API信息 4. 选择数据 二.编写脚本开始下载 ...

最新文章

  1. bzoj2729: [HNOI2012]排队
  2. 自制口袋妖怪_承诺和口袋妖怪-我如何学会异步思考
  3. Poj2826 An Easy Problem
  4. java scala中传递变长参数
  5. 关于合格工程师素养的一些思考
  6. 第三篇:知其然,知其所以然-USB音频设备的开发过程
  7. 分享一个超厉害的网站,几乎解决一切command not found问题
  8. 巧用 Dummy 解决断网情况下的网络访问问题
  9. 前端处理无网络兜底图片展示
  10. java设计triangle三角形_Java:【三角形类Triangle】设计一个名为Triangle的类来扩展GeometricObject类。该类包括:...
  11. 金丹期前期:1.2、python语言-python的基本元素:变量及命名规则、数据类型及转换、运算符、输入输出
  12. React Native手动实现调用原生相机相册(Android端)
  13. python的几个有趣小程序
  14. 科研热点|警惕!10月WOS数据库更新,这2本期刊被剔除SCI~
  15. 解决maven工程的properties文件内容呈灰色
  16. 佛山计算机专业刁,计算机应用基础 高职计算机大类专业 刁爱军项目策划方案汇报 原始.pptx...
  17. python实时播放音频和录音_python实现播放音频和录音功能示例代码
  18. WORD行间距无法调整?
  19. 2021年Java面试心得:java短信模板设计
  20. 在html页面上内容竖着显示

热门文章

  1. 基于SSM的疫情物资管理系统
  2. 中国省份及其地级市整理JSON版(2015-08-23)
  3. 使用标签〈base〉
  4. R语言在计算基因表达量均值,使用函数mean,R报错:既不是数值也不是逻辑值,返回NA。
  5. 基于Springboot的宠物医院管理系统-JAVA【数据库设计、论文、源码、开题报告】
  6. Linux磁盘管理:磁盘分区的分配和格式化磁盘
  7. 小波卷积网络Multi-level Wavelet-CNN for Image Restoration论文阅读笔记
  8. 识别人脸伪装 仅看眼睛和嘴巴就能识别一半
  9. smtp 协议 MIME协议
  10. BP神经网络的数学本质