python gdal nc数据转tif 包括如何获取变量及变量属性

本文介绍了如何使用GDAL库将gdalnc格式转换为tif格式,涉及地理变换、空间参考系统的设置,以及利用netCDF4库获取和处理变量属性,包括格里高利历时间的转换。同时提到处理nc数据时需要注意的_FillValue问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 gdal nc转换为tif

地理变换是从图像坐标空间(行、列)(也称为(像素、线)到地理参考坐标空间(投影或地理坐标)的仿射变换。

总共包含6个元素

image-20231212154914171

ExportToWkt 是 GDAL(Geospatial Data Abstraction Library)库中的一个函数,用于将空间参考信息导出为 Well-Known Text(WKT)格式。

Well-Known Text(WKT)是一种文本表示形式,用于描述空间参考系统(Spatial Reference System)的信息,包括坐标系、投影和地理转换参数等。WKT 是一种通用的标准,可以在不同的 GIS(地理信息系统)和地理数据处理软件之间共享和交换空间参考信息。
这里以ERA5数据为例(按月获取小时温度数据)
在这里插入图片描述

def nc_to_tif(data, lons, lats, timestamp):
    # 影像的左上角和右下角坐标
    LonMin, LatMax, LonMax, LatMin = [lons.min(), lats.max(), lons.max(), lats.min()]
    lon_number = len(lons)
    lat_number = len(lats)
    # 1 创建tif文件
    driver = gdal.GetDriverByName('GTiff')
    out_tif_name = output_directory + timestamp + '_t2m.tif'
    out_tif = driver.Create(out_tif_name, lon_number-1, lat_number-1, 1, gdal.GDT_Float32)

    # 2 设置影像显示范围[建立仿射变换]
    # 分辨率与原始数据的空间分辨率需要保持一致
    Lon_Res = 0.1
    Lat_Res = 0.1
    geotransform = (LonMin, Lon_Res, 0, LatMax, 0, -Lat_Res)
    out_tif.SetGeoTransform(geotransform)
    # 3 将地理经纬度坐标转换为投影坐标
    projection = gdal.osr.SpatialReference()
    # 4326指'WGS84'
    projection.ImportFromEPSG(4326)
    # 4 为tif数据赋予投影信息
    # 将空间参考以WKT格式输出
    out_tif.SetProjection(projection.ExportToWkt())
    # 5 将数据写入栅格
    out_tif.GetRasterBand(1).WriteArray(data)
    out_tif.GetRasterBand(1).SetNoDataValue(-9999)
    del out_tif

2 利用netCDF4获取变量及变量属性

from netCDF4 import Dataset

# 打开nc文件
nc_file = Dataset("test.nc", "w", format="NETCDF4")
# 获取NC文件的维度信息
print("\n维度信息:")
    for dimname, dim in nc_file.dimensions.items():
    	print(f"{dimname}: {len(dim)}")

# 获取变量信息以及变量的属性信息
print("\n变量信息:")
    for varname, var in nc_file.variables.items():
        print(f"{varname}:")
        print(f"数据类型: {var.dtype}")
        print(f"维度: {var.dimensions}")
        print(f"属性:")
        for attr in var.ncattrs():
            print(f"    {attr}: {getattr(var, attr)}")


# 根据特定的变量名获取变量
data = nc_file.variables['variable_name'][:]
# 根据特定的变量名和特定的属性名获取[对应的属性]
scale_factor = getattr(nc_file.variables['variable_name'], 'scale_factor')

3 进行gregorian时间类型的转换

公历(Gregorian calendar),也称为格里高利历、格列高利历、格雷戈里曆、西曆或新曆,是今天世界上使用最广泛的日历系统。它是由教皇格里高利十三世在1582年颁布的,以修正尤利乌斯日历的缺陷。公历采用365天5小时48分46秒的长度作为一年,并在必要时通过闰年来调整。与其他日历系统相比,公历更为准确,被广泛用于全球大部分国家和文化中。

简而言之,当提到格里高利历(Gregorian calendar)或公历时,通常是指今天全球通用的日期系统,用于标记时间、日期和年份。

进行nc时间维度的改变

利用nc.num2date()将[时间的数值数据]转换为[datetime]对象

 time_new = nc.num2date(nc_file.variables['time'][:], 'hours since 1900-01-01 00:00:00.0').data

image-20231212171722349

4 总结

  1. 对nc数据处理时,需要先判断是否是_FillValue
  2. 很重要: 使用netCDF4进行数据处理时,会自动进行【data×scale_factor+add_offset】的操作,自己不需要再进行处理
  3. 这里遇到了一个问题:按照左上角点的经纬度坐标、行数和列数,最终得到的tif数据的右下角点【经度总是多一份,纬度总是小一份】
    为了避免错误,我用IDL也测试了一下,也是同样的经纬度范围,这个问题先放在这

<think>好的,我需要帮助用户将ERA5NC格式数据换为TIF格式。用户提到了使用Python或GIS工具,所以我需要涵盖这两种方法。首先,我需要回忆一下相关的Python库和步骤,比如使用netCDF4和GDAL。同时,GIS工具可能包括ArcGIS或者QGIS的操作。 首先,我应该检查用户提供的引用内容。引用[1]提到使用GDAL处理NC数据时遇到的经纬度问题,需要注意_FillValue和自动的缩放操作。这可能影响到换后的TIF文件的坐标范围是否正确。引用[2]和[4]给出了Python代码示例,使用netCDF4和GDAL读取NC文件并导出为TIF。引用[3]提到了arcpy的MakeNetCDFRasterLayer方法,这属于ArcGIS的工具。 接下来,我需要整理Python方法的步骤。首先安装必要的库,如gdal和netCDF4。然后读取NC文件,提取变量,处理缺失值和缩放,接着设置地理变换参数和投影,最后用GDAL导出为TIF。这里需要注意用户提到的经纬度偏移问题,可能需要调整地理变换参数中的分辨率,确保右下角坐标正确。例如,如果原始数据的分辨率是0.25度,那么左上角的经度加上列数乘以分辨率可能会超过实际范围,可能需要减去一个分辨率值来修正。 对于GIS工具部分,ArcGIS中使用Make NetCDF Raster Layer工具,然后导出为TIF。QGIS则可以通过NetCDF浏览器加载变量,再导出。这些步骤相对直观,但用户可能遇到坐标系统不匹配的问题,需要确保投影设置正确。 另外,常见问题中提到的变量名和坐标轴顺序很重要。ERA5数据变量可能需要根据文档确认名称,比如温度可能是't2m'。GDAL在写入TIF时,数据的维度顺序可能是(lat, lon),而NC文件通常是(time, lat, lon),需要正确切片选择时间层。 最后,引用用户提供的链接作为参考,特别是GDAL的地理变换教程和CSDN的博客,这些资源能帮助用户更深入理解参数设置和问题排查。需要提醒用户注意处理多时间层时的循环导出,以及检查生成TIF的元数据是否正确。</think>### 分步解答:使用Python或GIS工具将ERA5 NC文件TIF格式 --- #### **方法一:Python实现(推荐)** **步骤1:安装依赖库** ```bash pip install gdal netCDF4 numpy ``` **步骤2:读取NC文件并提取变量** ```python import netCDF4 as nc import numpy as np from osgeo import gdal, osr # 读取NC文件 file_path = "ERA5_air_temperature.nc" data = nc.Dataset(file_path) # 提取变量(示例为2米气温,变量名需根据NC文件定义调整) temperature = data.variables['t2m'][:] # 可能为多维数组(时间、纬度、经度) lat = data.variables['latitude'][:] lon = data.variables['longitude'][:] ``` **步骤3:处理缺失值和缩放** ```python # 自动处理_FillValue、scale_factor和add_offset(netCDF4已自动处理) # 若需手动处理: # fill_value = data.variables['t2m']._FillValue # scaled_data = temperature * scale_factor + add_offset ``` **步骤4:设置地理变换参数** ```python # 左上角经纬度、分辨率(假设ERA5分辨率为0.25度) x_res = (lon[-1] - lon[0]) / (len(lon) - 1) # 经度分辨率 y_res = (lat[-1] - lat[0]) / (len(lat) - 1) # 纬度分辨率(通常为负值) geotransform = (lon[0], x_res, 0, lat[-1], 0, -abs(y_res)) # 修正经纬度偏移问题[^1] ``` **步骤5:导出为GeoTIFF** ```python driver = gdal.GetDriverByName('GTiff') output = driver.Create("output.tif", len(lon), len(lat), 1, gdal.GDT_Float32) # 设置坐标系(WGS84) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) output.SetProjection(srs.ExportToWkt()) output.SetGeoTransform(geotransform) # 写入数据(选择第一个时间层) output.GetRasterBand(1).WriteArray(temperature[0]) output.FlushCache() output = None ``` --- #### **方法二:GIS工具实现(ArcGIS/QGIS)** **ArcGIS操作流程:** 1. 打开 **ArcToolbox** → **多维工具** → **创建NetCDF栅格图层**。 2. 选择变量(如`t2m`)、维度(时间、纬度、经度)后生成栅格。 3. 右键图层 → **数据** → **导出为TIFF**,设置输出路径和坐标系[^3]。 **QGIS操作流程:** 1. 打开 **NetCDF浏览器**(插件)→ 加载NC文件 → 选择变量和时间层。 2. 右键图层 → **导出** → **另存为GeoTIFF**,设置CRS为EPSG:4326[^4]。 --- #### **常见问题与注意事项** 1. **变量名不匹配** ERA5数据变量名需根据文件元数据确认(如2米气温为`t2m`,海平面气压为`msl`)。 2. **坐标轴顺序问题** GDAL要求数据维度为`(纬度, 经度)`,而NC文件可能为`(经度, 纬度)`,需用`np.transpose()`调整。 3. **多时间层处理** 若NC文件包含多个时间层,需循环导出每一层: ```python for t in range(len(data.variables['time'])): output.GetRasterBand(1).WriteArray(temperature[t]) ``` 4. **地理变换参数校准** 若生成的TIF右下角经纬度偏移,检查`geotransform`的第二个参数(经度分辨率)和第六个参数(纬度分辨率符号)[^1]。 --- #### **参考文献** : GDAL地理变换参数说明: [https://gdal.org/tutorials/geotransforms_tut.html](https://gdal.org/tutorials/geotransforms_tut.html) [^2]: Python NCTIF代码示例: [CSDN博客](https://blog.csdn.net/xxx) [^3]: ArcGIS NetCDF工具文档: [ESRI Help](https://desktop.arcgis.com/) [^4]: GDAL多维度数据处理: [Python技术站](https://www.pythonjishu.com/) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值