由于做项目需要运用到netCDF格式的气象数据,而ArcGIS中需要用栅格影像进行处理,对于较多的文件,ArcGIS一个个手动转换过于繁琐,因此我们采用Python进行转换,当然也可以采用matlab进行转换。
首先需要安装下面几个库:
(资料图片仅供参考)
import os import netCDF4 as nc import numpy as np from osgeo import gdal, osr, ogr import glob
我们可以在下面网址中寻找对应python安装版本的安装包,下载后,在pycharm控制台中直接安装即可。例如pip install netCDF4-1.5.8-cp39-cp39-
win_amd64.whl
https://www.lfd.uci.edu/~gohlke/pythonlibs/
安装之后即可进行转换:
def nc2tif(data, Output_folder): tmp_data = nc.Dataset(data) # 利用.Dataset()方法读取nc数据 print("tmp_data", tmp_data) Lat_data = tmp_data.variables["lat"][:] Lon_data = tmp_data.variables["lon"][:] # print(Lat_data) # print(Lon_data) tmp_arr = np.asarray(tmp_data.variables["temp"]) # 影像的左上角&右下角坐标 Lonmin, Latmax, Lonmax, Latmin = [Lon_data.min(), Lat_data.max(), Lon_data.max(), Lat_data.min()] # print(Lonmin, Latmax, Lonmax, Latmin) # 分辨率计算 Num_lat = len(Lat_data) # 5146 Num_lon = len(Lon_data) # 7849 Lat_res = (Latmax - Latmin) / (float(Num_lat) - 1) Lon_res = (Lonmax - Lonmin) / (float(Num_lon) - 1) # print(Num_lat, Num_lon) # print(Lat_res, Lon_res) for i in range(len(tmp_arr[:])): # i=0,1,2,3,4,5,6,7,8,9,... # 创建tif文件 driver = gdal.GetDriverByName("GTiff") out_tif_name = Output_folder + "\\" + data.split("\\")[-1].split(".")[0] + "_" + str(i + 1) + ".tif" out_tif = driver.Create(out_tif_name, Num_lon, Num_lat, 1, gdal.GDT_Int16) # 设置影像的显示范围 # Lat_re前需要添加负号 geotransform = (Lonmin, Lon_res, 0.0, Latmax, 0.0, -Lat_res) out_tif.SetGeoTransform(geotransform) # 定义投影 prj = osr.SpatialReference() prj.ImportFromEPSG(4326) # WGS84 out_tif.SetProjection(prj.ExportToWkt()) # 数据导出 out_tif.GetRasterBand(1).WriteArray(tmp_arr[i]) # 将数据写入内存,此时没有写入到硬盘 out_tif.FlushCache() # 将数据写入到硬盘 out_tif = None # 关闭tif文件 def main(): Input_folder = r"E:\competition\航天宏图\2-meter air temperature_CMFD\Data_forcing_01yr_010deg\\" # Input_folder = r"E:\competition\航天宏图\2-meter air temperature_CMFD\Data_forcing_01mo_010deg\\" Output_folder = r"E:\competition\航天宏图\2-meter air temperature_CMFD\tif\\" # 读取所有数据 data_list = glob.glob(os.path.join(Input_folder + "*.nc")) print(data_list) for i in range(len(data_list)): data = data_list[i] nc2tif(data, Output_folder) print(data + "转tif成功")
值得注意的是,tmp_arr = np.asarray(tmp_data.variables["temp"])中的temp可以根据需要转换的波段进行选择,我们可以在读取数据之后print一下,找到对应的波段进行替换即可。如下图中我们应该选择的就是temp。
完成上述步骤即可得到所需的tif图像:
在上述代码中,经过处理的影像是倒置的,可能是处理过程中仿射矩阵读写错误导致的。因此我们可以在写入影像的时候,进行影像的垂直镜像操作即可:WriteArray(ndvi_arr_float[i][::-1])
def NC_to_tiffs(data, Output_folder): nc_data_obj = nc.Dataset(data) Lon = nc_data_obj.variables["lon"][:] Lat = nc_data_obj.variables["lat"][:] ndvi_arr = np.asarray(nc_data_obj.variables["temp"]) ndvi_arr_float = ndvi_arr.astype(float) / 10000 之间 # 影像的左上角和右下角坐标 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(ndvi_arr[:])): driver = gdal.GetDriverByName("GTiff") out_tif_name = Output_folder + "\\" + data.split("\\")[-1].split(".")[0] + "_" + str(i + 1) + ".tif" out_tif = driver.Create(out_tif_name, N_Lon, N_Lat, 1, gdal.GDT_Float32) geotransform = (LonMin, Lon_Res, 0, LatMax, 0, -Lat_Res) out_tif.SetGeoTransform(geotransform) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) out_tif.SetProjection(srs.ExportToWkt()) # 数据写出 out_tif.GetRasterBand(1).WriteArray(ndvi_arr_float[i][::-1]) # 将数据写入内存,此时没有写入硬盘 此处[::-1]用于图像的垂直镜像对称,避免图像颠倒 out_tif.FlushCache() # 将数据写入硬盘 out_tif = None # 注意必须关闭tif文件
这样便可以得到正确输出的影像:
当然,我们除了在写入时做垂直镜像操作之外,还可以利用python对图像进行几何变换来实现翻转。具体代码如下:
图像水平翻转:
# 图像水平翻转 im_data_hor = np.flip(im_data, axis=2) hor_path = train_image_path + "\\" + str(tran_num) + imageList[i][-4:] writeTiff(im_data_hor, im_geotrans, im_proj, hor_path)
标签水平翻转:
# 标签水平翻转 Hor = cv2.flip(label, 1) hor_path = train_label_path + "\\" + str(tran_num) + labelList[i][-4:] cv2.imwrite(hor_path, Hor) tran_num += 1
图像垂直翻转:
# 图像垂直翻转 im_data_vec = np.flip(im_data, axis=1) vec_path = train_image_path + "\\" + str(tran_num) + imageList[i][-4:] writeTiff(im_data_vec, im_geotrans, im_proj, vec_path)
标签垂直翻转:
# 标签垂直翻转 Vec = cv2.flip(label, 0) vec_path = train_label_path + "\\" + str(tran_num) + labelList[i][-4:] cv2.imwrite(vec_path, Vec) tran_num += 1
图像镜像翻转:
# 图像对角镜像 im_data_dia = np.flip(im_data_vec, axis=2) dia_path = train_image_path + "\\" + str(tran_num) + imageList[i][-4:] writeTiff(im_data_dia, im_geotrans, im_proj, dia_path)
标签镜像翻转:
# 标签对角镜像 Dia = cv2.flip(label, -1) dia_path = train_label_path + "\\" + str(tran_num) + labelList[i][-4:] cv2.imwrite(dia_path, Dia) tran_num += 1
若是输出路径的文件夹没有建立好,则会报如下错误。当然,为了减少工作量,也可以定义一个函数,如果路径不存在则自动创建,就可以解决这个问题。
到此这篇关于基于Python实现nc批量转tif格式的文章就介绍到这了,更多相关Python nc转tif内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 1亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 2现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 3如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 4AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 5转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 6充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 7好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 8名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?
- 9亚马逊云科技成立量子网络中心致力解决量子计算领域的挑战
- 10京东绿色建材线上平台上线 新增用户70%来自下沉市场