package com.moral.util; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import com.alibaba.fastjson.JSONObject; import com.moral.constant.Constants; public class AmendUtils { /** * @param value 需要科学计算的数据 * @param digit 保留的小数位 * @return 功能:四舍六入五成双计算法 */ public static double sciCal(double value, int digit) { String result; try { double ratio = Math.pow(10, digit); double _num = value * ratio; double mod = _num % 1; double integer = Math.floor(_num); double returnNum; if (mod > 0.5) { returnNum = (integer + 1) / ratio; } else if (mod < 0.5) { returnNum = integer / ratio; } else { returnNum = (integer % 2 == 0 ? integer : integer + 1) / ratio; } BigDecimal bg = new BigDecimal(returnNum); result = bg.setScale(digit, BigDecimal.ROUND_HALF_UP).toString(); } catch (RuntimeException e) { throw e; } return Double.parseDouble(result); } /** * @param list 参数,[value={"O3":12},.....] * @return 功能:臭氧日均值计算 */ public static Object getO3AvgOfDay(List> list) { double max; List avgs = new ArrayList<>(); for (int i = 8; i <= 24; i++) { List data = new ArrayList<>(); for (Map dataMap : list) { Map dataValue = JSONObject.parseObject((String) dataMap.get("value"), Map.class); Double o3 = Double.parseDouble(dataValue.get(Constants.SENSOR_CODE_O3).toString()); int hour = DateUtils.getHour((Date) dataMap.get("time")); if (hour == 0) { hour = 24; } if (hour <= i && hour >= i - 7) { data.add(o3); } } if (data.size() < 6) { continue; } double average = data.stream().mapToDouble(aDouble -> aDouble).summaryStatistics().getAverage(); avgs.add(average); } max = avgs.stream().mapToDouble(aDouble -> aDouble).summaryStatistics().getMax(); if (avgs.size() < 14) { if (max < 160d) { return null; } } return sciCal(max, 4); } /** * @param list 参数,[value={"风速":12,”风向“:200},.....] * @return 功能:风向均值计算 */ public static Object getWindDirAvg(List> list) { double avgDir; double sumSin = 0d; double sumCos = 0d; int size = 0; for (Map map : list) { Map dataValue = JSONObject.parseObject((String) map.get("value"), Map.class); Object wind = dataValue.get(Constants.SENSOR_CODE_WIND_DIR); Object speed = dataValue.get(Constants.SENSOR_CODE_WIND_SPEED); if (wind == null || speed == null) { continue; } size++; int windDir = Integer.parseInt(wind.toString()); double windSpeed = Double.parseDouble(speed.toString()); double sin = windSpeed * Math.sin(windDir / 180d) * Math.PI; double cos = windSpeed * Math.cos(windDir / 180d) * Math.PI; sumSin += sin; sumCos += cos; } if (size == 0) { return null; } double avgSin = sumSin / size; double avgCos = sumCos / size; if (avgSin > 0 && avgCos > 0) { avgDir = Math.atan(avgSin / avgCos) * 180 / Math.PI; } else if ((avgSin > 0 && avgCos < 0) || (avgSin < 0 && avgCos < 0)) { avgDir = Math.atan(avgSin / avgCos) * 180 / Math.PI + 180; } else { avgDir = Math.atan(avgSin / avgCos) * 180 / Math.PI + 360; } return sciCal(avgDir, 4); } /** * @param data 需要求百分位的数据 * @param p 百分位,例:95百分位,p=95 * @return 功能:百分位数计算 */ public static double percentile(List data, int p) { int n = data.size(); Collections.sort(data); double v = n / (100 / p); System.out.println(n % (100 / p)); if (n % (100 / p) == 0) { if (v == n) { return data.get(n - 1); } return (data.get((int) v - 1) + data.get((int) v)) / 2; } return sciCal(data.get((int) v), 4); } public static Object getCOAvgOfWeek(List> list) { List data = new ArrayList<>(); for (Map dataMap : list) { Map dataValue = JSONObject.parseObject((String) dataMap.get("value"), Map.class); Object o = dataValue.get(Constants.SENSOR_CODE_CO); if (o == null) { continue; } Double co = Double.parseDouble(o.toString()); data.add(co); } if (data.size() == 0) { return null; } return percentile(data, 95); } public static Object getO3AvgOfWeek(List> list) { List data = new ArrayList<>(); for (Map dataMap : list) { Map dataValue = JSONObject.parseObject((String) dataMap.get("value"), Map.class); Object o = dataValue.get(Constants.SENSOR_CODE_O3); if (o == null) { continue; } Double o3 = Double.parseDouble(o.toString()); data.add(o3); } if (data.size() == 0) { return null; } return percentile(data, 90); } }