这里说的裁剪是指保留特定经纬度范围内的数据内容,不是指不规则形状裁剪,代码如下:
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');