气象数据读取(4)--- 优雅的交汇
1.前言
通过前两篇文章,我们完成了对风云和COSMIC的数据提取。我们实现了相应的功能,但是我们发现重复代码实在是太多了。并且在数据存储格式上,也有点小问题。这也太难受了吧。所以我们来尝试将冗余代码去掉,实现解耦,复用,改变相应存储格式。。。哈哈哈,说的这么牛逼,其实很简单啦
2.代码分析
在上两篇文章中,我们都是通过下面的方法获得了我们想要的数据
- 获取存放NC文件的文件路径
- 根据文件路径,获取每一个NC文件的全路径名,并存放到一个数组中
- 对上述数组里的每一个NC文件进行读取,获得Global Attributes和Variables。
- 提供相应的get方法,让外部方便使用我们的工具类
并且我们还知道,二者的数据结构很像。所以思考一下,我们在获取文件列表时,对文件类型进行判断,看它是风云数据,还是COSMIC数据。那如何判断?我在这里给大家提供一个思路,我们创建一个布尔类型的变量,用这个变量去标记我们读到的值是什么类型的。
private static boolean isFyFile;
- 如果是风云卫星,那么我们就将其标记为true
- 如果是COSMIC卫星,那么我们就返回false
是不是一下子豁然开朗了,哈哈哈
3. 优雅的交汇
好了,经过上面的分析,我们首先在utils里新建一个ReadAllNcDataUtils类,代码内容如下:
package roDataDemo.utils;
import ucar.ma2.Array;
import ucar.nc2.Attribute;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
//TODO:对文件夹里的文件类型进行过滤,因为这个工作其实挺烦的,特别是COSMIC数据文件含有较多的.符号,所以这里就不操作了。
/**
* 该工具类针对FY-3C卫星的GNOS掩星数据和COSMIC数据进行数据提取
* 提示:getVariablesLists(); getGlobalVariablesLists(),在这两个方法中,String vbName和int position
* 是我根据目前(2020-8-13)的数据结构给定的,后续有可能国家卫星气象中心提供的数据可能会不一样(但是一般不会变得),可以自行修改
* 提取数据包括:Global Attributes:掩星点坐标(经纬度),时间(年,月,日)
* Attributes:海拔,温度,压强
* 也可以根据自己需要提取其他相关参数,请自行配置
* <p>
* 重要提醒:!!! 在实例化该工具类后,必须先实现getNcDataList()方法,这样写是为了实例化后少写代码。有利有弊
* <p>
* 涉及到了文件读,应该要有关闭操作,请在使用后添加.close()进行关闭
*/
public class ReadAllNcDataUtils {
private static List<File> fileList;
private static NetcdfFile ncData;
private static boolean isFyFile;
public List<File> getFileList(String filepath) {
File file = new File(filepath);
File[] filesNames = file.listFiles();
return Arrays.asList(filesNames);
}
public List<NetcdfFile> getConditionNcDataList(List<String> filePathList) {
List<NetcdfFile> mNc = new ArrayList<NetcdfFile>();
isFyFile = filePathList.get(0).contains("FY");
for (String s : filePathList) {
try {
NetcdfFile open = NetcdfFile.open(s);
mNc.add(open);
} catch (IOException e) {
e.printStackTrace();
}
}
return mNc;
}
public List<NetcdfFile> getNcDataList(String filepath) {
List<NetcdfFile> mNc = new ArrayList<NetcdfFile>();
File file = new File(filepath);
File[] filesNames = file.listFiles();
assert filesNames != null;
fileList = Arrays.asList(filesNames);
//将读出的文件列表进行数据来源判断:①GNOS②COSMIC
isFyFile = fileList.get(0).toString().contains("FY");
for (File itemFile : fileList) {
try {
ncData = NetcdfFile.open(itemFile.getPath());
mNc.add(ncData);
} catch (IOException e) {
e.printStackTrace();
}
}
return mNc;
}
/**
* 获取掩星点纬度,
* GNOS是11
* COSMIC是24
*
* @return
*/
public List<String> getRoLat(List<NetcdfFile> nf) {
//随便起的名字,方便书写,想不到好名字,呜呜呜
List<String> sb = new ArrayList<String>();
return isFyFile ? getGlobalVariablesLists(11, sb, nf) : getGlobalVariablesLists(24, sb, nf);
//return getGlobalVariablesLists(11, mLat);
}
/**
* 获取掩星点经度
* GNOS是12
* COSMIC是
*
* @return
*/
public List<String> getRoLon(List<NetcdfFile> nf) {
List<String> sb = new ArrayList<String>();
return isFyFile ? getGlobalVariablesLists(12, sb, nf) : getGlobalVariablesLists(25, sb, nf);
}
/**
* 获取掩星事件发生年份
* <p>
* GNOS是0
* COSMIC是3
*
* @return
*/
public List<String> getRoYear(List<NetcdfFile> nf) {
List<String> sb = new ArrayList<String>();
return isFyFile ? getGlobalVariablesLists(0, sb, nf) : getGlobalVariablesLists(3, sb, nf);
}
/**
* 获取掩星事件发生月份
* GNOS是1
* COSMIC是4
*
* @return
*/
public List<String> getRoMonth(List<NetcdfFile> nf) {
List<String> sb = new ArrayList<String>();
return isFyFile ? getGlobalVariablesLists(1, sb, nf) : getGlobalVariablesLists(4, sb, nf);
}
/**
* 获取掩星事件发生天
* GNOS是2
* COSMIC是5
*
* @return
*/
public List<String> getRoDay(List<NetcdfFile> nf) {
List<String> sb = new ArrayList<String>();
return isFyFile ? getGlobalVariablesLists(2, sb, nf) : getGlobalVariablesLists(5, sb, nf);
}
/**
* 获取掩星事件发生小时
* GNOS是3
* COSMIC是6
*
* @return
*/
public List<String> getRoHour(List<NetcdfFile> nf) {
List<String> sb = new ArrayList<String>();
return isFyFile ? getGlobalVariablesLists(3, sb, nf) : getGlobalVariablesLists(6, sb, nf);
}
/**
* 获取掩星事件发生分钟
* GNOS是4
* COSMIC是7
*
* @return
*/
public List<String> getRoMinute(List<NetcdfFile> nf) {
List<String> sb = new ArrayList<String>();
return isFyFile ? getGlobalVariablesLists(4, sb, nf) : getGlobalVariablesLists(7, sb, nf);
}
/**
* 获取掩星事件发生秒数
* GNOS是5
* COSMIC是8
*
* @return
*/
public List<String> getRoSecond(List<NetcdfFile> nf) {
List<String> sb = new ArrayList<String>();
return isFyFile ? getGlobalVariablesLists(5, sb, nf) : getGlobalVariablesLists(8, sb, nf);
}
/**
* 获得海拔
* GNOS是 MSL_alt
* COSMIC是MSL_alt
*
* @param
* @return
*/
public List<Array> getAltList(List<NetcdfFile> nf) {
List<Array> mAltsList = new ArrayList<Array>();
return getVariablesLists("MSL_alt", mAltsList, nf);
}
/**
* 获得温度
* GNOS是 Temp
* COSMIC是Temp
*
* @param
* @return
*/
public List<Array> getTempList(List<NetcdfFile> nf) {
List<Array> mTempsList = new ArrayList<Array>();
return getVariablesLists("Temp", mTempsList, nf);
}
/**
* 获得压强
* GNOS是 Pres
* COSMIC是Pres
*
* @param
* @return
*/
public List<Array> getPressList(List<NetcdfFile> nf) {
List<Array> mPressList = new ArrayList<Array>();
return getVariablesLists("Pres", mPressList, nf);
}
private static List<String> getGlobalVariablesLists(int position, List<String> mGlobalVb, List<NetcdfFile> nf) {
for (NetcdfFile netcdfFile : nf) {
List<Attribute> globalAttributes = netcdfFile.getGlobalAttributes();
Array values = globalAttributes.get(position).getValues();
String s = values.toString();
mGlobalVb.add(s);
}
return mGlobalVb;
}
private static List<Array> getVariablesLists(String vbName,
List<Array> mVrsList, List<NetcdfFile> nf) {
for (NetcdfFile netcdfFile : nf) {
Array read = null;
Variable sb = netcdfFile.findVariable(vbName);
try {
read = sb.read();
} catch (IOException e) {
e.printStackTrace();
}
mVrsList.add(read);
}
return mVrsList;
}
}
我们来简单分析一下代码:
我们在别的类中使用该工具类时,首先我们要实例化出来一个该工具类
ReadAllNcDataUtils rd = new ReadAllNcDataUtils();
此时我们就有了一个ReadAllNcDataUtils类型的实例 rd
假如此时我们想获得"D:\新建文件夹"里存放的所有掩星文件的掩星点坐标的纬度值。那么我们就要使用getRolat方法
可以发现,此时getRolat方法需要有一个LIstanbul
所以我们在执行getRolat方法前,要先执行getNcDataList方法,此时代码为:
ReadAllNcDataUtils rd = new ReadAllNcDataUtils();
List<NetcdfFile> ncDataList = rd.getNcDataList("D:\\新建文件夹");
List<String> roLat = rd.getRoLat(ncDataList);
这时,我们就把文件中所有的掩星点纬度值存入到了数组roLat里面。是不是很神奇,哈哈哈。现在你是不是也明白了工具类的重要性。它可以极大的提升我们的工作效率,并可以让我们使用很少的代码,完成本来很复杂的事情。
其实,在日常的开发工作中,我们可以将经常用到的代码进行整理,提供相应的get,set以及构造方法。这也是一种好习惯。
4.数据的时空特征匹配
我们把数据读出来了,但是,我们读出来的数据,都是离散的,并没有明确的时空特征,那我们要这数据有啥用?所以,我们必须要写一个能匹配时空特征的工具类,下个文章,我们分享一个时空特征匹配工具类。
- [x] 我们的征途是星辰大海。我就是我,我就是天!
- [x] 疾风亦有龟途对本文享有版权,转载请标明原文链接,禁止复制!
- [x] 欢迎访问我的个人博客网站---->夙夜星辰叹
- [x] 欢迎关注我的微信公众号:
版权属于: 依依东望