CIMISS数据获取流程

时间:2022-07-13 16:52:36

1、规整时间。将时间进行调整,根据需要,设定为北京时间,以获取天的数据为例,时间格式为yyyyMMdd000000,这里获取日数据,时间统一往后推一天,例如今天获取的数据是CIMISS昨天的数据。获取小时,获取分钟,通过代码的编写,可相应的调整时间。

以天为例,这里主要就是利用java现成的工具类,实现时间的转换。

log.info("DAY=====日值资料=======CIMISS DAY START");
Calendar cal = getCalendar(11, -24, false);
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd000000");
String time = format.format(cal.getTime());
log.info(" DAY time:" + time + "===========日资料时间=====================");

第二行中的参数,11代表小时,-24代表延迟 24小时,false代表北京时间。getCalendar的具体实现如下:

/**
* 获取时间,当Job.date未设置时,则使用世界时间
* @param type {@link int} 延迟类型 ,主要类型皆为{@link Calendar}的常量 11代表小时,12代表分钟
* @param delay {@link int} 延迟时间
* @param timezome {@link Boolean} true世界时,false北京时
* @return {@link Calendar} 返回值 日历
*/

public Calendar getCalendar(int type, int delay,boolean timezome) { //11, -24, false
SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMddHHmm");
Calendar c = Calendar.getInstance();
if(timezome){
c.add(Calendar.HOUR_OF_DAY, -8);//UTC时间
}
if (date == null || date.equals("")) {
c.add(type, delay);
return c;
} else {
Date date = new Date();
try {
date = dateFormat.parse(this.date);
} catch (ParseException e) {
e.printStackTrace();
}
c.setTime(date);
}
return c;
}

通过以上处理,即可得到一个我们需要的时间,从而通过该时间获得CIMISS里面的数据。

2、从CIMISS里面获取相应的数据。分为时间点的数据获取和时间段的数据获取两种。以获取天数据为例,执行这行代码,List awsDayList = getAwsDayData(time, isopen);time指的是两种不同的时间;isopen的值有两种,分别为false和true,当为false,指的是时间点的数据获取;为true,指的是时间段的数据获取。所有获得的数据是以awsDayList集合的方式返回。

以获取天数据为例,通过调用getAwsDayData(String time, boolean isopen)获取天数据这个方法,time这里有两种,分别为时间点喝时间段timeRange。
isopen这里有两种值,分别为false和true,当为false,则是决定了time为时间点,对应着后面的自动入库流程;当为true,则决定了time为时间段,对应着后面的补录入库的流程。
当执行时间点的数据的获取的时候,调用的CIMISS的接口为getSurfEleInRegionByTime,当执行时间段的数据的获取的时候,调用的CIMISS的接口为getSurfEleInRegionByTimeRange。

在了解了这些参数的含义之后,开始执行数据的获取,调用CIMISS所提供的方法,根据该方法传递相应的参数, callAPI_to_array2D(userId, pwd, interfaceId, params, retArray2D),前三个参数分别为账户名,密码,调用的CIMISS的接口,params指的是我们从CIMISS所获得的要素名elements ,如检索站号,北京时间,经度,纬度,雨量等等。这里需要全部获取,即CIMISS有什么,我们就需要拿到什么。最后一个参数代表着一个实体类对象,传进去是个空的实体类,我们客户端调用这个callAPI_to_array2D方法,只有当返回值是个0的时候, retArray2D这个空的实体类对象才会拥有我们想要获得的数据,即那些要素。通过retArray2D.data这种方式即可遍历出里面的所有数据,从而给集合awsDayList存上数据,再为我们下面的入库做准备。

log.info("DAY=====日值资料=======CIMISS DAY START");
Calendar cal = getCalendar(11, -24, false);
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd000000");
String time = format.format(cal.getTime());
log.info(" DAY time:" + time + "===========日资料时间=====================");
List<AwsDay> awsDayList = getAwsDayData(time, false); //按照时间点来获得数据,true是时间段

log.info("DAY=====日值资料=======开始调用insertdb.....");

