package com.moral.api.service.impl; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.moral.api.config.properties.AnnouncementProperties; import com.moral.api.config.properties.SpecialCitiesProperties; import com.moral.api.entity.CityAqiDaily; import com.moral.api.entity.CityAqiMonthly; import com.moral.api.entity.SysArea; import com.moral.api.mapper.CityAqiMonthlyMapper; import com.moral.api.service.CityAqiDailyService; import com.moral.api.service.CityAqiMonthlyService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.moral.api.service.SysAreaService; import com.moral.constant.Constants; import com.moral.constant.RedisConstants; import com.moral.util.AmendUtils; import com.moral.util.ComprehensiveIndexUtils; import com.moral.util.DateUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import java.text.DecimalFormat; import java.time.Duration; import java.util.*; import java.util.stream.Collectors; import java.util.stream.DoubleStream; /** *

* 城市aqi月数据表 服务实现类 *

* * @author moral * @since 2021-11-05 */ @Service public class CityAqiMonthlyServiceImpl extends ServiceImpl implements CityAqiMonthlyService { @Autowired private CityAqiMonthlyMapper cityAqiMonthlyMapper; @Autowired private SpecialCitiesProperties specialCitiesProperties; @Autowired private SysAreaService sysAreaService; @Autowired private CityAqiDailyService cityAqiDailyService; @Autowired private RedisTemplate redisTemplate; @Autowired private AnnouncementProperties announcementProperties; @Override public List getCityAqiMonthByRegionCodeAndTime(Integer regionCode, Date startDate, Date endDate) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("city_code", regionCode); queryWrapper.between("time", startDate, endDate); return cityAqiMonthlyMapper.selectList(queryWrapper); } @Override public CityAqiMonthly getCityAqiMonthByRegionCodeAndTime(Integer regionCode, Date time) { time = DateUtils.getFirstDayOfMonth(time); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("city_code", regionCode); queryWrapper.eq("time", time); return cityAqiMonthlyMapper.selectOne(queryWrapper); } @Override public Map airQualityRankingAnnouncement(Integer regionCode, Date time) { Map result = new LinkedHashMap<>(); String month = DateUtils.getMonth(time) + ""; int yearMonthOfSelect = Integer.parseInt(DateUtils.dateToDateString(time, DateUtils.yyyyMM_EN)); int nowYearMonthOfSelect = Integer.parseInt(DateUtils.getCurDate(DateUtils.yyyyMM_EN)); if (yearMonthOfSelect > nowYearMonthOfSelect) { return result; } //先根据时间和地区code从redis中获取,没有再计算后存入redis result = (Map) redisTemplate.opsForValue().get(RedisConstants.AQI_ANNOUNCEMENT + "_" + regionCode + "_" + DateUtils.dateToDateString(time, DateUtils.yyyyMM_EN)); if (result != null) { return result; } result = new LinkedHashMap<>(); //获取xx市和所有县市区名字信息 QueryWrapper sysAreaQueryWrapper = new QueryWrapper<>(); sysAreaQueryWrapper.select("area_code", "area_name") .eq("parent_code", regionCode).or() .eq("area_code", regionCode); List sysAreas = sysAreaService.list(sysAreaQueryWrapper); Map areasMap = new HashMap<>(); for (SysArea sysArea : sysAreas) { areasMap.put(sysArea.getAreaCode(), sysArea.getAreaName()); } String cityName = areasMap.remove(regionCode); result.put("cityName", cityName); result.put("areaSize", areasMap.size()); //一、空气质量排名 //1.本月xx市空气质量排名 Map currentRankingResult = new HashMap<>(); //获取本月xx市空气质量数据 QueryWrapper cityAqiMonthlyQueryWrapper = new QueryWrapper<>(); cityAqiMonthlyQueryWrapper.select("value") .eq("city_code", regionCode) .eq("time", time); CityAqiMonthly cityAqiMonthly = cityAqiMonthlyMapper.selectOne(cityAqiMonthlyQueryWrapper); Double compositeIndex = null; String compositeIndexYearOnYear = null; Double pm25 = null; String pm25YearOnYear = null; if (cityAqiMonthly != null) { Map aqiMap = JSONObject.parseObject(cityAqiMonthly.getValue(), Map.class); //1.综指 if (aqiMap.get("compositeIndex") != null) { compositeIndex = Double.parseDouble(aqiMap.get("compositeIndex").toString()); } currentRankingResult.put("compositeIndex", compositeIndex); //2.综指同比 if (aqiMap.get("compositeIndex_yearOnYear") != null) { compositeIndexYearOnYear = aqiMap.get("compositeIndex_yearOnYear").toString(); } currentRankingResult.put("compositeIndex_yearOnYear", compositeIndexYearOnYear); //3.PM2.5浓度 if (aqiMap.get("PM2_5") != null) { pm25 = Objects.nonNull(aqiMap.get("PM2_5"))?Double.parseDouble(aqiMap.get("PM2_5").toString()):0d; } currentRankingResult.put("PM2_5", pm25 + "ug/m³"); //4.PM.5浓度同比 if (aqiMap.get("PM2_5_yearOnYear") != null) { pm25YearOnYear = aqiMap.get("PM2_5_yearOnYear").toString(); } currentRankingResult.put("PM2_5_yearOnYear", pm25YearOnYear); //5.168城市排名,包括综指,综指同比,pm2.5,pm2.5同比 Map ranking168 = getOneSixEightCitiesRanking(regionCode, time); currentRankingResult.putAll(ranking168); //6.2+26城市排名,包括综指,综指同比,pm2.5,pm2.5同比 Map ranking28 = getTwentyEightCitiesRanking(regionCode, time); currentRankingResult.putAll(ranking28); //7.河北八通道城市排名,包括综指,综指同比,pm2.5,pm2.5同比 Map ranking8Channels = getHeBeiEightCitiesRanking(regionCode, time); currentRankingResult.putAll(ranking8Channels); } String start = DateUtils.dateToDateString(time, DateUtils.yyyy_MM_dd_CN); //本月最后一日 String end = DateUtils.dateToDateString(DateUtils.getLastDayOfMonth(time), DateUtils.yyyy_MM_dd_CN); result.put("currentRanking", aqiQualityRankingResponse(start + "-" + end, cityName, currentRankingResult)); //2.1-x月xx市空气质量排名 //所有县市区codes List areaCodes = new ArrayList<>(areasMap.keySet()); //地级市code areaCodes.add(regionCode); Map> monthlyCumulativeResult = null; Double cityCompositeIndex = null; String cityCompositeIndexYearOnYear = null; Double cityPM25 = null; String cityPM25YearOnYear = null; if (!"1".equals(month)) { Map cumulativeRankingResult = new HashMap<>(); //获取xx市和下属所有县市区1-xx月数据 monthlyCumulativeResult = getMonthlyCumulativeResult(time, areaCodes); //xx市数据 if (monthlyCumulativeResult != null) { Map cityMap = monthlyCumulativeResult.remove(regionCode); if (cityMap != null) { //地级市综指 cityCompositeIndex = Double.parseDouble(cityMap.get("compositeIndex").toString()); if (cityMap.get("compositeIndex_yearOnYear") != null) { cityCompositeIndexYearOnYear = cityMap.get("compositeIndex_yearOnYear").toString(); } //地级市PM2.5 cityPM25 = Double.parseDouble(cityMap.get("PM2_5").toString()); if (cityMap.get("PM2_5_yearOnYear") != null) { cityPM25YearOnYear = cityMap.get("PM2_5_yearOnYear").toString(); } } } cumulativeRankingResult.put("compositeIndex", cityCompositeIndex); cumulativeRankingResult.put("compositeIndex_yearOnYear", cityCompositeIndexYearOnYear); cumulativeRankingResult.put("PM2_5", cityPM25); if (cityPM25 != null) { cumulativeRankingResult.put("PM2_5", cityPM25 + "ug/m³"); } cumulativeRankingResult.put("PM2_5_yearOnYear", cityPM25YearOnYear); //5.168城市排名,包括综指,综指同比,pm2.5,pm2.5同比 Map ranking168 = getOneSixEightCitiesRankingOfCumulative(regionCode, time); cumulativeRankingResult.putAll(ranking168); //6.2+26城市排名,包括综指,综指同比,pm2.5,pm2.5同比 Map ranking28 = getTwentyEightCitiesRankingOfCumulative(regionCode, time); cumulativeRankingResult.putAll(ranking28); //7.河北八通道城市排名,包括综指,综指同比,pm2.5,pm2.5同比 Map ranking8Channels = getHeBeiEightCitiesRankingOfCumulative(regionCode, time); cumulativeRankingResult.putAll(ranking8Channels); //开始时间,当年1月1日 start = DateUtils.dateToDateString(DateUtils.getFirstDayOfYear(time), DateUtils.yyyy_MM_dd_CN); //结束时间,当月最后一天 end = DateUtils.dateToDateString(DateUtils.getLastDayOfMonth(time), DateUtils.yyyy_MM_dd_CN); result.put("cumulativeRanking", aqiQualityRankingResponse(start + "-" + end, cityName, cumulativeRankingResult)); } //二、各县市区空气质量情况结果集 //获取本期xx市下所有县市区数据 cityAqiMonthlyQueryWrapper.clear(); areaCodes.remove(regionCode); cityAqiMonthlyQueryWrapper.select("city_code", "value") .eq("time", time) .in("city_code", areaCodes); List areaData = cityAqiMonthlyMapper.selectList(cityAqiMonthlyQueryWrapper); //获取本期所有县市区与中心城区(地级市)因子对比情况 Map areaCurrentMonthResult = getAreaCurrentMonthResult(areasMap, areaData, compositeIndex, compositeIndexYearOnYear, pm25, pm25YearOnYear); //本月县市区综指与中心城区对比 result.put("currentCompositeIndexContrast", compositeIndexContrastResponse(month, cityName, areaCodes.size(), areaCurrentMonthResult)); //本月县市区综指同比与中心城区对比 result.put("currentCompositeIndexYearOnYearContrast", compositeIndexYearOnYearContrastResponse(month, cityName, areaCodes.size(), areaCurrentMonthResult)); //本月县市区PM2.5与中心城区对比 result.put("currentPM25Contrast", pm25tContrastResponse(month, cityName, areaCodes.size(), areaCurrentMonthResult)); //本月县市区Pm2.5同比与中心城区对比 result.put("currentPM25YearOnYearContrast", pm25YearOnYearContrastResponse(month, cityName, areaCodes.size(), areaCurrentMonthResult)); //三、1-x月累计结果 List cumulativeList = null; if (!"1".equals(month)) { cumulativeList = new ArrayList<>(); if (monthlyCumulativeResult != null) { for (Map.Entry> entry : monthlyCumulativeResult.entrySet()) { CityAqiMonthly cityAqiMonthly1 = new CityAqiMonthly(); cityAqiMonthly1.setCityCode(entry.getKey()); cityAqiMonthly1.setValue(JSONObject.toJSONString(entry.getValue())); cumulativeList.add(cityAqiMonthly1); } } month = "1-" + DateUtils.getMonth(time); //获取1-x月所有县市区与地级市数据对比情况 Map monthlyCumulativeListResultMap = getAreaCurrentMonthResult(areasMap, cumulativeList, cityCompositeIndex, cityCompositeIndexYearOnYear, cityPM25, cityPM25YearOnYear); //1-xx月份县市区综指与中心城区对比 result.put("cumulativeCompositeIndexContrast", compositeIndexContrastResponse(month, cityName, areaCodes.size(), monthlyCumulativeListResultMap)); //1-xx月份县市区综指同比与中心城区对比 result.put("cumulativeCompositeIndexYearOnYearContrast", compositeIndexYearOnYearContrastResponse(month, cityName, areaCodes.size(), monthlyCumulativeListResultMap)); //1-xx月份县市区PM2.5与中心城区对比 result.put("cumulativePM25Contrast", pm25tContrastResponse(month, cityName, areaCodes.size(), monthlyCumulativeListResultMap)); //1-xx月份县市区Pm2.5同比与中心城区对比 result.put("cumulativePM25YearOnYearContrast", pm25YearOnYearContrastResponse(month, cityName, areaCodes.size(), monthlyCumulativeListResultMap)); } //四、附件 //1.本期综指和pm2.5考核排名报表 List> airQualityRankingOfCurrentReport = airQualityRankingOfCurrentReport(areaData, areasMap); result.put("currentAirQualityRankingReport", airQualityRankingOfCurrentReport); //2.1-x月份累计空气质量综指和pm2.5排名报表 if (!"1".equals(month)) { List> cumulativeAirQualityRankingReport = cumulativeAirQualityRankingReport(cumulativeList, areasMap); result.put("cumulativeAirQualityRankingReport", cumulativeAirQualityRankingReport); } //3.本期五因子(PM10,SO2,NO2,CO,O3)对比报表 List> currentFiveSensorsContrastReport = currentFiveSensorsContrastReport(time, areaCodes, areaData, areasMap); result.put("currentFiveSensorsContrastReport", currentFiveSensorsContrastReport); //4.1-x月份五因子(PM10,SO2,NO2,CO,O3)对比报表 if (!"1".equals(month)) { List> cumulativeFiveSensorsContrastReport = cumulativeFiveSensorsContrastReport(cumulativeList, areasMap); result.put("cumulativeFiveSensorsContrastReport", cumulativeFiveSensorsContrastReport); } //存入redis redisTemplate.opsForValue().set(RedisConstants.AQI_ANNOUNCEMENT + "_" + regionCode + "_" + DateUtils.dateToDateString(time, DateUtils.yyyyMM_EN), result, Duration.ofDays(30)); return result; } /** * @param startEnd 时间 * @param cityName 地级市名字 * @param result 当月数据map * @description 当月排名文字拼接 */ private String aqiQualityRankingResponse(String startEnd, String cityName, Map result) { Object compositeIndex = result.get("compositeIndex"); Object compositeIndex_rank_168 = result.get("compositeIndex_rank_168"); Object compositeIndex_rank_28 = result.get("compositeIndex_rank_28"); Object compositeIndex_rank_8Channels = result.get("compositeIndex_rank_8Channels"); Object compositeIndexYearOnYear = result.get("compositeIndex_yearOnYear"); Object compositeIndexYearOnYear_rank_168 = result.get("compositeIndex_yearOnYear_rank_168"); Object compositeIndexYearOnYear_rank_28 = result.get("compositeIndex_yearOnYear_rank_28"); Object compositeIndexYearOnYear_rank_8Channels = result.get("compositeIndex_yearOnYear_rank_8Channels"); //综指排名 StringBuilder compositeIndexBuilder = new StringBuilder(); if (compositeIndex_rank_168 != null) { compositeIndexBuilder.append("在168城市正排第" + compositeIndex_rank_168 + "名"); } if (compositeIndex_rank_28 != null) { compositeIndexBuilder.append("在'2+26'城市正排第" + compositeIndex_rank_28 + "名"); } if (compositeIndex_rank_8Channels != null) { compositeIndexBuilder.append("在河北八通道城市正排第" + compositeIndex_rank_8Channels + "名"); } //综指同比排名 StringBuilder compositeIndexYearOnYearBuilder = new StringBuilder(); if (compositeIndexYearOnYear_rank_168 != null) { compositeIndexYearOnYearBuilder.append("在168城市正排第" + compositeIndexYearOnYear_rank_168 + "名"); } if (compositeIndexYearOnYear_rank_28 != null) { compositeIndexYearOnYearBuilder.append("在'2+26'城市正排第" + compositeIndexYearOnYear_rank_28 + "名"); } if (compositeIndexYearOnYear_rank_8Channels != null) { compositeIndexYearOnYearBuilder.append("在河北八通道城市正排第" + compositeIndexYearOnYear_rank_8Channels + "名"); } Object pm2_5 = result.get("PM2_5"); Object pm2_5_rank_168 = result.get("PM2_5_rank_168"); Object pm2_5_rank_28 = result.get("PM2_5_rank_28"); Object pm2_5_rank_8Channels = result.get("PM2_5_rank_8Channels"); Object pm2_5YearOnYear = result.get("PM2_5_yearOnYear"); Object pm2_5YearOnYear_rank_168 = result.get("PM2_5_yearOnYear_rank_168"); Object pm2_5YearOnYear_rank_28 = result.get("PM2_5_yearOnYear_rank_28"); Object pm2_5YearOnYear_rank_8Channels = result.get("PM2_5_yearOnYear_rank_8Channels"); //PM2.5排名 StringBuilder pm25Builder = new StringBuilder(); if (pm2_5_rank_168 != null) { pm25Builder.append("在168城市正排第" + pm2_5_rank_168 + "名"); } if (pm2_5_rank_28 != null) { pm25Builder.append("在'2+26'城市正排第" + pm2_5_rank_28 + "名"); } if (pm2_5_rank_8Channels != null) { pm25Builder.append("在河北八通道城市正排第" + pm2_5_rank_8Channels + "名"); } //PM2.5同比排名 StringBuilder pm25YearOnYearBuilder = new StringBuilder(); if (pm2_5YearOnYear_rank_168 != null) { pm25YearOnYearBuilder.append("在168城市正排第" + pm2_5YearOnYear_rank_168 + "名"); } if (pm2_5YearOnYear_rank_28 != null) { pm25YearOnYearBuilder.append("在'2+26'城市正排第" + pm2_5YearOnYear_rank_28 + "名"); } if (pm2_5YearOnYear_rank_8Channels != null) { pm25YearOnYearBuilder.append("在河北八通道城市正排第" + pm2_5YearOnYear_rank_8Channels + "名"); } String currentRanking = announcementProperties.getCurrentRanking(); currentRanking = currentRanking.replace("{start-end}", startEnd) .replace("{cityName}", cityName) .replace("{compositeIndex}", compositeIndex == null ? "_" : compositeIndex.toString()) .replace("{compositeIndexRanking}", compositeIndexBuilder.toString().equals("") ? "_" : compositeIndexBuilder.toString()) .replace("{compositeIndexYearOnYearRanking}", compositeIndexYearOnYearBuilder.toString().equals("") ? "_" : compositeIndexYearOnYearBuilder.toString()) .replace("{PM2_5}", pm2_5 == null ? "_" : pm2_5.toString()) .replace("{PM2_5Ranking}", pm25Builder.toString().equals("") ? "_" : pm25Builder.toString()) .replace("{PM2_5YearOnYearRanking}", pm25YearOnYearBuilder.toString().equals("") ? "_" : pm25YearOnYearBuilder.toString()); String strCompositeIndexYearOnYear = "_"; if (compositeIndexYearOnYear != null) { if (compositeIndexYearOnYear.toString().startsWith("-")) { strCompositeIndexYearOnYear = compositeIndexYearOnYear.toString().replace("-", "下降"); } else if (Double.parseDouble(compositeIndexYearOnYear.toString().replace("%", "")) == 0d) { strCompositeIndexYearOnYear = compositeIndexYearOnYear.toString(); } else { strCompositeIndexYearOnYear = "上升" + compositeIndexYearOnYear; } } String strPM25YearOnYear = "_"; if (pm2_5YearOnYear != null) { if (pm2_5YearOnYear.toString().startsWith("-")) { strPM25YearOnYear = pm2_5YearOnYear.toString().replace("-", "下降"); } else { strPM25YearOnYear = "上升" + pm2_5YearOnYear; } } currentRanking = currentRanking.replace("{compositeIndexYearOnYear}", strCompositeIndexYearOnYear).replace("{PM2_5YearOnYear}", strPM25YearOnYear); return currentRanking; } /** * @param month 月份 * @param cityName 地级市名字 * @param result 当月数据map * @description 县市区与中心城市对比文字拼接 */ private String compositeIndexContrastResponse(String month, String cityName, Integer areaSize, Map result) { Object compositeIndex = result.get("compositeIndex"); List compositeIndexLowerList = (List) result.get("compositeIndexLower"); List compositeIndexHigherList = (List) result.get("compositeIndexHigher"); List compositeIndexEqualList = (List) result.get("compositeIndexEqual"); //综指对比 String compositeIndexLower = compositeIndexLowerList.stream() .map(String::valueOf).collect(Collectors.joining(",")); String compositeIndexHigher = compositeIndexHigherList.stream() .map(String::valueOf).collect(Collectors.joining(",")); String compositeIndexEqual = compositeIndexEqualList.stream() .map(String::valueOf).collect(Collectors.joining(",")); StringBuilder builder = new StringBuilder(); if (compositeIndexLowerList.size() != 0) { builder.append("有" + compositeIndexLowerList.size() + "个县(市、区)空气质量综合指数低于中心城区,分别为:").append(compositeIndexLower + ","); } if (compositeIndexEqualList.size() != 0) { builder.append(compositeIndexEqual + "" + compositeIndexEqualList.size() + "个县(市、区)空气质量综合指数与中心城区持平"); } if (compositeIndexHigherList.size() != 0) { builder.append("有" + compositeIndexHigherList.size() + "个县(市、区)空气质量综合指数高于中心城区,分别为:").append(compositeIndexHigher); } String currentContrastCompositeIndex = announcementProperties.getContrastCompositeIndex(); currentContrastCompositeIndex = currentContrastCompositeIndex.replace("{month}", month) .replace("{cityName}", cityName) .replace("{compositeIndex}", compositeIndex == null ? "_" : compositeIndex.toString()) .replace("{areaSize}", areaSize + "") .replace("{details}", builder.toString().equals("") ? "_" : builder.toString()); return currentContrastCompositeIndex; } /** * @param month 月份 * @param cityName 地级市名字 * @param result 当月数据map * @description 当月排名文字拼接 */ private String compositeIndexYearOnYearContrastResponse(String month, String cityName, Integer areaSize, Map result) { Object compositeIndexYearOnYear = result.get("compositeIndexYearOnYear"); List compositeIndexYearOnYearLowerList = (List) result.get("compositeIndexYearOnYearLower"); List compositeIndexYearOnYearHigherList = (List) result.get("compositeIndexYearOnYearHigher"); List compositeIndexYearOnYearEqualList = (List) result.get("compositeIndexYearOnYearEqual"); List compositeIndexYearOnYearHigherOfPositiveList = (List) result.get("compositeIndexYearOnYearHigherOfPositive"); List compositeIndexYearOnYearHigherOfNegativeList = (List) result.get("compositeIndexYearOnYearHigherOfNegative"); List compositeIndexYearOnYearHigherOfZeroList = (List) result.get("compositeIndexYearOnYearHigherOfZero"); //综指同比对比 String compositeIndexYearOnYearLower = compositeIndexYearOnYearLowerList.stream() .map(String::valueOf).collect(Collectors.joining(",")); String compositeIndexYearOnYearEqual = compositeIndexYearOnYearEqualList.stream() .map(String::valueOf).collect(Collectors.joining(",")); String compositeIndexYearOnYearHigherOfPositive = compositeIndexYearOnYearHigherOfPositiveList.stream() .map(String::valueOf).collect(Collectors.joining(",")); String compositeIndexYearOnYearHigherOfNegative = compositeIndexYearOnYearHigherOfNegativeList.stream() .map(String::valueOf).collect(Collectors.joining(",")); StringBuilder builder = new StringBuilder(); if (compositeIndexYearOnYearLowerList.size() != 0) { builder.append("有" + compositeIndexYearOnYearLowerList.size() + "个县(市、区)空气质量综合指数同比改善幅度大于中心城区,分别为:") .append(compositeIndexYearOnYearLower + ";"); } if (compositeIndexYearOnYearEqualList.size() != 0) { builder.append(compositeIndexYearOnYearEqual + "" + compositeIndexYearOnYearEqualList.size() + "个县(市、区)空气质量综合指数同比改善幅度与中心城区持平;"); } if (compositeIndexYearOnYearHigherList.size() != 0) { builder.append("有" + compositeIndexYearOnYearHigherList.size() + "个县(市、区)空气质量综合指数同比改善幅度小于中心城区,"); if (compositeIndexYearOnYearHigherOfPositiveList.size() != 0) { builder.append("其中有" + compositeIndexYearOnYearHigherOfPositiveList.size() + "个县(市、区)空气质量综合指数同比上升,分别为:" + compositeIndexYearOnYearHigherOfPositive + ","); } if (compositeIndexYearOnYearHigherOfZeroList.size() != 0) { builder.append("其中有" + compositeIndexYearOnYearHigherOfZeroList.size() + "个县(市、区)空气质量综合指数同比持平,"); } if (compositeIndexYearOnYearHigherOfNegativeList.size() != 0) { builder.append("其中有" + compositeIndexYearOnYearHigherOfNegativeList.size() + "个县(市、区)空气质量综合指数同比下降,分别为:" + compositeIndexYearOnYearHigherOfNegative); } } String strCompositeIndexYearOnYear = "_"; if (compositeIndexYearOnYear != null) { if (compositeIndexYearOnYear.toString().startsWith("-")) { strCompositeIndexYearOnYear = compositeIndexYearOnYear.toString().replace("-", "下降"); } else if (Double.parseDouble(compositeIndexYearOnYear.toString().replace("%", "")) == 0d) { strCompositeIndexYearOnYear = compositeIndexYearOnYear.toString(); } else { strCompositeIndexYearOnYear = "上升" + compositeIndexYearOnYear; } } String currentContrastCompositeIndexYearOnYear = announcementProperties.getContrastCompositeIndexYearOnYear(); currentContrastCompositeIndexYearOnYear = currentContrastCompositeIndexYearOnYear.replace("{month}", month) .replace("{cityName}", cityName) .replace("{compositeIndexYearOnYear}", strCompositeIndexYearOnYear) .replace("{areaSize}", areaSize + "") .replace("{details}", builder.toString().equals("") ? "_" : builder.toString()); return currentContrastCompositeIndexYearOnYear; } /** * @param month 月份 * @param cityName 地级市名字 * @param result 当月数据map * @description PM2.5拼接 */ private String pm25tContrastResponse(String month, String cityName, Integer areaSize, Map result) { Object pm25 = result.get("PM2_5"); List pm25LowerList = (List) result.get("PM2_5Lower"); List pm25HigherList = (List) result.get("PM2_5Higher"); List pm25EqualList = (List) result.get("PM2_5Equal"); //PM2.5对比 String pm25Lower = pm25LowerList.stream() .map(String::valueOf).collect(Collectors.joining(",")); String pm25Higher = pm25HigherList.stream() .map(String::valueOf).collect(Collectors.joining(",")); String pm25Equal = pm25EqualList.stream() .map(String::valueOf).collect(Collectors.joining(",")); StringBuilder builder = new StringBuilder(); if (pm25LowerList.size() != 0) { builder.append("有" + pm25LowerList.size() + "个县(市、区)PM2.5累计浓度低于中心城区,分别为:").append(pm25Lower); } if (pm25EqualList.size() != 0) { builder.append(pm25Equal + "" + pm25EqualList.size() + "个县(市、区)PM2.5累计浓度与中心城区持平,"); } if (pm25HigherList.size() != 0) { builder.append("有" + pm25HigherList.size() + "个县(市、区)PM2.5累计浓度高于中心城区,分别为:").append(pm25Higher); } String propertiesCurrentContrastPm25 = announcementProperties.getContrastPm25(); propertiesCurrentContrastPm25 = propertiesCurrentContrastPm25.replace("{month}", month) .replace("{cityName}", cityName) .replace("{PM2_5}", pm25 == null ? "_" : pm25.toString()) .replace("{areaSize}", areaSize + "") .replace("{details}", builder.toString().equals("") ? "_" : builder.toString()); return propertiesCurrentContrastPm25; } /** * @param month 月份 * @param cityName 地级市名字 * @param result 当月数据map * @description PM2.5同比对比文字拼接 */ private String pm25YearOnYearContrastResponse(String month, String cityName, Integer areaSize, Map result) { Object pm25YearOnYear = result.get("PM2_5YearOnYear"); List pm25YearOnYearLowerList = (List) result.get("PM2_5YearOnYearLower"); List pm25YearOnYearHigherList = (List) result.get("PM2_5YearOnYearHigher"); List pm25YearOnYearEqualList = (List) result.get("PM2_5YearOnYearEqual"); List pm25YearOnYearLowerOfPositiveList = (List) result.get("pm25YearOnYearLowerOfPositive"); List pm25YearOnYearLowerOfNegativeList = (List) result.get("pm25YearOnYearLowerOfNegative"); List pm25YearOnYearLowerOfZeroList = (List) result.get("pm25YearOnYearLowerOfZero"); //PM2.5同比对比 String pm25YearOnYearHigher = pm25YearOnYearHigherList.stream() .map(String::valueOf).collect(Collectors.joining(",")); String pm25YearOnYearEqual = pm25YearOnYearEqualList.stream() .map(String::valueOf).collect(Collectors.joining(",")); String pm25YearOnYearLowerOfPositive = pm25YearOnYearLowerOfPositiveList.stream() .map(String::valueOf).collect(Collectors.joining(",")); String pm25YearOnYearLowerOfNegative = pm25YearOnYearLowerOfNegativeList.stream() .map(String::valueOf).collect(Collectors.joining(",")); StringBuilder builder = new StringBuilder(); if (pm25YearOnYearLowerList.size() != 0) { builder.append("有" + pm25YearOnYearLowerList.size() + "个县(市、区)PM2.5累计浓度同比改善幅度大于中心城区,"); if (pm25YearOnYearLowerOfNegativeList.size() != 0) { builder.append("其中有" + pm25YearOnYearLowerOfNegativeList.size() + "个县(市、区)PM2.5累计浓度同比下降,分别为:") .append(pm25YearOnYearLowerOfNegative); } if (pm25YearOnYearLowerOfZeroList.size() != 0) { builder.append("有" + pm25YearOnYearLowerOfZeroList.size() + "个县(市、区)PM2.5累计浓度同比持平,"); } if (pm25YearOnYearLowerOfPositiveList.size() != 0) { builder.append("有" + pm25YearOnYearLowerOfPositiveList.size() + "个县(市、区)PM2.5累计浓度同比上升,分别为:").append(pm25YearOnYearLowerOfPositive); } } if (pm25YearOnYearEqualList.size() != 0) { builder.append(pm25YearOnYearEqual + "" + pm25YearOnYearEqualList.size() + "个县(市、区)PM2.5累计浓度同比改善幅度与中心城区持平;"); } if (pm25YearOnYearHigherList.size() != 0) { builder.append("有" + pm25YearOnYearHigherList.size() + "个县(市、区)PM2.5累计浓度同比改善幅度小于中心城区,分别为:").append(pm25YearOnYearHigher); } String strPM25IndexYearOnYear = "_"; if (pm25YearOnYear != null) { if (pm25YearOnYear.toString().startsWith("-")) { strPM25IndexYearOnYear = pm25YearOnYear.toString().replace("-", "下降"); } else if (Double.parseDouble(pm25YearOnYear.toString().replace("%", "")) == 0d) { strPM25IndexYearOnYear = pm25YearOnYear.toString(); } else { strPM25IndexYearOnYear = "上升" + pm25YearOnYear; } } String currentContrastPm25YearOnYear = announcementProperties.getContrastPm25YearOnYear(); currentContrastPm25YearOnYear = currentContrastPm25YearOnYear.replace("{month}", month) .replace("{cityName}", cityName) .replace("{PM2_5YearOnYear}", strPM25IndexYearOnYear) .replace("{areaSize}", areaSize + "") .replace("{details}", builder.toString().equals("") ? "_" : builder.toString()); return currentContrastPm25YearOnYear; } /** * @param data 数据集合 * @param regionCode 当前地区编码 * @param rankField 排名字段 * @description 根据某字段获取排名 */ private Integer ranking(List data, Integer regionCode, String rankField) { Integer rank = null; data = data.stream().sorted((o1, o2) -> { Map map1 = JSONObject.parseObject(o1.getValue(), Map.class); Map map2 = JSONObject.parseObject(o2.getValue(), Map.class); Object b1 = map1.get(rankField); Object b2 = map2.get(rankField); if (b1 != null && b2 != null) { double aDouble1 = Double.parseDouble(b1.toString().replace("%", "")); double aDouble2 = Double.parseDouble(b2.toString().replace("%", "")); return aDouble1 > aDouble2 ? 1 : -1; } else if (b1 == null && b2 == null) { return 0; } else if (b1 == null) { return -1; } else { return 1; } }).collect(Collectors.toList()); for (int i = 0; i < data.size(); i++) { Integer cityCode = data.get(i).getCityCode(); if (cityCode.equals(regionCode)) { Map map = JSONObject.parseObject(data.get(i).getValue(), Map.class); if (map.get(rankField) != null) { rank = i + 1; } break; } } return rank; } /** * @param regionCode 地区编码 * @param time 时间 * @description 本市在168城市中排名情况 */ private Map getOneSixEightCitiesRanking(Integer regionCode, Date time) { Map result = new HashMap<>(); if (specialCitiesProperties.isOneSixEightCities(regionCode)) { QueryWrapper queryWrapper = new QueryWrapper<>(); List oneSixEightCities = specialCitiesProperties.getOneSixEightCities(); List oneSixEightCitiesCodes = oneSixEightCities.stream() .map(SysArea::getAreaCode) .collect(Collectors.toList()); //获取168城市数据 queryWrapper.clear(); queryWrapper.select("city_code", "value") .eq("time", time) .in("city_code", oneSixEightCitiesCodes); List monthlyData168 = cityAqiMonthlyMapper.selectList(queryWrapper); //综指168城市排名 Integer compositeIndexRank = ranking(monthlyData168, regionCode, "compositeIndex"); //综指同比168城市排名 Integer compositeIndexYearOnYearRank = ranking(monthlyData168, regionCode, "compositeIndex_yearOnYear"); //PM2.5浓度168城市排名 Integer pm25Rank = ranking(monthlyData168, regionCode, "PM2_5"); //PM2.5浓度同比168城市排名 Integer pm25YearOnYearRank = ranking(monthlyData168, regionCode, "PM2_5_yearOnYear"); //存入结果集 result.put("compositeIndex_rank_168", compositeIndexRank == null ? "_" : compositeIndexRank); result.put("compositeIndex_yearOnYear_rank_168", compositeIndexYearOnYearRank == null ? "_" : compositeIndexYearOnYearRank); result.put("PM2_5_rank_168", pm25Rank == null ? "_" : pm25Rank); result.put("PM2_5_yearOnYear_rank_168", pm25YearOnYearRank == null ? "_" : pm25YearOnYearRank); } return result; } //1-x月168城市排名 private Map getOneSixEightCitiesRankingOfCumulative(Integer regionCode, Date time) { Map result = new HashMap<>(); if (specialCitiesProperties.isOneSixEightCities(regionCode)) { List oneSixEightCities = specialCitiesProperties.getOneSixEightCities(); List oneSixEightCitiesCodes = oneSixEightCities.stream() .map(SysArea::getAreaCode) .collect(Collectors.toList()); //168城市1-x月累计 Map> cumulative168Result = getMonthlyCumulativeResult(time, oneSixEightCitiesCodes); List cumulativeData168 = new ArrayList<>(); for (Map.Entry> entry : cumulative168Result.entrySet()) { CityAqiMonthly cityAqiMonthly = new CityAqiMonthly(); Integer cityCode = entry.getKey(); Map value = entry.getValue(); cityAqiMonthly.setCityCode(cityCode); cityAqiMonthly.setValue(JSONObject.toJSONString(value)); cumulativeData168.add(cityAqiMonthly); } //综指168城市排名 Integer compositeIndexRank = ranking(cumulativeData168, regionCode, "compositeIndex"); //综指同比168城市排名 Integer compositeIndexYearOnYearRank = ranking(cumulativeData168, regionCode, "compositeIndex_yearOnYear"); //PM2.5浓度168城市排名 Integer pm25Rank = ranking(cumulativeData168, regionCode, "PM2_5"); //PM2.5浓度同比168城市排名 Integer pm25YearOnYearRank = ranking(cumulativeData168, regionCode, "PM2_5_yearOnYear"); //存入结果集 result.put("compositeIndex_rank_168", compositeIndexRank == null ? "_" : compositeIndexRank); result.put("compositeIndex_yearOnYear_rank_168", compositeIndexYearOnYearRank == null ? "_" : compositeIndexYearOnYearRank); result.put("PM2_5_rank_168", pm25Rank == null ? "_" : pm25Rank); result.put("PM2_5_yearOnYear_rank_168", pm25YearOnYearRank == null ? "_" : pm25YearOnYearRank); } return result; } //1-x月2+26城市排名 private Map getTwentyEightCitiesRankingOfCumulative(Integer regionCode, Date time) { Map result = new HashMap<>(); if (specialCitiesProperties.isTwentyEightCities(regionCode)) { List twentyCities = specialCitiesProperties.getTwentyEightCities(); List twentyCitiesCodes = twentyCities.stream() .map(SysArea::getAreaCode) .collect(Collectors.toList()); //168城市1-x月累计 Map> cumulative168Result = getMonthlyCumulativeResult(time, twentyCitiesCodes); List cumulativeData168 = new ArrayList<>(); for (Map.Entry> entry : cumulative168Result.entrySet()) { CityAqiMonthly cityAqiMonthly = new CityAqiMonthly(); Integer cityCode = entry.getKey(); Map value = entry.getValue(); cityAqiMonthly.setCityCode(cityCode); cityAqiMonthly.setValue(JSONObject.toJSONString(value)); cumulativeData168.add(cityAqiMonthly); } //综指168城市排名 Integer compositeIndexRank = ranking(cumulativeData168, regionCode, "compositeIndex"); //综指同比168城市排名 Integer compositeIndexYearOnYearRank = ranking(cumulativeData168, regionCode, "compositeIndex_yearOnYear"); //PM2.5浓度168城市排名 Integer pm25Rank = ranking(cumulativeData168, regionCode, "PM2_5"); //PM2.5浓度同比168城市排名 Integer pm25YearOnYearRank = ranking(cumulativeData168, regionCode, "PM2_5_yearOnYear"); //存入结果集 result.put("compositeIndex_rank_28", compositeIndexRank == null ? "_" : compositeIndexRank); result.put("compositeIndex_yearOnYear_rank_28", compositeIndexYearOnYearRank == null ? "_" : compositeIndexYearOnYearRank); result.put("PM2_5_rank_28", pm25Rank == null ? "_" : pm25Rank); result.put("PM2_5_yearOnYear_rank_28", pm25YearOnYearRank == null ? "_" : pm25YearOnYearRank); } return result; } //1-x月河北八通道城市排名 private Map getHeBeiEightCitiesRankingOfCumulative(Integer regionCode, Date time) { Map result = new HashMap<>(); if (specialCitiesProperties.isHeBeiEightCities(regionCode)) { List heBeiEightCities = specialCitiesProperties.getHeBeiEightCities(); List heBeiEightCitiesCodes = heBeiEightCities.stream() .map(SysArea::getAreaCode) .collect(Collectors.toList()); //168城市1-x月累计 Map> cumulative168Result = getMonthlyCumulativeResult(time, heBeiEightCitiesCodes); List cumulativeData168 = new ArrayList<>(); for (Map.Entry> entry : cumulative168Result.entrySet()) { CityAqiMonthly cityAqiMonthly = new CityAqiMonthly(); Integer cityCode = entry.getKey(); Map value = entry.getValue(); cityAqiMonthly.setCityCode(cityCode); cityAqiMonthly.setValue(JSONObject.toJSONString(value)); cumulativeData168.add(cityAqiMonthly); } //综指168城市排名 Integer compositeIndexRank = ranking(cumulativeData168, regionCode, "compositeIndex"); //综指同比168城市排名 Integer compositeIndexYearOnYearRank = ranking(cumulativeData168, regionCode, "compositeIndex_yearOnYear"); //PM2.5浓度168城市排名 Integer pm25Rank = ranking(cumulativeData168, regionCode, "PM2_5"); //PM2.5浓度同比168城市排名 Integer pm25YearOnYearRank = ranking(cumulativeData168, regionCode, "PM2_5_yearOnYear"); //存入结果集 result.put("compositeIndex_rank_8channels", compositeIndexRank == null ? "_" : compositeIndexRank); result.put("compositeIndex_YearOnYear_rank_8channels", compositeIndexYearOnYearRank == null ? "_" : compositeIndexYearOnYearRank); result.put("PM2_5_rank_8channels", pm25Rank == null ? "_" : pm25Rank); result.put("PM2_5_yearOnYear_rank_8channels", pm25YearOnYearRank == null ? "_" : pm25YearOnYearRank); } return result; } /** * @param regionCode 地区编码 * @param time 时间 * @description 本市在2+26城市中排名情况 */ private Map getTwentyEightCitiesRanking(Integer regionCode, Date time) { Map result = new HashMap<>(); if (specialCitiesProperties.isTwentyEightCities(regionCode)) { QueryWrapper queryWrapper = new QueryWrapper<>(); List twentyEightCities = specialCitiesProperties.getTwentyEightCities(); List twentyEightCitiesCodes = twentyEightCities.stream() .map(SysArea::getAreaCode) .collect(Collectors.toList()); //获取2+26城市数据 queryWrapper.select("city_code", "value") .eq("time", time) .in("city_code", twentyEightCitiesCodes); List monthlyData28 = cityAqiMonthlyMapper.selectList(queryWrapper); //综指2+26城市排名 Integer compositeIndexRank = ranking(monthlyData28, regionCode, "compositeIndex"); //综指同比2+26城市排名 Integer compositeIndexYearOnYearRank = ranking(monthlyData28, regionCode, "compositeIndex_yearOnYear"); //PM2.5浓度2+26城市排名 Integer pm25Rank = ranking(monthlyData28, regionCode, "PM2_5"); //PM2.5浓度同比2+26城市排名 Integer pm25YearOnYearRank = ranking(monthlyData28, regionCode, "PM2_5_yearOnYear"); //存入结果集 result.put("compositeIndex_rank_28", compositeIndexRank == null ? "_" : compositeIndexRank); result.put("compositeIndex_yearOnYear_rank_28", compositeIndexYearOnYearRank == null ? "_" : compositeIndexYearOnYearRank); result.put("PM2_5_rank_28", pm25Rank == null ? "_" : pm25Rank); result.put("PM2_5_yearOnYear_rank_28", pm25YearOnYearRank == null ? "_" : pm25YearOnYearRank); } return result; } /** * @param regionCode 地区编码 * @param time 时间 * @description 本市在河北八通道城市中排名情况 */ private Map getHeBeiEightCitiesRanking(Integer regionCode, Date time) { Map result = new HashMap<>(); if (specialCitiesProperties.isHeBeiEightCities(regionCode)) { QueryWrapper queryWrapper = new QueryWrapper<>(); List heBeiEightCities = specialCitiesProperties.getHeBeiEightCities(); List heBeiEightCitiesCodes = heBeiEightCities.stream() .map(SysArea::getAreaCode) .collect(Collectors.toList()); //获取2+26城市数据 queryWrapper.select("city_code", "value") .eq("time", time) .in("city_code", heBeiEightCitiesCodes); List monthlyData8Channels = cityAqiMonthlyMapper.selectList(queryWrapper); //综指八通道城市排名 Integer compositeIndexRank = ranking(monthlyData8Channels, regionCode, "compositeIndex"); //综指同比八通道城市排名 Integer compositeIndexYearOnYearRank = ranking(monthlyData8Channels, regionCode, "compositeIndex_yearOnYear"); //PM2.5浓度八通道城市排名 Integer pm25Rank = ranking(monthlyData8Channels, regionCode, "PM2_5"); //PM2.5浓度同比八通道城市排名 Integer pm25YearOnYearRank = ranking(monthlyData8Channels, regionCode, "PM2_5_yearOnYear"); //存入结果集 result.put("compositeIndex_rank_8channels", compositeIndexRank == null ? "_" : compositeIndexRank); result.put("compositeIndex_yearOnYear_rank_8channels", compositeIndexYearOnYearRank == null ? "_" : compositeIndexYearOnYearRank); result.put("PM2_5_rank_8channels", pm25Rank == null ? "_" : pm25Rank); result.put("PM2_5_yearOnYear_rank_8channels", pm25YearOnYearRank == null ? "_" : pm25YearOnYearRank); } return result; } /** * @param areasMap 所有县市区信息 areaCode--areaName * @param areaData 所有县市区数据 * @param compositeIndex 中心城区(地级市)综指 * @param compositeIndexYearOnYear 中心城区(地级市)综指同比 * @param pm25 中心城区(地级市)pm.5浓度 * @param pm25YearOnYear 中心城区(地级市)pm2.5同比 * @description 获取本期所有县市区与中心城区(地级市)因子对比情况 */ private Map getAreaCurrentMonthResult(Map areasMap, List areaData, Double compositeIndex, String compositeIndexYearOnYear, Double pm25, String pm25YearOnYear) { Map result = new HashMap<>(); result.put("compositeIndex", compositeIndex); result.put("compositeIndexYearOnYear", compositeIndexYearOnYear); result.put("PM2_5", null); if (pm25 != null) { result.put("PM2_5", pm25 + "ug/m³"); } result.put("PM2_5YearOnYear", pm25YearOnYear); //综指低于中心城区(地级市)集合 List compositeIndexLowerList = new ArrayList<>(); //综指高于中心城区(地级市)集合 List compositeIndexHigherList = new ArrayList<>(); //综指等于中心城区(地级市)集合 List compositeIndexEqualList = new ArrayList<>(); //综指同比低于中心城区(地级市)集合 List compositeIndexYearOnYearLowerList = new ArrayList<>(); //综指同比高于中心城区(地级市)集合 List compositeIndexYearOnYearHigherList = new ArrayList<>(); //综指同比等于中心城区(地级市)集合 List compositeIndexYearOnYearEqualList = new ArrayList<>(); //综指同比高于于中心城区(地级市)的地区中综指同比为正的 List compositeIndexYearOnYearHigherOfPositiveList = new ArrayList<>(); //综指同比高于于中心城区(地级市)的地区中综指同比为负的 List compositeIndexYearOnYearHigherOfNegativeList = new ArrayList<>(); //综指同比高于于中心城区(地级市)的地区中综指同比为0的 List compositeIndexYearOnYearHigherOfZeroList = new ArrayList<>(); //pm2.5低于中心城区(地级市)集合 List pm25LowerList = new ArrayList<>(); //pm2.5高于中心城区(地级市)集合 List pm25HigherList = new ArrayList<>(); //pm2.5等于中心城区(地级市)集合 List pm25EqualList = new ArrayList<>(); //pm2.5同比低于中心城区(地级市)集合 List pm25YearOnYearLowerList = new ArrayList<>(); //pm2.5同比高于于中心城区(地级市)集合 List pm25YearOnYearHigherList = new ArrayList<>(); ///pm2.5同比等于中心城区(地级市)集合 List pm25YearOnYearEqualList = new ArrayList<>(); //pm2.5同比低于于中心城区(地级市)的地区中综指同比为正的 List pm25YearOnYearLowerOfPositiveList = new ArrayList<>(); //pm2.5同比低于于中心城区(地级市)的地区中综指同比为负的 List pm25YearOnYearLowerOfNegativeList = new ArrayList<>(); //pm2.5同比低于于中心城区(地级市)的地区中综指同比0的 List pm25YearOnYearLowerOfZeroList = new ArrayList<>(); Double cityCompositeIndexYearOnYear = null; if (compositeIndexYearOnYear != null) { cityCompositeIndexYearOnYear = Double.parseDouble(compositeIndexYearOnYear.replace("%", "")); } Double citypm25YearOnYear = null; if (pm25YearOnYear != null) { citypm25YearOnYear = Double.parseDouble(pm25YearOnYear.replace("%", "")); } for (CityAqiMonthly areaDatum : areaData) { Integer areaCode = areaDatum.getCityCode(); Map valueMap = JSONObject.parseObject(areaDatum.getValue(), Map.class); double compositeIndexValue = Double.parseDouble(valueMap.get("compositeIndex").toString()); Double compositeIndexYearOnYearValue = null; if (valueMap.get("compositeIndex_yearOnYear") != null) { compositeIndexYearOnYearValue = Double.parseDouble(valueMap.get("compositeIndex_yearOnYear").toString().replace("%", "")); } int pm25Value = (int) Double.parseDouble(valueMap.get("PM2_5").toString()); Double pm25YearOnYearValue = null; if (valueMap.get("PM2_5_yearOnYear") != null) { pm25YearOnYearValue = Double.parseDouble(valueMap.get("PM2_5_yearOnYear").toString().replace("%", "")); } String areaName = areasMap.get(areaCode); if (compositeIndexValue < compositeIndex) { compositeIndexLowerList.add(areaName + "(" + compositeIndexValue + ")"); } else if (compositeIndexValue > compositeIndex) { compositeIndexHigherList.add(areaName + "(" + compositeIndexValue + ")"); } else { compositeIndexEqualList.add(areaName + "(" + compositeIndexValue + ")"); } if (cityCompositeIndexYearOnYear != null && compositeIndexYearOnYearValue != null) { String compositeIndex_yearOnYear = valueMap.get("compositeIndex_yearOnYear").toString(); if (compositeIndexYearOnYearValue > 0d) { compositeIndex_yearOnYear = "上升" + compositeIndex_yearOnYear; } else if (compositeIndexYearOnYearValue < 0d) { compositeIndex_yearOnYear = compositeIndex_yearOnYear.replace("-", "下降"); } if (compositeIndexYearOnYearValue > cityCompositeIndexYearOnYear) { compositeIndexYearOnYearHigherList.add(areaName + "(" + compositeIndex_yearOnYear + ")"); if (compositeIndexYearOnYearValue > 0) { compositeIndexYearOnYearHigherOfPositiveList.add(areaName + "(" + compositeIndex_yearOnYear + ")"); } else if (compositeIndexYearOnYearValue < 0) { compositeIndexYearOnYearHigherOfNegativeList.add(areaName + "(" + compositeIndex_yearOnYear + ")"); } else { compositeIndexYearOnYearHigherOfZeroList.add(areaName + "(" + compositeIndex_yearOnYear + ")"); } } else if (compositeIndexYearOnYearValue < cityCompositeIndexYearOnYear) { compositeIndexYearOnYearLowerList.add(areaName + "(" + compositeIndex_yearOnYear + ")"); } else { compositeIndexYearOnYearEqualList.add(areaName + "(" + compositeIndex_yearOnYear + ")"); } } if (pm25Value < pm25) { pm25LowerList.add(areaName + "(" + pm25Value + "ug/m³)"); } else if (pm25Value > pm25) { pm25HigherList.add(areaName + "(" + pm25Value + "ug/m³)"); } else { pm25EqualList.add(areaName + "(" + pm25Value + "ug/m³)"); } if (citypm25YearOnYear != null && pm25YearOnYearValue != null) { String pm2_5_yearOnYear = valueMap.get("PM2_5_yearOnYear").toString(); if (pm25YearOnYearValue > 0d) { pm2_5_yearOnYear = "上升" + pm2_5_yearOnYear; } else if (pm25YearOnYearValue < 0d) { pm2_5_yearOnYear = pm2_5_yearOnYear.replace("-", "下降"); } if (pm25YearOnYearValue < citypm25YearOnYear) { pm25YearOnYearLowerList.add(areaName + "(" + pm2_5_yearOnYear + ")"); if (pm25YearOnYearValue > 0) { pm25YearOnYearLowerOfPositiveList.add(areaName + "(" + pm2_5_yearOnYear + ")"); } else if (pm25YearOnYearValue < 0) { pm25YearOnYearLowerOfNegativeList.add(areaName + "(" + pm2_5_yearOnYear + ")"); } else { pm25YearOnYearLowerOfZeroList.add(areaName + "(" + pm2_5_yearOnYear + ")"); } } else if (pm25YearOnYearValue > citypm25YearOnYear) { pm25YearOnYearHigherList.add(areaName + "(" + pm2_5_yearOnYear + ")"); } else { pm25YearOnYearEqualList.add(areaName + "(" + pm2_5_yearOnYear + ")"); } } } result.put("compositeIndexLower", compositeIndexLowerList); result.put("compositeIndexHigher", compositeIndexHigherList); result.put("compositeIndexEqual", compositeIndexEqualList); result.put("compositeIndexYearOnYearHigher", compositeIndexYearOnYearHigherList); result.put("compositeIndexYearOnYearLower", compositeIndexYearOnYearLowerList); result.put("compositeIndexYearOnYearEqual", compositeIndexYearOnYearEqualList); result.put("compositeIndexYearOnYearHigherOfPositive", compositeIndexYearOnYearHigherOfPositiveList); result.put("compositeIndexYearOnYearHigherOfNegative", compositeIndexYearOnYearHigherOfNegativeList); result.put("compositeIndexYearOnYearHigherOfZero", compositeIndexYearOnYearHigherOfZeroList); result.put("PM2_5Lower", pm25LowerList); result.put("PM2_5Higher", pm25HigherList); result.put("PM2_5Equal", pm25EqualList); result.put("PM2_5YearOnYearHigher", pm25YearOnYearHigherList); result.put("PM2_5YearOnYearLower", pm25YearOnYearLowerList); result.put("PM2_5YearOnYearEqual", pm25YearOnYearEqualList); result.put("pm25YearOnYearLowerOfPositive", pm25YearOnYearLowerOfPositiveList); result.put("pm25YearOnYearLowerOfNegative", pm25YearOnYearLowerOfNegativeList); result.put("pm25YearOnYearLowerOfZero", pm25YearOnYearLowerOfZeroList); return result; } //1-x月累计结果 public Map> getMonthlyCumulativeResult(Date time, List regionCodes) { //开始时间,当年1月1日 Date start = DateUtils.getFirstDayOfYear(time); //结束时间,当月最后一天 Date end = DateUtils.getLastDayOfMonth(time); //获取所有地区当年1-x月的日数据 QueryWrapper cityAqiDailyQueryWrapper = new QueryWrapper<>(); cityAqiDailyQueryWrapper.select("city_code", "value") .ge("time", start) .le("time", end) .in("city_code", regionCodes); List cityAqiDailyList = cityAqiDailyService.list(cityAqiDailyQueryWrapper); if (cityAqiDailyList.size() == 0) { return null; } Map> currentMap = getMonthCumulative(cityAqiDailyList); //获取所有地区上年1-x月的日数据,用于计算同比 cityAqiDailyQueryWrapper.clear(); cityAqiDailyQueryWrapper.select("city_code", "value") .ge("time", DateUtils.addYears(start, -1)) .le("time", DateUtils.addYears(end, -1)) .in("city_code", regionCodes); List lastCityAqiDailyList = cityAqiDailyService.list(cityAqiDailyQueryWrapper); Map> lastMap = getMonthCumulative(lastCityAqiDailyList); //计算各因子同比 for (Map.Entry> entry : currentMap.entrySet()) { Integer regionCode = entry.getKey(); Map current = entry.getValue(); Map last = lastMap.get(regionCode); Map map = yearOnYearOfSensor(last, current); if (map != null) { currentMap.put(regionCode, yearOnYearOfSensor(last, current)); } } return currentMap; } /** * @param last 上年数据 * @param current 当前数据 * @description 计算各因子同比 */ private Map yearOnYearOfSensor(Map last, Map current) { if (last == null) { return null; } //需要计算同比的因子 List sensors = Arrays.asList("PM2_5", "PM10", "SO2", "NO2", "CO", "O3", "compositeIndex"); for (String sensor : sensors) { //上年本月该因子值 double lastValue = Double.parseDouble(last.get(sensor).toString()); //当前该因子值 double currentValue = Double.parseDouble(current.get(sensor).toString()); DecimalFormat decimalFormat = new DecimalFormat("0.00%"); String format = decimalFormat.format((currentValue - lastValue) / lastValue); current.put(sensor + "_yearOnYear", format); current.put(sensor + "_last", lastValue); } return current; } /** * @param data 各个地区的数据集合 * @description 计算1-x月各因子均值 */ private Map> getMonthCumulative(List data) { Map> result = new HashMap<>(); //需要均值计算的因子 List sensors = Arrays.asList("PM2_5", "PM10", "SO2", "NO2"); //按city_code分组 Map> cityDataMap = data.stream() .collect(Collectors.groupingBy(CityAqiDaily::getCityCode)); //1-x月均值计算 cityDataMap.forEach((cityCode, list) -> { Map jsonMap = new HashMap<>(); Map params = new HashMap<>(); List> temp = new ArrayList<>(); for (CityAqiDaily cityAqiDaily : list) { Map valueMap = JSONObject.parseObject(cityAqiDaily.getValue(), Map.class); Map tempMap = new HashMap<>(); Map hashMap = new HashMap<>(); tempMap.put(Constants.SENSOR_CODE_CO, valueMap.get("CO")); tempMap.put(Constants.SENSOR_CODE_O3, valueMap.get("O3")); hashMap.put("value", JSONObject.toJSONString(tempMap)); temp.add(hashMap); } params.put("data", temp); //1. CO 95百分位计算并修约 Map coAvgOfWeekOrMonth = AmendUtils.getCOAvgOfWeekOrMonth(params); if (!ObjectUtils.isEmpty(coAvgOfWeekOrMonth)) { jsonMap.put("CO", coAvgOfWeekOrMonth.get(Constants.SENSOR_CODE_CO)); } //2. O3 90百分位计算并修约 Map o3AvgOfWeekOrMonth = AmendUtils.getO3AvgOfWeekOrMonth(params); if (!ObjectUtils.isEmpty(o3AvgOfWeekOrMonth)) { jsonMap.put("O3", o3AvgOfWeekOrMonth.get(Constants.SENSOR_CODE_O3)); } sensors.forEach(sensor -> { OptionalDouble optionalDouble = list.stream().flatMapToDouble(v -> { Map dataValue = JSONObject.parseObject(v.getValue(), Map.class); double aDouble = Double.parseDouble(dataValue.get(sensor).toString()); return DoubleStream.of(aDouble); }).average(); if (optionalDouble.isPresent()) { //银行家算法修约 jsonMap.put(sensor, AmendUtils.sciCal(optionalDouble.getAsDouble(), 0)); } }); //1-x月综指 Double compositeIndex = ComprehensiveIndexUtils.dailyData(jsonMap); jsonMap.put("compositeIndex", compositeIndex); result.put(cityCode, jsonMap); }); return result; } /** * 1.考核排名计算公式:(空气质量综合指数绝对值排名×20%+空气质量指数改善幅度排名×30%)+(PM2.5平均浓度绝对值排名×20%+PM2.5平均浓度改善幅度排名×30%)。 * 2.加权得分值越小,空气质量考核综合评价越好。 * 3.排名位次数值相加得分相同的情况下,优先按照PM2.5月均浓度值、改善幅度确定排名先后,平均浓度值低、下降幅度大的排名靠前。 * * @param list 所有县市区数据 * @param areasMap 所有县市区信息 areaCode--areaName * @description 本期综指和pm2.5考核排名报表 */ private List> airQualityRankingOfCurrentReport(List list, Map areasMap) { List> result = new ArrayList<>(); Map dataMap = new HashMap<>(); for (CityAqiMonthly cityAqiMonthly : list) { dataMap.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); } for (Map.Entry entry : areasMap.entrySet()) { Map resultMap = new HashMap<>(); Integer regionCode = entry.getKey(); String areaName = entry.getValue(); resultMap.put("areaName", areaName); //本期综指 resultMap.put("compositeIndex", null); //综指同比 resultMap.put("compositeIndexYearOnYear", null); //本期PM2.5 resultMap.put("PM2_5", null); //PM2.5同比 resultMap.put("PM2_5YearOnYear", null); if (dataMap.get(regionCode) != null) { Map valueMap = JSONObject.parseObject(dataMap.get(regionCode).getValue(), Map.class); resultMap.put("compositeIndex", valueMap.get("compositeIndex")); resultMap.put("compositeIndexYearOnYear", valueMap.get("compositeIndex_yearOnYear")); resultMap.put("PM2_5", valueMap.get("PM2_5")); resultMap.put("PM2_5YearOnYear", valueMap.get("PM2_5_yearOnYear")); } result.add(resultMap); } //1.按综指绝对值排名 result.sort((o1, o2) -> { if (o1.get("compositeIndex") != null && o2.get("compositeIndex") != null) { double compositeIndexAbs1 = Math.abs(Double.parseDouble(o1.get("compositeIndex").toString())); double compositeIndexAbs2 = Math.abs(Double.parseDouble(o2.get("compositeIndex").toString())); return compositeIndexAbs1 > compositeIndexAbs2 ? 1 : -1; } else if (o1.get("compositeIndex") == null && o2.get("compositeIndex") == null) { return 0; } else if (o1.get("compositeIndex") == null) { return -1; } else { return 1; } }); //放入排名字段 for (int i = 0; i < result.size(); i++) { Map map = result.get(i); map.put("compositeIndexRank", i + 1); } //2.按空气质量改善幅度(综指同比)排名 result.sort((o1, o2) -> { if (o1.get("compositeIndexYearOnYear") != null && o2.get("compositeIndexYearOnYear") != null) { double compositeIndexYearOnYear1 = Double.parseDouble(o1.get("compositeIndexYearOnYear").toString().replace("%", "")); double compositeIndexYearOnYear2 = Double.parseDouble(o2.get("compositeIndexYearOnYear").toString().replace("%", "")); return compositeIndexYearOnYear1 > compositeIndexYearOnYear2 ? 1 : -1; } else if (o1.get("compositeIndexYearOnYear") == null && o2.get("compositeIndexYearOnYear") == null) { return 0; } else if (o1.get("compositeIndexYearOnYear") == null) { return -1; } else { return 1; } }); //放入排名字段 for (int i = 0; i < result.size(); i++) { Map map = result.get(i); map.put("compositeIndexYearOnYearRank", i + 1); } //3.按pm2.5浓度绝对值排名 result.sort((o1, o2) -> { if (o1.get("PM2_5") != null && o2.get("PM2_5") != null) { double compositeIndexAbs1 = Math.abs(Double.parseDouble(o1.get("PM2_5").toString())); double compositeIndexAbs2 = Math.abs(Double.parseDouble(o2.get("PM2_5").toString())); return compositeIndexAbs1 > compositeIndexAbs2 ? 1 : -1; } else if (o1.get("PM2_5") == null && o2.get("PM2_5") == null) { return 0; } else if (o1.get("PM2_5") == null) { return -1; } else { return 1; } }); //放入排名字段 for (int i = 0; i < result.size(); i++) { Map map = result.get(i); map.put("PM2_5Rank", i + 1); } //4.按pm2.5改善幅度排名 result.sort((o1, o2) -> { if (o1.get("PM2_5YearOnYear") != null && o2.get("PM2_5YearOnYear") != null) { double pm25YearOnYear1 = Double.parseDouble(o1.get("PM2_5YearOnYear").toString().replace("%", "")); double pm25YearOnYear2 = Double.parseDouble(o2.get("PM2_5YearOnYear").toString().replace("%", "")); return pm25YearOnYear1 > pm25YearOnYear2 ? 1 : -1; } else if (o1.get("PM2_5YearOnYear") == null && o2.get("PM2_5YearOnYear") == null) { return 0; } else if (o1.get("PM2_5YearOnYear") == null) { return -1; } else { return 1; } }); //放入排名字段 for (int i = 0; i < result.size(); i++) { Map map = result.get(i); map.put("PM2_5YearOnYearRank", i + 1); } //加权得分计算 for (Map map : result) { int compositeIndexRank = Integer.parseInt(map.get("compositeIndexRank").toString()); int compositeIndexYearOnYearRank = Integer.parseInt(map.get("compositeIndexYearOnYearRank").toString()); int pm25Rank = Integer.parseInt(map.get("PM2_5Rank").toString()); int pm25YearOnYearRank = Integer.parseInt(map.get("PM2_5YearOnYearRank").toString()); double score = compositeIndexRank * 0.2 + compositeIndexYearOnYearRank * 0.3 + pm25Rank * 0.2 + pm25YearOnYearRank * 0.3; String format = String.format("%.1f", score); map.put("score", Double.parseDouble(format)); } //最终排序 result.sort((o1, o2) -> { double score1 = Double.parseDouble(o1.get("score").toString()); double score2 = Double.parseDouble(o2.get("score").toString()); if (score1 > score2) { return 1; } else if (score1 < score2) { return -1; } //排名位次数值相加得分相同的情况下,优先按照PM2.5月均浓度值、改善幅度确定排名先后,平均浓度值低、下降幅度大的排名靠前。 int pm251 = Integer.parseInt(o1.get("PM2_5").toString()); int pm252 = Integer.parseInt(o2.get("PM2_5").toString()); if (pm251 > pm252) { return 1; } else if (pm251 < pm252) { return -1; } //pm2.5浓度相同,再按照改善幅度排名 double pm25YearOnYear1 = Double.parseDouble(o1.get("PM2_5YearOnYearRank").toString().replace("%", "")); double pm25YearOnYear2 = Double.parseDouble(o2.get("PM2_5YearOnYearRank").toString().replace("%", "")); return pm25YearOnYear1 > pm25YearOnYear2 ? 1 : -1; }); //放入最终排名字段 for (int i = 0; i < result.size(); i++) { Map map = result.get(i); map.put("resultRank", i + 1); } for (Map map : result) { for (Map.Entry entry : map.entrySet()) { if (entry.getValue() == null) { map.put(entry.getKey(), ""); } } } return result; } /** * @param list 所有县市区1-x月份数据 * @param areasMap 所有县市区信息 areaCode--areaName * @description 1-x月份累计空气质量综指和pm2.5排名报表 */ private List> cumulativeAirQualityRankingReport(List list, Map areasMap) { List> result = new ArrayList<>(); Map dataMap = new HashMap<>(); for (CityAqiMonthly cityAqiMonthly : list) { dataMap.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); } for (Map.Entry entry : areasMap.entrySet()) { Map resultMap = new HashMap<>(); Integer regionCode = entry.getKey(); String areaName = entry.getValue(); resultMap.put("areaName", areaName); //本期综指 resultMap.put("compositeIndex", null); //上期综指 resultMap.put("compositeIndexLast", null); //综指同比 resultMap.put("compositeIndexYearOnYear", null); //本期PM2.5 resultMap.put("PM2_5", null); //上期PM2.5 resultMap.put("PM2_5Last", null); //PM2.5同比 resultMap.put("PM2_5YearOnYear", null); if (dataMap.get(regionCode) != null) { Map valueMap = JSONObject.parseObject(dataMap.get(regionCode).getValue(), Map.class); //综指本期,上期,同比 resultMap.put("compositeIndex", valueMap.get("compositeIndex")); resultMap.put("compositeIndexLast", valueMap.get("compositeIndex_last")); resultMap.put("compositeIndexYearOnYear", valueMap.get("compositeIndex_yearOnYear")); //PM2.5本期,上期,同比 resultMap.put("PM2_5", valueMap.get("PM2_5")); resultMap.put("PM2_5Last", valueMap.get("PM2_5_last")); resultMap.put("PM2_5YearOnYear", valueMap.get("PM2_5_yearOnYear")); } result.add(resultMap); } //按pm2.5同比排名 result.sort((o1, o2) -> { if (o1.get("PM2_5YearOnYear") != null && o2.get("PM2_5YearOnYear") != null) { double pm25YearOnYear1 = Double.parseDouble(o1.get("PM2_5YearOnYear").toString().replace("%", "")); double pm25YearOnYear2 = Double.parseDouble(o2.get("PM2_5YearOnYear").toString().replace("%", "")); return pm25YearOnYear1 > pm25YearOnYear2 ? 1 : -1; } else if (o1.get("PM2_5YearOnYear") == null && o2.get("PM2_5YearOnYear") == null) { return 0; } else if (o1.get("PM2_5YearOnYear") == null) { return -1; } else { return 1; } }); //放入排名字段 for (int i = 0; i < result.size(); i++) { Map map = result.get(i); map.put("PM2_5YearOnYearRank", i + 1); } //按综指变化幅度排名 result.sort((o1, o2) -> { if (o1.get("compositeIndexYearOnYear") != null && o2.get("compositeIndexYearOnYear") != null) { double compositeIndexYearOnYear1 = Double.parseDouble(o1.get("compositeIndexYearOnYear").toString().replace("%", "")); double compositeIndexYearOnYear2 = Double.parseDouble(o2.get("compositeIndexYearOnYear").toString().replace("%", "")); return compositeIndexYearOnYear1 > compositeIndexYearOnYear2 ? 1 : -1; } else if (o1.get("compositeIndexYearOnYear") == null && o2.get("compositeIndexYearOnYear") == null) { return 0; } else if (o1.get("compositeIndexYearOnYear") == null) { return -1; } else { return 1; } }); //放入排名字段 for (int i = 0; i < result.size(); i++) { Map map = result.get(i); map.put("compositeIndexYearOnYearRank", i + 1); } for (Map map : result) { for (Map.Entry entry : map.entrySet()) { if (entry.getValue() == null) { map.put(entry.getKey(), ""); } } } return result; } /** * @param time 本期时间 * @param areaCodes 所有县市区code集合 * @param areaData 所有县市区本期数据 * @param areasMap 所有县市区信息 * @description 本期五因子(PM10,SO2,NO2,CO,O3)对比报表 */ private List> currentFiveSensorsContrastReport(Date time, List areaCodes, List areaData, Map areasMap) { List> result = new ArrayList<>(); //本期数据 Map dataCurrent = new HashMap<>(); for (CityAqiMonthly cityAqiMonthly : areaData) { dataCurrent.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); } //获取上年同期数据 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.clear(); queryWrapper.select("city_code", "value") .eq("time", DateUtils.addYears(time, -1)) .in("city_code", areaCodes); List monthlyDataLast = cityAqiMonthlyMapper.selectList(queryWrapper); Map dataLast = new HashMap<>(); for (CityAqiMonthly cityAqiMonthly : monthlyDataLast) { dataLast.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); } //报表中需要对比的五因子 List sensors = Arrays.asList("PM10", "SO2", "NO2", "CO", "O3"); for (Map.Entry entry : areasMap.entrySet()) { Map resultMap = new HashMap<>(); String areaName = entry.getValue(); Integer regionCode = entry.getKey(); resultMap.put("areaName", areaName); for (String sensor : sensors) { resultMap.put(sensor, null); resultMap.put(sensor + "YearOnYear", null); if (dataCurrent.get(regionCode) != null) { Map currentValue = JSONObject.parseObject(dataCurrent.get(regionCode).getValue(), Map.class); resultMap.put(sensor, currentValue.get(sensor)); resultMap.put(sensor + "YearOnYear", currentValue.get(sensor + "_yearOnYear")); } //上年同期五因子浓度 resultMap.put(sensor + "Last", null); if (dataLast.get(regionCode) != null) { Map lastValue = JSONObject.parseObject(dataLast.get(regionCode).getValue(), Map.class); //上年同期五因子浓度 resultMap.put(sensor + "Last", lastValue.get(sensor)); } } result.add(resultMap); } for (Map map : result) { for (Map.Entry entry : map.entrySet()) { if (entry.getValue() == null) { map.put(entry.getKey(), ""); } } } return result; } /** * @param areaData 所有县市区1-x月份数据,其中包含上年同期五因子浓度值 * @param areasMap 所有县市区信息 * @description 1-x月份五因子(PM10,SO2,NO2,CO,O3)对比报表 */ private List> cumulativeFiveSensorsContrastReport(List areaData, Map areasMap) { List> result = new ArrayList<>(); //本期数据 Map dataCurrent = new HashMap<>(); for (CityAqiMonthly cityAqiMonthly : areaData) { dataCurrent.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); } List sensors = Arrays.asList("PM10", "SO2", "NO2", "CO", "O3"); for (Map.Entry entry : areasMap.entrySet()) { Map resultMap = new HashMap<>(); String areaName = entry.getValue(); Integer regionCode = entry.getKey(); resultMap.put("areaName", areaName); for (String sensor : sensors) { resultMap.put(sensor, null); resultMap.put(sensor + "Last", null); resultMap.put(sensor + "YearOnYear", null); if (dataCurrent.get(regionCode) != null) { Map valueMap = JSONObject.parseObject(dataCurrent.get(regionCode).getValue(), Map.class); resultMap.put(sensor, valueMap.get(sensor)); resultMap.put(sensor + "Last", valueMap.get(sensor + "_last")); resultMap.put(sensor + "YearOnYear", valueMap.get(sensor + "_yearOnYear")); } } result.add(resultMap); } for (Map map : result) { for (Map.Entry entry : map.entrySet()) { if (entry.getValue() == null) { map.put(entry.getKey(), ""); } } } return result; } }