package com.moral.util; import org.springframework.util.ObjectUtils; import java.util.*; /** * @ClassName ComprehensiveIndexUtils * @Description 综合指数计算工具类 * @Author 陈凯裕 * @Date 2021/9/27 9:40 * @Version TODO **/ public class ComprehensiveIndexUtils { /** * @Description: 获取月综合指数,参数为日数据的集合,map为每日的数据 * @Param: [datas] * @return: Double * @Author: 陈凯裕 * @Date: 2021/9/27 */ public static Double monthData(List> datas) { //计算各污染物的统计量浓度值 Map CValueMap = calCValue(datas); if (CValueMap == null) return null; Double CSO2 = CValueMap.get("CSO2"); Double CNO2 = CValueMap.get("CNO2"); Double CPM25 = CValueMap.get("CPM25"); Double CPM10 = CValueMap.get("CPM10"); Double CCO = CValueMap.get("CCO"); Double CO3 = CValueMap.get("CO3"); //S开头为污染物年均值二级标准(当污染物是CO时,采用日均值二级标准。当污染是O3时,采用八小时均值二级标准) //数据来源GB 3095-2012 Double SSO2 = 60d; Double SNO2 = 40d; Double SPM25 = 35d; Double SPM10 = 70d; Double SCO = 4d; Double SO3 = 160d; //计算污染物单项指数 Double ISO2 = CSO2 / SSO2; Double INO2 = CNO2 / SNO2; Double IPM25 = CPM25 / SPM25; Double IPM10 = CPM10 / SPM10; Double ICO = CCO / SCO; Double IO3 = CO3 / SO3; //计算综合指数 Double comprehensiveIndex = MathUtils.add(ISO2, INO2); comprehensiveIndex = MathUtils.add(comprehensiveIndex, IPM25); comprehensiveIndex = MathUtils.add(comprehensiveIndex, IPM10); comprehensiveIndex = MathUtils.add(comprehensiveIndex, ICO); comprehensiveIndex = MathUtils.add(comprehensiveIndex, IO3); comprehensiveIndex = AmendUtils.sciCal(comprehensiveIndex, 2); return comprehensiveIndex; } /** * @Description: 计算各因子浓度值 * SO2 NO2 PM10 PM2.5为月均浓度,CO取日均值的第九十五百分位,O3取日最大八小时值的第九十百分位 * @Param: [datas] * @return: java.util.Map * @Author: 陈凯裕 * @Date: 2021/9/27 */ private static Map calCValue(List> datas) { //定义浓度值 Double CSO2;//SO2统计量浓度值 Double CNO2;//NO2统计量浓度值 Double CPM10;//PM10统计量浓度值 Double CPM25;//PM25统计量浓度值 Double CCO;//CO统计量浓度值 Double CO3;//O3统计量浓度值 //计算SO2 NO2 PM10 PM2.5月均值 Double SO2Sum = 0d; Double NO2Sum = 0d; Double PM10Sum = 0d; Double PM25Sum = 0d; Double SO2Num = 0d; Double NO2Num = 0d; Double PM10Num = 0d; Double PM25Num = 0d; for (Map data : datas) { Object SO2 = data.get("a21026"); Object NO2 = data.get("a21004"); Object PM10 = data.get("a34002"); Object PM25 = data.get("a34004"); if (SO2 != null) { SO2Num++; SO2Sum = MathUtils.add(SO2Sum, Double.valueOf(SO2.toString())); } if (NO2 != null) { NO2Num++; NO2Sum = MathUtils.add(NO2Sum, Double.valueOf(NO2.toString())); } if (PM10 != null) { PM10Num++; PM10Sum = MathUtils.add(PM10Sum, Double.valueOf(PM10.toString())); } if (PM25 != null) { PM25Num++; PM25Sum = MathUtils.add(PM25Sum, Double.valueOf(PM25.toString())); } } CSO2 = SO2Sum / SO2Num; CNO2 = NO2Sum / NO2Num; CPM10 = PM10Sum / PM10Num; CPM25 = PM25Sum / PM25Num; if (CSO2 == 0d || CNO2 == 0d || CPM10 == 0d || CPM25 == 0d) return null; /*计算CO统计量浓度值*/ //获取CO从小到大排序的集合 List COs = getSensorAsc(datas, "a21005"); //取第95百分位 if (COs.size() == 0) return null; Double COIndexd = COs.size() * 0.95; int COIndex = new Double(Math.ceil(COIndexd)).intValue(); CCO = COs.get(COIndex - 1); /*计算O3统计量浓度*/ //获取O3日八小时最大值从小到大排序的结婚 List O3s = getSensorAsc(datas, "a05024"); //取第90百分位 if (O3s.size() == 0) return null; Double O3Indexd = O3s.size() * 0.9; int O3Index = new Double(Math.ceil(O3Indexd)).intValue(); CO3 = O3s.get(O3Index - 1); Map result = new HashMap<>(); result.put("CSO2", CSO2); result.put("CNO2", CNO2); result.put("CPM25", CPM25); result.put("CPM10", CPM10); result.put("CCO", CCO); result.put("CO3", CO3); return result; } /** * @Description: 获取因子的升序排序集合 * @Param: [datas] * @return: java.util.List * @Author: 陈凯裕 * @Date: 2021/9/27 */ private static List getSensorAsc(List> datas, String sensor) { List result = new ArrayList<>(); datas.forEach(value -> { Object o = value.get(sensor); if (o != null) result.add(Double.valueOf(o.toString())); }); Collections.sort(result, new Comparator() { @Override public int compare(Double o1, Double o2) { return new Double(o1 - o2).intValue(); } }); return result; } /** * @Description: 获取日综合指数,参数为日六参数据 * @Param: [data] * @return: Double */ public static Double dailyData(Map data) { if (data == null) return null; Double CPM25 = Double.parseDouble(data.get("PM2_5").toString()); Double CPM10 = Double.parseDouble(data.get("PM10").toString()); Double CSO2 = Double.parseDouble(data.get("SO2").toString()); Double CNO2 = Double.parseDouble(data.get("NO2").toString()); Double CCO = Double.parseDouble(data.get("CO").toString()); Object o3 = data.get("O3"); Double CO3 = null; if (!ObjectUtils.isEmpty(o3)) { CO3 = Double.parseDouble(o3.toString()); } //S开头为污染物年均值二级标准(当污染物是CO时,采用日均值二级标准。当污染是O3时,采用八小时均值二级标准) //数据来源GB 3095-2012 Double SSO2 = 60d; Double SNO2 = 40d; Double SPM25 = 35d; Double SPM10 = 70d; Double SCO = 4d; Double SO3 = 160d; //计算污染物单项指数 Double ISO2 = CSO2 / SSO2; Double INO2 = CNO2 / SNO2; Double IPM25 = CPM25 / SPM25; Double IPM10 = CPM10 / SPM10; Double ICO = CCO / SCO; Double IO3 = null; if (!ObjectUtils.isEmpty(CO3)) { IO3 = CO3 / SO3; } //计算综合指数 Double comprehensiveIndex = MathUtils.add(ISO2, INO2); comprehensiveIndex = MathUtils.add(comprehensiveIndex, IPM25); comprehensiveIndex = MathUtils.add(comprehensiveIndex, IPM10); comprehensiveIndex = MathUtils.add(comprehensiveIndex, ICO); if (!ObjectUtils.isEmpty(IO3)) { comprehensiveIndex = MathUtils.add(comprehensiveIndex, IO3); } comprehensiveIndex = AmendUtils.sciCal(comprehensiveIndex, 2); return comprehensiveIndex; } }