def NC_to_tiffs(data, out_path):
coord = 4326 # 预设WGS84坐标系
nc_data_obj = nc.Dataset(data)
key = list(nc_data_obj.variables.keys()) # 提取所有变量名
print('基础属性为 ', key)
# 自动定位核心维度(lon/lat/time)
try:
lon_size = [i for i, x in enumerate(key) if x.lower().find('lon') != -1][0]
lat_size = [i for i, x in enumerate(key) if x.lower().find('lat') != -1][0]
time_size = [i for i, x in enumerate(key) if x.lower().find('time') != -1][0]
except IndexError:
raise ValueError("找不到必要的维度变量(lon/lat/time)")
# 交互式获取目标波段名
global band_name
if not band_name:
band_name = input("请输入您想要输出的波段的名字:") # 支持中文/英文变量名
# 解析数据与元信息
Lon = nc_data_obj.variables[key[lon_size]][:]
Lat = nc_data_obj.variables[key[lat_size]][:]
time = nc_data_obj.variables[key[time_size]]
times = nc.num2date(time[:], time.units) # 时间戳转日期对象
band = np.asarray(nc_data_obj.variables[key[band_size]]).astype(float)
# 地理配准参数计算
LonMin, LatMax, LonMax, LatMin = [Lon.min(), Lat.max(), Lon.max(), Lat.min()]
N_Lat = len(Lat)
N_Lon = len(Lon[0]) if Lon.ndim == 2 else len(Lon) # 兼容一维/二维经度
Lon_Res = (LonMax - LonMin) / (N_Lon - 1) # 计算分辨率
# 逐时间步生成TIF
for i in range(band.shape[0]):
dt = times[i].strftime("%Y-%m") # 格式化为年月
out_tif_name = os.path.join(out_path, f"{os.path.basename(data).replace('.nc', '')}_{dt}.tif")
if os.path.exists(out_tif_name): # 避免重复生成
print(f"文件 {out_tif_name} 已存在,跳过")
continue
# 创建GeoTIFF
driver = gdal.GetDriverByName('GTiff')
out_tif = driver.Create(out_tif_name, N_Lon, N_Lat, 1, gdal.GDT_Float32)
out_tif.SetGeoTransform((LonMin, Lon_Res, 0, LatMax, 0, -Lat_Res)) # 六参数坐标系
# 处理填充值(关键!)
fill_value = getattr(nc_data_obj.variables[key[band_size]], '_FillValue', 1e20)
arr1 = band[i, :, :].copy()
arr1[arr1 == fill_value] = -32767 # 替换为GIS通用无数据值
# 反转纬度方向(解决南北颠倒问题)
if Lat[0] < Lat[-1]: # 纬度递增(数据从南到北排列)
reversed_arr = arr1[::-1] # 反转数组保证TIF中纬度从上到下递减
else:
reversed_arr = arr1
# 写入数据并设置元信息
out_tif.GetRasterBand(1).WriteArray(reversed_arr)
out_tif.GetRasterBand(1).SetNoDataValue(-32767)
out_tif.SetProjection(osr.SpatialReference().ImportFromEPSG(coord).ExportToWkt())
out_tif.FlushCache()
print(f"成功生成:{out_tif_name}")