getAwsDayData实现如下:

    public List<AwsDay> getAwsDayData(String time, boolean isopen) { 

List<AwsDay> paraList = new ArrayList<AwsDay>();
/* 1. 定义client对象 */
DataQueryClient client = new DataQueryClient();

/* 2. 调用方法的参数定义,并赋值 */
/* 2.1 用户名&密码 */
String userId = QuartzUtil.getProperty("cimiss.user");
String pwd = QuartzUtil.getProperty("cimiss.password");
String interfaceId = "";
if (isopen){
/* 2.2 接口ID */
interfaceId = "getSurfEleInRegionByTimeRange";
}else{
/* 2.2 接口ID */
interfaceId = "getSurfEleInRegionByTime";
}
/* 2.3 接口参数,多个参数间无顺序 */
HashMap<String, String> params = new HashMap<String, String>();
// 必选参数
params.put("dataCode", "SURF_CHN_MUL_DAY"); // 资料代码,中国地面逐天资料
// params.put("elements", "Station_ID_C, Datetime, Lat, Lon, PRE");
params.put("elements",//要素代码
"Station_Name,Province,City,Cnty,Town,Datetime,REP_CORR_ID,Station_Id_C,Station_Id_d,"
+ "Lat,Lon,Alti,PRS_Sensor_Alti,Station_levl,Admin_Code_CHN,Year,Mon,Day,PRS_Avg,PRS_Max,"
+ "PRS_Max_OTime,PRS_Min,PRS_Min_OTime,PRS_Sea_Avg,TEM_Avg,TEM_Max,TEM_Max_OTime,TEM_Min,"
+ "TEM_Min_OTime,VAP_Avg,RHU_Avg,RHU_Min,RHU_Min_OTIME,CLO_Cov_Avg,CLO_Cov_Low_Avg,VIS_Min,"
+ "VIS_Min_OTime,PRE_Max_1h,PRE_Time_2008,PRE_Time_0820,PRE_Time_2020,PRE_Time_0808,EVP,EVP_Big,"
+ "Snow_Depth,Snow_PRS,EICE,EICED_NS,EICET_NS,EICEW_NS,EICED_WE,EICET_WE,"
+ "EICEW_WE,TEM,WIN_D,WIN_S,WIN_D_Avg_2mi_C,WIN_S_2mi_Avg,WIN_S_10mi_Avg,WIN_D_S_Max,WIN_S_Max,"
+ "WIN_S_Max_OTime,WIN_D_INST_Max,WIN_S_Inst_Max,WIN_S_INST_Max_OTime,GST_Avg,GST_Max,GST_Max_Otime,"
+ "GST_Min,GST_Min_OTime,GST_Avg_5cm,GST_Avg_10cm,GST_Avg_15cm,GST_Avg_20cm,GST_Avg_40cm,"
+ "GST_Avg_80cm,GST_Avg_160cm,GST_Avg_320cm,FRS_1st_Top,FRS_1st_Bot,FRS_2nd_Top,FRS_2nd_Bot,SSH,"
+ "Sunrist_Time,Sunset_Time,LGST_Avg,LGST_Max,LGST_Max_OTime,LGST_Min,LGST_Min_OTime,SCO,Rain,"
+ "PRE_OTime,Snow,Snow_OTime,Hail,HAIL_OTime,Fog,Fog_OTime,Mist,Dew,Frost,Glaze,GLAZE_OTime,SoRi,"
+ "SoRi_OTime,DrSnow,DrSnow_OTime,SnowSt,SnowSt_OTime,Tord,Tord_OTime,GSS,ICE,SaSt,SaSt_OTime,FlSa,"
+ "FlSa_OTime,FlDu,FlDu_OTime,Smoke,Haze,DuWhr,IcePri,Thund,THUND_OTime,Lit,Aur,AUR_OTime,"
+ "GaWIN,GaWIN_OTime,Squa,SQUA_OTime,WEP_Sumary,WEP_Record");
// 检索站号,北京时间,经度,纬度,雨量.........
if (isopen){
params.put("timeRange", time); // 检索时间段

}else{
params.put("times", time); // 检索时间
}
log.info("interfaceId : " + interfaceId + " time: " + time);
params.put("adminCodes", QuartzUtil.getProperty("cimiss.areaCode")); // 国内行政编码

/* 2.4 返回对象 */
RetArray2D retArray2D = new RetArray2D();


/* 3. 调用接口 */
try {
// 初始化接口服务连接资源
client.initResources();
// 调用接口
int rst = client.callAPI_to_array2D(userId, pwd, interfaceId, params, retArray2D); //返回一个retArray2D的对象,里面有值

log.info("DAY=====日值资料=======连接CIMISS: ----------------------" + rst);

// 输出结果
if (rst == 0) { // 正常返回


for (int iRow = 0; iRow < retArray2D.data.length; iRow++) {
AwsDay awsDay = new AwsDay();
int index = 0;

awsDay.setSTATION_NAME(retArray2D.data[iRow][index++]);
awsDay.setPROVINCE(retArray2D.data[iRow][index++]);
awsDay.setCITY(retArray2D.data[iRow][index++]);
awsDay.setCNTY(retArray2D.data[iRow][index++]);
awsDay.setTOWN(retArray2D.data[iRow][index++]);
awsDay.setDATETIME(retArray2D.data[iRow][index++]);
awsDay.setREP_CORR_ID(retArray2D.data[iRow][index++]);
awsDay.setSTATION_ID_C(retArray2D.data[iRow][index++]);
awsDay.setSTATION_ID_D(retArray2D.data[iRow][index++]);
awsDay.setLAT(retArray2D.data[iRow][index++]);
awsDay.setLON(retArray2D.data[iRow][index++]);
awsDay.setALTI(retArray2D.data[iRow][index++]);
awsDay.setPRS_SENSOR_ALTI(retArray2D.data[iRow][index++]);
awsDay.setSTATION_LEVL(retArray2D.data[iRow][index++]);
awsDay.setADMIN_CODE_CHN(retArray2D.data[iRow][index++]);
awsDay.setYEAR(retArray2D.data[iRow][index++]);
awsDay.setMON(retArray2D.data[iRow][index++]);
awsDay.setDAY(retArray2D.data[iRow][index++]);
awsDay.setPRS_AVG(retArray2D.data[iRow][index++]);
awsDay.setPRS_MAX(retArray2D.data[iRow][index++]);
awsDay.setPRS_MAX_OTIME(retArray2D.data[iRow][index++]);
awsDay.setPRS_MIN(retArray2D.data[iRow][index++]);
awsDay.setPRS_MIN_OTIME(retArray2D.data[iRow][index++]);
awsDay.setPRS_SEA_AVG(retArray2D.data[iRow][index++]);
awsDay.setTEM_AVG(retArray2D.data[iRow][index++]);
awsDay.setTEM_MAX(retArray2D.data[iRow][index++]);
awsDay.setTEM_MAX_OTIME(retArray2D.data[iRow][index++]);
awsDay.setTEM_MIN(retArray2D.data[iRow][index++]);
awsDay.setTEM_MIN_OTIME(retArray2D.data[iRow][index++]);
awsDay.setVAP_AVG(retArray2D.data[iRow][index++]);
awsDay.setRHU_AVG(retArray2D.data[iRow][index++]);
awsDay.setRHU_MIN(retArray2D.data[iRow][index++]);
awsDay.setRHU_MIN_OTIME(retArray2D.data[iRow][index++]);
awsDay.setCLO_COV_AVG(retArray2D.data[iRow][index++]);
awsDay.setCLO_COV_LOW_AVG(retArray2D.data[iRow][index++]);
awsDay.setVIS_MIN(retArray2D.data[iRow][index++]);
awsDay.setVIS_MIN_OTIME(retArray2D.data[iRow][index++]);
awsDay.setPRE_MAX_1H(retArray2D.data[iRow][index++]);
awsDay.setPRE_TIME_2008(retArray2D.data[iRow][index++]);
awsDay.setPRE_TIME_0820(retArray2D.data[iRow][index++]);
awsDay.setPRE_TIME_2020(retArray2D.data[iRow][index++]);
awsDay.setPRE_TIME_0808(retArray2D.data[iRow][index++]);
awsDay.setEVP(retArray2D.data[iRow][index++]);
awsDay.setEVP_BIG(retArray2D.data[iRow][index++]);
awsDay.setSNOW_DEPTH(retArray2D.data[iRow][index++]);
awsDay.setSNOW_PRS(retArray2D.data[iRow][index++]);
awsDay.setEICE(retArray2D.data[iRow][index++]);
awsDay.setEICED_NS(retArray2D.data[iRow][index++]);
awsDay.setEICET_NS(retArray2D.data[iRow][index++]);
awsDay.setEICEW_NS(retArray2D.data[iRow][index++]);
awsDay.setEICED_WE(retArray2D.data[iRow][index++]);
awsDay.setEICET_WE(retArray2D.data[iRow][index++]);
awsDay.setEICEW_WE(retArray2D.data[iRow][index++]);
awsDay.setTEM(retArray2D.data[iRow][index++]);
awsDay.setWIN_D(retArray2D.data[iRow][index++]);
awsDay.setWIN_S(retArray2D.data[iRow][index++]);
awsDay.setWIN_D_AVG_2MI_C(retArray2D.data[iRow][index++]);
awsDay.setWIN_S_2MI_AVG(retArray2D.data[iRow][index++]);
awsDay.setWIN_S_10MI_AVG(retArray2D.data[iRow][index++]);
awsDay.setWIN_D_S_MAX(retArray2D.data[iRow][index++]);
awsDay.setWIN_S_MAX(retArray2D.data[iRow][index++]);
awsDay.setWIN_S_MAX_OTIME(retArray2D.data[iRow][index++]);
awsDay.setWIN_D_INST_MAX(retArray2D.data[iRow][index++]);
awsDay.setWIN_S_INST_MAX(retArray2D.data[iRow][index++]);
awsDay.setWIN_S_INST_MAX_OTIME(retArray2D.data[iRow][index++]);
awsDay.setGST_AVG(retArray2D.data[iRow][index++]);
awsDay.setGST_MAX(retArray2D.data[iRow][index++]);
awsDay.setGST_MAX_OTIME(retArray2D.data[iRow][index++]);
awsDay.setGST_MIN(retArray2D.data[iRow][index++]);
awsDay.setGST_MIN_OTIME(retArray2D.data[iRow][index++]);
awsDay.setGST_AVG_5CM(retArray2D.data[iRow][index++]);
awsDay.setGST_AVG_10CM(retArray2D.data[iRow][index++]);
awsDay.setGST_AVG_15CM(retArray2D.data[iRow][index++]);
awsDay.setGST_AVG_20CM(retArray2D.data[iRow][index++]);
awsDay.setGST_AVG_40CM(retArray2D.data[iRow][index++]);
awsDay.setGST_AVG_80CM(retArray2D.data[iRow][index++]);
awsDay.setGST_AVG_160CM(retArray2D.data[iRow][index++]);
awsDay.setGST_AVG_320CM(retArray2D.data[iRow][index++]);
awsDay.setFRS_1ST_TOP(retArray2D.data[iRow][index++]);
awsDay.setFRS_1ST_BOT(retArray2D.data[iRow][index++]);
awsDay.setFRS_2ND_TOP(retArray2D.data[iRow][index++]);
awsDay.setFRS_2ND_BOT(retArray2D.data[iRow][index++]);
awsDay.setSSH(retArray2D.data[iRow][index++]);
awsDay.setSUNRIST_TIME(retArray2D.data[iRow][index++]);
awsDay.setSUNSET_TIME(retArray2D.data[iRow][index++]);
awsDay.setLGST_AVG(retArray2D.data[iRow][index++]);
awsDay.setLGST_MAX(retArray2D.data[iRow][index++]);
awsDay.setLGST_MAX_OTIME(retArray2D.data[iRow][index++]);
awsDay.setLGST_MIN(retArray2D.data[iRow][index++]);
awsDay.setLGST_MIN_OTIME(retArray2D.data[iRow][index++]);
awsDay.setSCO(retArray2D.data[iRow][index++]);
awsDay.setRAIN(retArray2D.data[iRow][index++]);
awsDay.setPRE_OTIME(retArray2D.data[iRow][index++]);
awsDay.setSNOW(retArray2D.data[iRow][index++]);
awsDay.setSNOW_OTIME(retArray2D.data[iRow][index++]);
awsDay.setHAIL(retArray2D.data[iRow][index++]);
awsDay.setHAIL_OTIME(retArray2D.data[iRow][index++]);
awsDay.setFOG(retArray2D.data[iRow][index++]);
awsDay.setFOG_OTIME(retArray2D.data[iRow][index++]);
awsDay.setMIST(retArray2D.data[iRow][index++]);
awsDay.setDEW(retArray2D.data[iRow][index++]);
awsDay.setFROST(retArray2D.data[iRow][index++]);
awsDay.setGLAZE(retArray2D.data[iRow][index++]);
awsDay.setGLAZE_OTIME(retArray2D.data[iRow][index++]);
awsDay.setSORI(retArray2D.data[iRow][index++]);
awsDay.setSORI_OTIME(retArray2D.data[iRow][index++]);
awsDay.setDRSNOW(retArray2D.data[iRow][index++]);
awsDay.setDRSNOW_OTIME(retArray2D.data[iRow][index++]);
awsDay.setSNOWST(retArray2D.data[iRow][index++]);
awsDay.setSNOWST_OTIME(retArray2D.data[iRow][index++]);
awsDay.setTORD(retArray2D.data[iRow][index++]);
awsDay.setTORD_OTIME(retArray2D.data[iRow][index++]);
awsDay.setGSS(retArray2D.data[iRow][index++]);
awsDay.setICE(retArray2D.data[iRow][index++]);
awsDay.setSAST(retArray2D.data[iRow][index++]);
awsDay.setSAST_OTIME(retArray2D.data[iRow][index++]);
awsDay.setFLSA(retArray2D.data[iRow][index++]);
awsDay.setFLSA_OTIME(retArray2D.data[iRow][index++]);
awsDay.setFLDU(retArray2D.data[iRow][index++]);
awsDay.setFLDU_OTIME(retArray2D.data[iRow][index++]);
awsDay.setSMOKE(retArray2D.data[iRow][index++]);
awsDay.setHAZE(retArray2D.data[iRow][index++]);
awsDay.setDUWHR(retArray2D.data[iRow][index++]);
awsDay.setICEPRI(retArray2D.data[iRow][index++]);
awsDay.setTHUND(retArray2D.data[iRow][index++]);
awsDay.setTHUND_OTIME(retArray2D.data[iRow][index++]);
awsDay.setLIT(retArray2D.data[iRow][index++]);
awsDay.setAUR(retArray2D.data[iRow][index++]);
awsDay.setAUR_OTIME(retArray2D.data[iRow][index++]);
awsDay.setGAWIN(retArray2D.data[iRow][index++]);
awsDay.setGAWIN_OTIME(retArray2D.data[iRow][index++]);
awsDay.setSQUA(retArray2D.data[iRow][index++]);
awsDay.setSQUA_OTIME(retArray2D.data[iRow][index++]);
awsDay.setWEP_SUMARY(retArray2D.data[iRow][index++]);
awsDay.setWEP_RECORD(retArray2D.data[iRow][index++]);

//
paraList.add(awsDay);

}
}else{
log.info("****************"+retArray2D.request.errorCode+"****"+retArray2D.request.errorMessage);
}
} catch (Exception e) {
// 异常输出
e.printStackTrace();
} finally {
// 释放接口服务连接资源
client.destroyResources();

}

client.destroyResources();
log.info("DAY=====日值资料=======连接CIMISS: ----------------------" + paraList.size());

return paraList;
}

