package ts.test.analysis;
import com.opencsv.CSVWriter;
import ucar.ma2.Array;
import ucar.ma2.Index;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;
public class test_3D {
public static void main(String[] args) throws IOException, InvalidRangeException {
// NC文件路径
String ncPath = "D:\\sfcf003.nc";
// 建立nc文件对象
NetcdfFile ncFile = NetcdfFile.open(ncPath);
// 获取所有的变量,用于获取他们的类型和变量名
List<Variable> variables = ncFile.getVariables();
// 由于变量的前五项是时间、经度、纬度、grid_xt、grid_yt,都不是二维数组,故要用一维数组的方式进行导出
for (int i = 0; i < 5; i++) {
// 得到该索性对应的变量名以形成导出的CSV文件名称
String variableName = variables.get(i).getName();
String outPath = "D:\\test0\\" + variableName + ".csv";
// 根据时间、经纬度、grid_xt/yt的性质,将其按照相应方式写入CSV
// 维度变量在nc文件中的顺序为grid_xt、lon、grid_yt、lat、time
switch (i){
case 1:
writeLonCSV(ncFile, outPath, variables.get(i));
break;
case 3:
writeLatCSV(ncFile, outPath, variables.get(i));
break;
default:
writeDimensionCSV(outPath, variables.get(i));
break;
}
}
// 由于变量的前五项是时间、经度、维度、grid_xt、grid_yt,都不是三维数组,不能按照提取其他变量的方式进行提取,故此处从第六个变量开始写入CSV
for (int i = 5; i < variables.size(); i++) {
// 得到该索性对应的变量名以形成导出的CSV文件名称
String variableName = variables.get(i).getName();
String outPath = "F:\\test1\\" + variableName + ".csv";
// 将该变量写入CSV
writeVariableCSV(outPath, variables.get(i));
}
// 关闭nc文件
ncFile.close();
}
// 读取时间、grid_xt、grid_yt的值,并将其存放在一维数组中
public static void writeDimensionCSV(String outPath, Variable variable) throws IOException, InvalidRangeException {
// 创建CSV
FileOutputStream fileOutputStream = new FileOutputStream(outPath);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
CSVWriter csvWriter = new CSVWriter(outputStreamWriter
, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END);
// 读取维度变量,并储存到String数组中
Array value = variable.read();
String[] strings = new String[(int) value.getSize()];
for (int i = 0; i < value.getSize(); i++) {
Double temp = value.getDouble(i);
strings[i] = temp.toString();
}
csvWriter.writeNext(strings);
// 刷新、关闭
csvWriter.flush();
csvWriter.close();
outputStreamWriter.close();
fileOutputStream.close();
}
// 读取经度的值,并将其存放在一维数组中
public static void writeLonCSV(NetcdfFile ncFile, String outPath, Variable variable) throws IOException, InvalidRangeException {
// 创建CSV
FileOutputStream fileOutputStream = new FileOutputStream(outPath);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
CSVWriter csvWriter = new CSVWriter(outputStreamWriter
, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END);
// 读取经度,用grid_xt的大小来控制每行数据量,并将读取到的数据储存到String数组中写入CSV
Array value = variable.read();
long num = ncFile.findVariable("grid_xt").getSize();
String[] strings = new String[(int) num];
for (int i = 0; i < variable.getSize(); i++) {
Double temp = value.getDouble(i);
int index = (int) (i % num);
strings[index] = temp.toString();
// 整合后写入CSV
if((i + 1) % num == 0)
csvWriter.writeNext(strings);
}
// 刷新、关闭
csvWriter.flush();
csvWriter.close();
outputStreamWriter.close();
fileOutputStream.close();
}
// 读取纬度的值,并将其存放在一维数组中
public static void writeLatCSV(NetcdfFile ncFile, String outPath, Variable variable) throws IOException, InvalidRangeException {
// 创建CSV
FileOutputStream fileOutputStream = new FileOutputStream(outPath);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
CSVWriter csvWriter = new CSVWriter(outputStreamWriter
, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END);
// 读取纬度,用grid_xt的大小来控制每行数据量,并将读取到的数据储存到String数组中写入CSV
Array value = variable.read();
long num = ncFile.findVariable("grid_xt").getSize();
String[] strings = new String[(int) num];
for (int i = 0; i < variable.getSize(); i++) {
Double temp = value.getDouble(i);
int index = (int) (i % num);
strings[index] = temp.toString();
// 整合后写入CSV
if((i + 1) % num == 0)
csvWriter.writeNext(strings);
}
// 刷新、关闭
csvWriter.flush();
csvWriter.close();
outputStreamWriter.close();
fileOutputStream.close();
}
// 读取变量在任一时间、经度、纬度下的值,并将其存放在二维数组中
public static void writeVariableCSV(String outPath, Variable v) throws IOException, InvalidRangeException {
// 读取nc数据到数组
Array data = v.read();
// 获取参数和索引,其中shape的前三个参数分别是时间、纬度、经度
int[] shape = data.getShape();
Index index = data.getIndex();
// 创建CSV
FileOutputStream fileOutputStream = new FileOutputStream(outPath);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
CSVWriter csvWriter = new CSVWriter(outputStreamWriter
, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END);
// 将三维数组降维,并用String数组提取数据,将其按行导出到CSV文件
// 按时间
for (int i = 0; i < shape[0]; i++) {
// 按维度
for (int j = 0; j < shape[1]; j++) {
String[] strings = new String[shape[2]];
// 按经度
for (int k = 0; k < shape[2]; k++) {
// 按照对应索引获取数据并转换为string类型添加到数组中
Float dval = data.getFloat(index.set(i, j, k));
strings[k] = dval.toString();
}
csvWriter.writeNext(strings);
}
}
// 刷新、关闭
csvWriter.flush();
csvWriter.close();
outputStreamWriter.close();
fileOutput
评论0