Python读取nc文件转tif

36 篇文章 45 订阅

前言

使用Python解析.nc文件,并导出为WGS84地理坐标系的tif格式文件。
PS
Anaconda 安装netCDF4库,在prompt中输入:

conda install netCDF4

如果安装完成后,在spyder里导入模块时,仍报错找不到模块,则在控制台输入以下语句即可。

!pip install netCDF4

nc文件解析

这里以葵花8 L3 叶绿素产品数据为例。葵花8数据的简介与下载参照下方链接。
葵花8卫星数据简介与下载
查看一下nc数据的内容。

import netCDF4 as nc
data = r'Y:\folder\H08_20200601_0000_1D_ROC010_FLDK.02401_02401.nc'
nc_data_obj = nc.Dataset(data)
nc_data_obj

Out[4]: 
<class 'netCDF4._netCDF4.Dataset'>
root group (NETCDF4 data model, file format HDF5):
    title: Himawari-8 AHI equal latitude-longitude map data (1-day average)
    id: H08_20200601_0000_1D_ROC010_FLDK.02401_02401.nc
    date_created: 2020-06-02T00:31:47Z
    pixel_number: 2401
    line_number: 2401
    upper_left_latitude: 60.0
    upper_left_longitude: 80.0
    grid_interval: 0.05
    band_number: 8
    algorithm version: 
    Ancillary meteorological data: Unavailable
    Ancillary ozone data: TOVS
    BRDF correction: on (Morel and Maritorena 2001)
    dimensions(sizes): latitude(2401), longitude(2401), band(8), time(1), geometry(17)
    variables(dimensions): float32 latitude(latitude), float32 longitude(longitude), int32 band_id(band), float64 start_time(time), float64 end_time(time), float64 geometry_parameters(geometry), int16 AROT_02(latitude, longitude), int16 ARAE(latitude, longitude), int16 Rw_01(latitude, longitude), int16 Rw_02(latitude, longitude), int16 Rw_03(latitude, longitude), int16 chlor_a(latitude, longitude), int16 apg442(latitude, longitude), int16 bbp442(latitude, longitude), uint8 Sample_number(latitude, longitude)
    groups: 

我们可以看到整个nc文件的属性内容。其中最为关键的是:

    pixel_number: 2401
    line_number: 2401
    upper_left_latitude: 60.0
    upper_left_longitude: 80.0
    grid_interval: 0.05 #

因为以上参数可以为我们将文件写出tif时提供仿射变换参数。
nc库将变量读取为数组时候将自动定标。
http://unidata.github.io/netcdf4-python/netCDF4/index.html#netCDF4.Variable.set_auto_scale
在这里插入图片描述

完整代码

# -*- coding: utf-8 -*-
import numpy as np
import netCDF4 as nc
from osgeo import gdal,osr,ogr
import os
import glob
import datetime 

def NC_to_tiffs(data,Output_folder):
    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['longitude'][:]
    Lat = nc_data_obj.variables['latitude'][:]
    u_arr = np.asarray(nc_data_obj.variables['chlor_a'])  # 这里根据需求输入想要转换的波段名称
    #print('time_1=',time_1.min(),'time_max=',time_1.max())

    #影像的左上角和右下角坐标
    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)

    dt = nc_data_obj.id
    #创建.tif文件
    driver = gdal.GetDriverByName('GTiff')
    out_tif_name = Output_folder + '\\'+ 'chlor_' + dt + '.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[:, :]== -32768] = -99
        
    #数据写出
    out_tif.GetRasterBand(1).WriteArray(u_arr)
    out_tif.GetRasterBand(1).SetNoDataValue(-99)
    out_tif.FlushCache() # 将数据写入硬盘
    del out_tif # 注意必须关闭tif文件
    #return nc_data_obj.variables

def main():
    Input_folder = r'Y:\folder'
    Output_folder = r'Y:\folder2'
       
    # 读取所有nc数据
    data_list = glob.glob(Input_folder + '\*.nc')

    for i in range(len(data_list)):
        data = data_list[i]
        NC_to_tiffs(data,Output_folder)
        print (data + '-----转tif成功')
    
if __name__ == '__main__':
    main()

转换结果

arcgis打开nc文件
在这里插入图片描述
gdal读取转换为tif
在这里插入图片描述
nc库读写 仿射变换 优点可以自动读取增益偏置参数定标
在这里插入图片描述

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值