private boolean isMoreLength(String s){
if(s.length()>4)
return true;
else
return false;
}

3、入库操作。遍历这个集合,获得其中的每一条数据。还是以天的数据为例,这里执行如下代码,即可实现入库的操作。根据第二步两种不同情况下获得数据,时间点的数据执行自动数据入库的操作;时间段的数据执行补录入库的操作。

对第二步获得的awsDayList进行入库,本地数据库这里有两个,入库操作的执行代码是:

insertDB(awsList1);

//日风补录入库
insertDayWindDB(awsList1);
insertDayWindDBTo22(awsList1);

//日温度补录入库
insertDayTempDB(awsList1);
insertDayWindDBTo22(awsList1);

//日能见度 补录入库
insertDayVisDB(awsList1);
insertDayWindDBTo22(awsList1);

//日降水补录入库
insertDayRainDB(awsList1);
insertDayWindDBTo22(awsList1);

第一个CIMISS入库,是所有的数据的入库,原始库。

下面的根据我们业务的操作需求,进行入库操作,都有双份,为的是防止数据库出问题或者其他情况,从而进行互相备份的操作。

入库操作的流程是利用jdbc操纵oracle数据,进行数据的存储。这里的aws_day的sql语句是写在xml文件里面通过对xml文件节点的解析,将aws_day这个参数传进去,从而setString我们从CIMISS获得的数据。

