Matlab批量裁剪nc文件并合并

这里说的裁剪是指保留特定经纬度范围内的数据内容,不是指不规则形状裁剪,代码如下:

clc,clear
datadir = 'D:\MODEL\ncep1_daily\uwnd_19812022\'; %待裁剪数据所在的文件夹
fileList = dir([datadir,'*.nc']);
var_name = 'uwnd'; % 变量名
latRange = [-16, 16];  % 纬度范围
lonRange = [120, 290];  % 经度范围
outputFile = 'merged3.nc';
ncid_out = netcdf.create(outputFile, 'CLOBBER');
% 打开第一个文件以获取维度信息和变量结构
firstFile = [fileList(1).folder,'\',fileList(1).name];
ncid_in = netcdf.open(firstFile, 'NC_NOWRITE');

% 读取维度信息并复制到新的 netCDF 文件中
[numdims, numvars, numglobalatts, unlimdimid] = netcdf.inq(ncid_in);

% 获取经纬度变量的ID
lat_varid = netcdf.inqVarID(ncid_in, 'lat');  % 假设纬度变量名为 'lat'
lon_varid = netcdf.inqVarID(ncid_in, 'lon');  % 假设经度变量名为 'lon'

% 读取经纬度数据
lat_data = netcdf.getVar(ncid_in, lat_varid);
lon_data = netcdf.getVar(ncid_in, lon_varid);

% 找到符合经纬度范围的索引
lat_indices = find(lat_data >= latRange(1) & lat_data <= latRange(2));
lon_indices = find(lon_data >= lonRange(1) & lon_data <= lonRange(2));

% 复制所有维度到输出文件,正常写numdims-1就行,我这里是最后一个维度不需要
for i = 0:numdims-2
    [dimname, dimlen] = netcdf.inqDim(ncid_in, i);
    
    if strcmp(dimname, 'lat')
        netcdf.defDim(ncid_out, dimname, length(lat_indices));  % 保留纬度范围内的数据
    elseif strcmp(dimname, 'lon')
        netcdf.defDim(ncid_out, dimname, length(lon_indices));  % 保留经度范围内的数据
    elseif strcmp(dimname, 'time')
        netcdf.defDim(ncid_out, dimname, netcdf.getConstant('NC_UNLIMITED'));  % 时间维度是可扩展的
    else
        netcdf.defDim(ncid_out, dimname, dimlen);  % 其他维度保持不变
    end
end

% 复制所有变量的定义到输出文件,同上,-2是因为最后一个变量不需要
for i = 0:numvars-2
    [varname, xtype, dimids, numatts] = netcdf.inqVar(ncid_in, i);
    varid_out = netcdf.defVar(ncid_out, varname, xtype, dimids);
    
    % 复制变量的所有属性
    for j = 0:numatts-1
        attname = netcdf.inqAttName(ncid_in, i, j);
        attvalue = netcdf.getAtt(ncid_in, i, attname);
        netcdf.putAtt(ncid_out, varid_out, attname, attvalue);
    end
end

% 结束定义模式
netcdf.endDef(ncid_out);

% 关闭第一个文件
netcdf.close(ncid_in);

% 初始化时间维度的累加器
time_offset = 0;

% 循环遍历所有文件,沿时间维度合并变量数据
for k = 1:length(fileList)
    ncid_in = netcdf.open([fileList(k).folder,'\',fileList(k).name], 'NC_NOWRITE');
    
    % 获取当前文件的时间变量
    time_varid = netcdf.inqVarID(ncid_in, 'time');  % 假设时间变量为 'time'
    time_data = netcdf.getVar(ncid_in, time_varid);
    time_len = length(time_data);
    
    % 对每个变量读取数据并写入到新的 netCDF 文件
    for i = 0:numvars-2
        [varname, xtype, dimids, numatts] = netcdf.inqVar(ncid_in, i);
        varid_in = netcdf.inqVarID(ncid_in, varname);
        varid_out= netcdf.inqVarID(ncid_out, varname);
        disp(varname);
        % 特别处理纬度和经度变量
        if strcmp(varname, 'uwnd')
            disp('uwnd');
            data = netcdf.getVar(ncid_in, varid_in);
                data = data(lon_indices, lat_indices, :);  % 筛选经纬度范围
                netcdf.putVar(ncid_out, varid_out, [0, 0, time_offset], [length(lon_indices), length(lat_indices), time_len], data);
        end
        if strcmp(varname, 'lat')
            disp('lat');
            % 写入纬度数据 (一维),不需要提供时间维度的索引
            netcdf.putVar(ncid_out, varid_out, 0, length(lat_indices), lat_data(lat_indices));
        end
        if strcmp(varname, 'lon')
            disp('lon');
            % 写入经度数据 (一维),不需要提供时间维度的索引
            netcdf.putVar(ncid_out, varid_out, 0, length(lon_indices), lon_data(lon_indices));
        end
        if strcmp(varname, 'time')
            disp('time');
            % 时间维度:直接追加时间数据
            netcdf.putVar(ncid_out, varid_out, time_offset, time_len, time_data);
           
        end
  
        
    end
    
    % 更新时间累加器
    time_offset = time_offset + time_len;
    
    netcdf.close(ncid_in);
end

% 关闭合并后的文件
netcdf.close(ncid_out);

disp('所有文件已成功合并,并保留指定经纬度范围的数据到 merged.nc');

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值