从 NetCDF 4.5 Grib2Record 中提取天气预报数据
Extract weather forecast data from NetCDF 4.5 Grib2Record
更新:更改了这个问题以更好地反映我目前的理解。
我有一个 NetCDF 版本 4.5 Grib2Record 对象。给定一个 (x,y) 网格点和一个变量名,我想按预测时间从对象中提取该变量的所有预测数据(如果记录包含该变量的预测)。由于写入磁盘索引文件的默认行为,我不想使用更高级别的 NetCDFFile 接口。
我尝试查看较低级别的代码(Grib2Rectilyser、Grib2Customizer 等),但代码太密集,我正在寻求帮助以了解从哪里开始。
如果有任何关于如何获取 Grib2Record 和 1. 检查特定预测变量是否包含在其中,以及 2. 如果包含,则按预测有效时间提取预测数据的指示,我将不胜感激给定 x-y 网格点和 z 级别。
我曾使用 grib2 文件进行风力预测,这就是我如何获取记录以及如何处理它以获得风力(V U 分量)
Grib2Input input = new Grib2Input(getRandomAccessFile());
if (!input.scan(false, false)) {
logger.error("Failed to successfully scan grib file");
return;
}
Grib2Data data = new Grib2Data(getRandomAccessFile());
List<Grib2Record> records = input.getRecords();
for (Grib2Record record : records) {
Grib2IndicatorSection is = record.getIs();
Grib2IdentificationSection id = record.getId();
Grib2Pds pdsv = record.getPDS().getPdsVars();
Grib2GDSVariables gdsv = record.getGDS().getGdsVars();
long time = id.getRefTime() + (record.getPDS().getForecastTime() * 3600000);
logger.debug("Record description at " + pdsv.getReferenceDate() + " forecast "
+ new Date(time) + ": " + ParameterTable.getParameterName(is.getDiscipline(), pdsv.getParameterCategory(), pdsv.getParameterNumber()));
float[] values = data.getData(record.getGdsOffset(), record.getPdsOffset(), 0);
if ((is.getDiscipline() == 0) && (pdsv.getParameterCategory() == 2) && (pdsv.getParameterNumber() == 2)) {
// U-component_of_wind
int c = 0;
for (double lat = gdsv.getLa1(); lat >= gdsv.getLa2(); lat = lat - gdsv.getDy()) {
for (double lon = gdsv.getLo1(); lon <= gdsv.getLo2(); lon = lon + gdsv.getDx()) {
logger.debug(lat + "\t" + lon + "\t" +
values[c]);
c++;
}
}
} else if ((is.getDiscipline() == 0) && (pdsv.getParameterCategory() == 2) && (pdsv.getParameterNumber() == 3)) {
// V-component_of_wind
int c = 0;
for (double lat = gdsv.getLa1(); lat >= gdsv.getLa2(); lat = lat - gdsv.getDy()) {
for (double lon = gdsv.getLo1(); lon <= gdsv.getLo2(); lon = lon + gdsv.getDx()) {
logger.debug(lat + "\t" + lon + "\t" +
values[c]);
c++;
}
}
}
}
private RandomAccessFile getRandomAccessFile() {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(path, "r");
raf.order(RandomAccessFile.BIG_ENDIAN);
} catch (IOException e) {
logger.error("Error opening file " + path, e);
}
return raf;
}
更新:更改了这个问题以更好地反映我目前的理解。
我有一个 NetCDF 版本 4.5 Grib2Record 对象。给定一个 (x,y) 网格点和一个变量名,我想按预测时间从对象中提取该变量的所有预测数据(如果记录包含该变量的预测)。由于写入磁盘索引文件的默认行为,我不想使用更高级别的 NetCDFFile 接口。
我尝试查看较低级别的代码(Grib2Rectilyser、Grib2Customizer 等),但代码太密集,我正在寻求帮助以了解从哪里开始。
如果有任何关于如何获取 Grib2Record 和 1. 检查特定预测变量是否包含在其中,以及 2. 如果包含,则按预测有效时间提取预测数据的指示,我将不胜感激给定 x-y 网格点和 z 级别。
我曾使用 grib2 文件进行风力预测,这就是我如何获取记录以及如何处理它以获得风力(V U 分量)
Grib2Input input = new Grib2Input(getRandomAccessFile());
if (!input.scan(false, false)) {
logger.error("Failed to successfully scan grib file");
return;
}
Grib2Data data = new Grib2Data(getRandomAccessFile());
List<Grib2Record> records = input.getRecords();
for (Grib2Record record : records) {
Grib2IndicatorSection is = record.getIs();
Grib2IdentificationSection id = record.getId();
Grib2Pds pdsv = record.getPDS().getPdsVars();
Grib2GDSVariables gdsv = record.getGDS().getGdsVars();
long time = id.getRefTime() + (record.getPDS().getForecastTime() * 3600000);
logger.debug("Record description at " + pdsv.getReferenceDate() + " forecast "
+ new Date(time) + ": " + ParameterTable.getParameterName(is.getDiscipline(), pdsv.getParameterCategory(), pdsv.getParameterNumber()));
float[] values = data.getData(record.getGdsOffset(), record.getPdsOffset(), 0);
if ((is.getDiscipline() == 0) && (pdsv.getParameterCategory() == 2) && (pdsv.getParameterNumber() == 2)) {
// U-component_of_wind
int c = 0;
for (double lat = gdsv.getLa1(); lat >= gdsv.getLa2(); lat = lat - gdsv.getDy()) {
for (double lon = gdsv.getLo1(); lon <= gdsv.getLo2(); lon = lon + gdsv.getDx()) {
logger.debug(lat + "\t" + lon + "\t" +
values[c]);
c++;
}
}
} else if ((is.getDiscipline() == 0) && (pdsv.getParameterCategory() == 2) && (pdsv.getParameterNumber() == 3)) {
// V-component_of_wind
int c = 0;
for (double lat = gdsv.getLa1(); lat >= gdsv.getLa2(); lat = lat - gdsv.getDy()) {
for (double lon = gdsv.getLo1(); lon <= gdsv.getLo2(); lon = lon + gdsv.getDx()) {
logger.debug(lat + "\t" + lon + "\t" +
values[c]);
c++;
}
}
}
}
private RandomAccessFile getRandomAccessFile() {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(path, "r");
raf.order(RandomAccessFile.BIG_ENDIAN);
} catch (IOException e) {
logger.error("Error opening file " + path, e);
}
return raf;
}