# -*- coding: utf-8 -*- import argparse import os from osgeo import gdal, osr import numpy as np import netCDF4 as nc from datetime import datetime, timezone import time def nc2ENVIBin(nc_file_path,output_envi_path,utctime): # Input parameters (replace these with your actual values) time_index = -1 # Example: 0 for the first time step; adjust if needed # Step 1: Read the NetCDF file using netCDF4 ds=None filename = "数据/测试文件.nc" with open(nc_file_path, 'rb') as f: ds = nc.Dataset('in_memory', mode='r', memory=f.read()) print(f"Available variables: {list(ds.variables.keys())}") # Optional: Print variables for verification valid_time_list=ds.variables["valid_time"][:] for timeID in range(0,len(valid_time_list)): # print(valid_time_list[timeID],utctime) if valid_time_list[timeID] == utctime: time_index = timeID break if time_index == -1: return -1 else: print(f"time_index={time_index}") # Extract the variable data (assuming 3D: time, lat, lon) data_U10 = ds.variables["u10"][time_index, :, :].filled(np.nan) # Handle masked values as NaN data_V10 = ds.variables["v10"][time_index, :, :].filled(np.nan) # Handle masked values as NaN # Extract lat and lon (adjust variable names if your file uses different ones, e.g., 'latitude', 'longitude') lat = ds.variables['latitude'][:] lon = ds.variables['longitude'][:] # Calculate geotransform parameters x_res = (lon[-1] - lon[0]) / (len(lon) - 1) y_res = (lat[0] - lat[-1]) / (len(lat) - 1) # Note: lat often decreases north to south top_left_x = lon[0] - x_res / 2 top_left_y = lat[0] + y_res / 2 geotransform = (top_left_x, x_res, 0, top_left_y, 0, -y_res) # Negative y_res for north-up # Step 2: Create ENVI file using GDAL driver = gdal.GetDriverByName('ENVI') envi_ds = driver.Create( output_envi_path, data_U10.shape[1], # Width (lon) data_U10.shape[0], # Height (lat) 2, # Single band gdal.GDT_Float32 # Assuming float data; adjust to gdal.GDT_Float64 if needed ) # Set geotransform and projection (EPSG:4326 for WGS84 lat/lon) envi_ds.SetGeoTransform(geotransform) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) envi_ds.SetProjection(srs.ExportToWkt()) # Write the data to the band envi_band = envi_ds.GetRasterBand(1) envi_band.SetNoDataValue(np.nan) # Set NaN as no-data value (optional) envi_band.WriteArray(data_U10) envi_band = envi_ds.GetRasterBand(2) envi_band.SetNoDataValue(np.nan) # Set NaN as no-data value (optional) envi_band.WriteArray(data_V10) # Add ENVI-specific metadata to the header (optional, but recommended) envi_ds.SetMetadataItem('wavelength units', 'None', 'ENVI') # Example; customize as needed envi_ds.SetMetadataItem('data type', '4', 'ENVI') # 4 = float32; matches GDT_Float32 # Clean up envi_ds.FlushCache() envi_ds = None ds.close() print(f"Conversion complete: {output_envi_path} (with .hdr)") def getParams(): parser = argparse.ArgumentParser() parser.add_argument('-i','--infile',default=r'D:\风场\20250807_SAR_EC_2024年\ERA5风场\total_precipitation202410.nc', help='输入风场文件路径') parser.add_argument('-o', '--outfile',default=r'D:\风场\20250807_SAR_EC_2024年\ERA5风场\total_precipitation202410.bin', help='输出Bin文件路径') parser.add_argument('-t', '--time',type=int, default=2024100108,help='yyyymmddhh') args = parser.parse_args() return args def timestr2utc(timeint): timestr = str(timeint) # 解析字符串为datetime对象(默认无时区信息) dt = datetime.strptime(timestr, "%Y%m%d%H") # 显式标记为UTC时间(两种等效方式) dt_utc = dt.replace(tzinfo=timezone.utc) # 方式1:使用标准库 # 或使用pytz库:dt_utc = pytz.utc.localize(dt) timestamp = time.mktime(dt_utc.timetuple()) utc_timestamp = int(timestamp) # 当前UTC时间戳(秒级) print("UTC时间:", dt_utc) print("ISO格式:", dt_utc.isoformat()) # 输出:2024-08-01T02:00:00+00:00 print("UTC时间戳:", utc_timestamp) # 输出:2024-08-01T02:00:00+00:00 return utc_timestamp if __name__ == '__main__': parser = getParams() inNcFilePath=parser.infile outbinpath=parser.outfile searchTime=parser.time print('infile=',inNcFilePath) print('outfile=',outbinpath) time_utc=timestr2utc(searchTime) nc2ENVIBin(inNcFilePath,outbinpath,time_utc)