private void insertDB(List<AwsDay> list) {
PreparedStatement ps = null;
// log.info("DAY=====日值资料===CIMSIS====开始入库。。。。: ");

try {
// 利用jdbcTemplate2得到在Spring中配置的dataSource数据源信息
con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
// 用于手动控制事务提交时机
con.setAutoCommit(false);
ps = con.prepareStatement(aws_day);
log.info("DAY=====日值资料===CIMSIS====JDBC 中集合大小: " + list.size());

for (int i = 0; i < list.size(); i++) {
AwsDay a = list.get(i);

ps.setString(1, a.getSTATION_NAME());
ps.setString(2, a.getPROVINCE());
ps.setString(3, a.getCITY());
ps.setString(4, a.getCNTY());
ps.setString(5, a.getTOWN());
ps.setString(6, a.getDATETIME());
ps.
...
...
ps.addBatch();
// 每个次执行集合大小且当执行到最后一条的时候直接批处理
if ((i > 0 && i % 2000 == 0) || i == list.size() - 1) {
// 执行批处理操作
ps.executeBatch();
// 主动提交事务
con.commit();
// 每次提交后把批量堆里清空(防止批处理OOM)
ps.clearBatch();
}
}

} catch (SQLException e) {
log.error(e.getMessage());
log.error(e.fillInStackTrace());
try {
if (con != null) {
// 出现异常情况就回滚
con.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}

} finally {
if (null != ps) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (null != con) {
try {
// 执行结尾,关闭数据源连接
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

对于日风,日温度入库等不是将所有的数据塞进数据库,而是相当于将原表的数据拆分,放入我们的业务数据库。