From fdbef2a3293e536be6b119e4e1e67cc8cc9842f0 Mon Sep 17 00:00:00 2001 From: jinpengyong <jpy123456> Date: Fri, 08 Apr 2022 08:55:29 +0800 Subject: [PATCH] 空气质量排名报告 --- screen-api/src/main/java/com/moral/api/service/impl/CityAqiMonthlyServiceImpl.java | 1601 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 1,592 insertions(+), 9 deletions(-) diff --git a/screen-api/src/main/java/com/moral/api/service/impl/CityAqiMonthlyServiceImpl.java b/screen-api/src/main/java/com/moral/api/service/impl/CityAqiMonthlyServiceImpl.java index 5806e82..d3822e4 100644 --- a/screen-api/src/main/java/com/moral/api/service/impl/CityAqiMonthlyServiceImpl.java +++ b/screen-api/src/main/java/com/moral/api/service/impl/CityAqiMonthlyServiceImpl.java @@ -1,18 +1,40 @@ 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.stereotype.Service; -import java.io.*; +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.ArrayList; +import java.util.Arrays; import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.OptionalDouble; +import java.util.stream.Collectors; +import java.util.stream.DoubleStream; /** * <p> @@ -26,23 +48,1584 @@ public class CityAqiMonthlyServiceImpl extends ServiceImpl<CityAqiMonthlyMapper, CityAqiMonthly> implements CityAqiMonthlyService { @Autowired - CityAqiMonthlyMapper cityAqiMonthlyMapper; + 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<CityAqiMonthly> getCityAqiMonthByRegionCodeAndTime(Integer regionCode, Date startDate, Date endDate) { QueryWrapper<CityAqiMonthly> queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("city_code",regionCode); - queryWrapper.between("time",startDate,endDate); + queryWrapper.eq("city_code", regionCode); + queryWrapper.between("time", startDate, endDate); return cityAqiMonthlyMapper.selectList(queryWrapper); } @Override - public CityAqiMonthly getCityAqiMonthByRegionCodeAndTime(Integer regionCode, Date time){ + public CityAqiMonthly getCityAqiMonthByRegionCodeAndTime(Integer regionCode, Date time) { time = DateUtils.getFirstDayOfMonth(time); QueryWrapper<CityAqiMonthly> queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("city_code",regionCode); - queryWrapper.eq("time",time); + queryWrapper.eq("city_code", regionCode); + queryWrapper.eq("time", time); return cityAqiMonthlyMapper.selectOne(queryWrapper); } + @Override + public Map<String, Object> airQualityRankingAnnouncement(Integer regionCode, Date time) { + Map<String, Object> 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<String, Object>) redisTemplate.opsForValue().get(RedisConstants.AQI_ANNOUNCEMENT + "_" + regionCode + "_" + DateUtils.dateToDateString(time, DateUtils.yyyyMM_EN)); + if (result != null) { + return result; + } + + result = new LinkedHashMap<>(); + //������xx��������������������������������� + QueryWrapper<SysArea> sysAreaQueryWrapper = new QueryWrapper<>(); + sysAreaQueryWrapper.select("area_code", "area_name") + .eq("parent_code", regionCode).or() + .eq("area_code", regionCode); + List<SysArea> sysAreas = sysAreaService.list(sysAreaQueryWrapper); + Map<Integer, String> 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<String, Object> currentRankingResult = new HashMap<>(); + + //������������xx��������������������� + QueryWrapper<CityAqiMonthly> cityAqiMonthlyQueryWrapper = new QueryWrapper<>(); + cityAqiMonthlyQueryWrapper.select("value") + .eq("city_code", regionCode) + .eq("time", time); + CityAqiMonthly cityAqiMonthly = cityAqiMonthlyMapper.selectOne(cityAqiMonthlyQueryWrapper); + Double compositeIndex = null; + String compositeIndexYearOnYear = null; + Integer pm25 = null; + String pm25YearOnYear = null; + if (cityAqiMonthly != null) { + Map<String, Object> 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 = Integer.parseInt(aqiMap.get("PM2_5").toString()); + } + 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<String, Object> ranking168 = getOneSixEightCitiesRanking(regionCode, time); + currentRankingResult.putAll(ranking168); + + //6.2+26���������������������������������������������pm2.5,pm2.5������ + Map<String, Object> ranking28 = getTwentyEightCitiesRanking(regionCode, time); + currentRankingResult.putAll(ranking28); + + //7.������������������������������������������������������������pm2.5,pm2.5������ + Map<String, Object> 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<Integer> areaCodes = new ArrayList<>(areasMap.keySet()); + //���������code + areaCodes.add(regionCode); + Map<Integer, Map<String, Object>> monthlyCumulativeResult = null; + Double cityCompositeIndex = null; + String cityCompositeIndexYearOnYear = null; + Integer cityPM25 = null; + String cityPM25YearOnYear = null; + if (!"1".equals(month)) { + Map<String, Object> cumulativeRankingResult = new HashMap<>(); + + //������xx���������������������������1-xx��������� + monthlyCumulativeResult = getMonthlyCumulativeResult(time, areaCodes); + //xx��������� + + if (monthlyCumulativeResult != null) { + Map<String, Object> 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 = (int) 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<String, Object> ranking168 = getOneSixEightCitiesRankingOfCumulative(regionCode, time); + cumulativeRankingResult.putAll(ranking168); + + //6.2+26���������������������������������������������pm2.5,pm2.5������ + Map<String, Object> ranking28 = getTwentyEightCitiesRankingOfCumulative(regionCode, time); + cumulativeRankingResult.putAll(ranking28); + + //7.������������������������������������������������������������pm2.5,pm2.5������ + Map<String, Object> 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<CityAqiMonthly> areaData = cityAqiMonthlyMapper.selectList(cityAqiMonthlyQueryWrapper); + + //��������������������������������������������������������������������������� + Map<String, Object> 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<CityAqiMonthly> cumulativeList = null; + if (!"1".equals(month)) { + cumulativeList = new ArrayList<>(); + if (monthlyCumulativeResult != null) { + for (Map.Entry<Integer, Map<String, Object>> 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<String, Object> 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<Map<String, Object>> airQualityRankingOfCurrentReport = airQualityRankingOfCurrentReport(areaData, areasMap); + result.put("currentAirQualityRankingReport", airQualityRankingOfCurrentReport); + + //2.1-x���������������������������������pm2.5������������ + if (!"1".equals(month)) { + List<Map<String, Object>> cumulativeAirQualityRankingReport = cumulativeAirQualityRankingReport(cumulativeList, areasMap); + result.put("cumulativeAirQualityRankingReport", cumulativeAirQualityRankingReport); + } + + + //3.������������������PM10,SO2,NO2,CO,O3��������������� + List<Map<String, Object>> currentFiveSensorsContrastReport = currentFiveSensorsContrastReport(time, areaCodes, areaData, areasMap); + result.put("currentFiveSensorsContrastReport", currentFiveSensorsContrastReport); + + + //4.1-x������������������PM10,SO2,NO2,CO,O3��������������� + if (!"1".equals(month)) { + List<Map<String, Object>> 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<String, Object> 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<String, Object> result) { + Object compositeIndex = result.get("compositeIndex"); + List<String> compositeIndexLowerList = (List<String>) result.get("compositeIndexLower"); + List<String> compositeIndexHigherList = (List<String>) result.get("compositeIndexHigher"); + List<String> compositeIndexEqualList = (List<String>) 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<String, Object> result) { + Object compositeIndexYearOnYear = result.get("compositeIndexYearOnYear"); + List<String> compositeIndexYearOnYearLowerList = (List<String>) result.get("compositeIndexYearOnYearLower"); + List<String> compositeIndexYearOnYearHigherList = (List<String>) result.get("compositeIndexYearOnYearHigher"); + List<String> compositeIndexYearOnYearEqualList = (List<String>) result.get("compositeIndexYearOnYearEqual"); + List<String> compositeIndexYearOnYearHigherOfPositiveList = (List<String>) result.get("compositeIndexYearOnYearHigherOfPositive"); + List<String> compositeIndexYearOnYearHigherOfNegativeList = (List<String>) result.get("compositeIndexYearOnYearHigherOfNegative"); + List<String> compositeIndexYearOnYearHigherOfZeroList = (List<String>) 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<String, Object> result) { + Object pm25 = result.get("PM2_5"); + List<String> pm25LowerList = (List<String>) result.get("PM2_5Lower"); + List<String> pm25HigherList = (List<String>) result.get("PM2_5Higher"); + List<String> pm25EqualList = (List<String>) 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<String, Object> result) { + Object pm25YearOnYear = result.get("PM2_5YearOnYear"); + + List<String> pm25YearOnYearLowerList = (List<String>) result.get("PM2_5YearOnYearLower"); + List<String> pm25YearOnYearHigherList = (List<String>) result.get("PM2_5YearOnYearHigher"); + List<String> pm25YearOnYearEqualList = (List<String>) result.get("PM2_5YearOnYearEqual"); + List<String> pm25YearOnYearLowerOfPositiveList = (List<String>) result.get("pm25YearOnYearLowerOfPositive"); + List<String> pm25YearOnYearLowerOfNegativeList = (List<String>) result.get("pm25YearOnYearLowerOfNegative"); + List<String> pm25YearOnYearLowerOfZeroList = (List<String>) 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<CityAqiMonthly> data, Integer regionCode, String rankField) { + Integer rank = null; + data = data.stream().sorted((o1, o2) -> { + Map<String, Object> map1 = JSONObject.parseObject(o1.getValue(), Map.class); + Map<String, Object> 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<String, Object> 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<String, Object> getOneSixEightCitiesRanking(Integer regionCode, Date time) { + Map<String, Object> result = new HashMap<>(); + + if (specialCitiesProperties.isOneSixEightCities(regionCode)) { + + QueryWrapper<CityAqiMonthly> queryWrapper = new QueryWrapper<>(); + List<SysArea> oneSixEightCities = specialCitiesProperties.getOneSixEightCities(); + List<Integer> 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<CityAqiMonthly> 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<String, Object> getOneSixEightCitiesRankingOfCumulative(Integer regionCode, Date time) { + Map<String, Object> result = new HashMap<>(); + + if (specialCitiesProperties.isOneSixEightCities(regionCode)) { + List<SysArea> oneSixEightCities = specialCitiesProperties.getOneSixEightCities(); + List<Integer> oneSixEightCitiesCodes = oneSixEightCities.stream() + .map(SysArea::getAreaCode) + .collect(Collectors.toList()); + + //168������1-x��������� + Map<Integer, Map<String, Object>> cumulative168Result = getMonthlyCumulativeResult(time, oneSixEightCitiesCodes); + List<CityAqiMonthly> cumulativeData168 = new ArrayList<>(); + for (Map.Entry<Integer, Map<String, Object>> entry : cumulative168Result.entrySet()) { + CityAqiMonthly cityAqiMonthly = new CityAqiMonthly(); + Integer cityCode = entry.getKey(); + Map<String, Object> 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<String, Object> getTwentyEightCitiesRankingOfCumulative(Integer regionCode, Date time) { + Map<String, Object> result = new HashMap<>(); + + if (specialCitiesProperties.isTwentyEightCities(regionCode)) { + List<SysArea> twentyCities = specialCitiesProperties.getTwentyEightCities(); + List<Integer> twentyCitiesCodes = twentyCities.stream() + .map(SysArea::getAreaCode) + .collect(Collectors.toList()); + + //168������1-x��������� + Map<Integer, Map<String, Object>> cumulative168Result = getMonthlyCumulativeResult(time, twentyCitiesCodes); + List<CityAqiMonthly> cumulativeData168 = new ArrayList<>(); + for (Map.Entry<Integer, Map<String, Object>> entry : cumulative168Result.entrySet()) { + CityAqiMonthly cityAqiMonthly = new CityAqiMonthly(); + Integer cityCode = entry.getKey(); + Map<String, Object> 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<String, Object> getHeBeiEightCitiesRankingOfCumulative(Integer regionCode, Date time) { + Map<String, Object> result = new HashMap<>(); + + if (specialCitiesProperties.isHeBeiEightCities(regionCode)) { + List<SysArea> heBeiEightCities = specialCitiesProperties.getHeBeiEightCities(); + List<Integer> heBeiEightCitiesCodes = heBeiEightCities.stream() + .map(SysArea::getAreaCode) + .collect(Collectors.toList()); + + //168������1-x��������� + Map<Integer, Map<String, Object>> cumulative168Result = getMonthlyCumulativeResult(time, heBeiEightCitiesCodes); + List<CityAqiMonthly> cumulativeData168 = new ArrayList<>(); + for (Map.Entry<Integer, Map<String, Object>> entry : cumulative168Result.entrySet()) { + CityAqiMonthly cityAqiMonthly = new CityAqiMonthly(); + Integer cityCode = entry.getKey(); + Map<String, Object> 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<String, Object> getTwentyEightCitiesRanking(Integer regionCode, Date time) { + Map<String, Object> result = new HashMap<>(); + + if (specialCitiesProperties.isTwentyEightCities(regionCode)) { + + QueryWrapper<CityAqiMonthly> queryWrapper = new QueryWrapper<>(); + List<SysArea> twentyEightCities = specialCitiesProperties.getTwentyEightCities(); + List<Integer> twentyEightCitiesCodes = twentyEightCities.stream() + .map(SysArea::getAreaCode) + .collect(Collectors.toList()); + //������2+26������������ + queryWrapper.select("city_code", "value") + .eq("time", time) + .in("city_code", twentyEightCitiesCodes); + List<CityAqiMonthly> 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<String, Object> getHeBeiEightCitiesRanking(Integer regionCode, Date time) { + Map<String, Object> result = new HashMap<>(); + + if (specialCitiesProperties.isHeBeiEightCities(regionCode)) { + QueryWrapper<CityAqiMonthly> queryWrapper = new QueryWrapper<>(); + List<SysArea> heBeiEightCities = specialCitiesProperties.getHeBeiEightCities(); + List<Integer> heBeiEightCitiesCodes = heBeiEightCities.stream() + .map(SysArea::getAreaCode) + .collect(Collectors.toList()); + //������2+26������������ + queryWrapper.select("city_code", "value") + .eq("time", time) + .in("city_code", heBeiEightCitiesCodes); + List<CityAqiMonthly> 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<String, Object> getAreaCurrentMonthResult(Map<Integer, String> areasMap, List<CityAqiMonthly> areaData, Double compositeIndex, String compositeIndexYearOnYear, Integer pm25, String pm25YearOnYear) { + Map<String, Object> 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<String> compositeIndexLowerList = new ArrayList<>(); + //��������������������������������������������� + List<String> compositeIndexHigherList = new ArrayList<>(); + //��������������������������������������������� + List<String> compositeIndexEqualList = new ArrayList<>(); + + //��������������������������������������������������� + List<String> compositeIndexYearOnYearLowerList = new ArrayList<>(); + //��������������������������������������������������� + List<String> compositeIndexYearOnYearHigherList = new ArrayList<>(); + //��������������������������������������������������� + List<String> compositeIndexYearOnYearEqualList = new ArrayList<>(); + //��������������������������������������������������������������������������������� + List<String> compositeIndexYearOnYearHigherOfPositiveList = new ArrayList<>(); + //��������������������������������������������������������������������������������� + List<String> compositeIndexYearOnYearHigherOfNegativeList = new ArrayList<>(); + //���������������������������������������������������������������������������0��� + List<String> compositeIndexYearOnYearHigherOfZeroList = new ArrayList<>(); + + + //pm2.5��������������������������������������� + List<String> pm25LowerList = new ArrayList<>(); + //pm2.5��������������������������������������� + List<String> pm25HigherList = new ArrayList<>(); + //pm2.5��������������������������������������� + List<String> pm25EqualList = new ArrayList<>(); + + //pm2.5��������������������������������������������� + List<String> pm25YearOnYearLowerList = new ArrayList<>(); + //pm2.5������������������������������������������������ + List<String> pm25YearOnYearHigherList = new ArrayList<>(); + ///pm2.5��������������������������������������������� + List<String> pm25YearOnYearEqualList = new ArrayList<>(); + //pm2.5��������������������������������������������������������������������������� + List<String> pm25YearOnYearLowerOfPositiveList = new ArrayList<>(); + //pm2.5��������������������������������������������������������������������������� + List<String> pm25YearOnYearLowerOfNegativeList = new ArrayList<>(); + //pm2.5������������������������������������������������������������������0��� + List<String> 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<String, Object> 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<Integer, Map<String, Object>> getMonthlyCumulativeResult(Date time, List<Integer> regionCodes) { + + //���������������������1���1��� + Date start = DateUtils.getFirstDayOfYear(time); + //��������������������������������� + Date end = DateUtils.getLastDayOfMonth(time); + + //������������������������1-x��������������� + QueryWrapper<CityAqiDaily> cityAqiDailyQueryWrapper = new QueryWrapper<>(); + cityAqiDailyQueryWrapper.select("city_code", "value") + .ge("time", start) + .le("time", end) + .in("city_code", regionCodes); + List<CityAqiDaily> cityAqiDailyList = cityAqiDailyService.list(cityAqiDailyQueryWrapper); + if (cityAqiDailyList.size() == 0) { + return null; + } + + Map<Integer, Map<String, Object>> 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<CityAqiDaily> lastCityAqiDailyList = cityAqiDailyService.list(cityAqiDailyQueryWrapper); + Map<Integer, Map<String, Object>> lastMap = getMonthCumulative(lastCityAqiDailyList); + + //��������������������� + for (Map.Entry<Integer, Map<String, Object>> entry : currentMap.entrySet()) { + Integer regionCode = entry.getKey(); + Map<String, Object> current = entry.getValue(); + Map<String, Object> last = lastMap.get(regionCode); + Map<String, Object> map = yearOnYearOfSensor(last, current); + if (map != null) { + currentMap.put(regionCode, yearOnYearOfSensor(last, current)); + } + } + return currentMap; + } + + /** + * @param last ������������ + * @param current ������������ + * @description ��������������������� + */ + private Map<String, Object> yearOnYearOfSensor(Map<String, Object> last, Map<String, Object> current) { + if (last == null) { + return null; + } + //��������������������������� + List<String> 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<Integer, Map<String, Object>> getMonthCumulative(List<CityAqiDaily> data) { + Map<Integer, Map<String, Object>> result = new HashMap<>(); + //��������������������������� + List<String> sensors = Arrays.asList("PM2_5", "PM10", "SO2", "NO2"); + //���city_code������ + Map<Integer, List<CityAqiDaily>> cityDataMap = data.stream() + .collect(Collectors.groupingBy(CityAqiDaily::getCityCode)); + //1-x��������������� + cityDataMap.forEach((cityCode, list) -> { + Map<String, Object> jsonMap = new HashMap<>(); + Map<String, Object> params = new HashMap<>(); + List<Map<String, Object>> temp = new ArrayList<>(); + for (CityAqiDaily cityAqiDaily : list) { + Map<String, Object> valueMap = JSONObject.parseObject(cityAqiDaily.getValue(), Map.class); + Map<String, Object> tempMap = new HashMap<>(); + Map<String, Object> 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<String, Object> coAvgOfWeekOrMonth = AmendUtils.getCOAvgOfWeekOrMonth(params); + if (!ObjectUtils.isEmpty(coAvgOfWeekOrMonth)) { + jsonMap.put("CO", coAvgOfWeekOrMonth.get(Constants.SENSOR_CODE_CO)); + } + + //2. O3 90������������������������ + Map<String, Object> 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<String, Object> 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<Map<String, Object>> airQualityRankingOfCurrentReport(List<CityAqiMonthly> list, Map<Integer, String> areasMap) { + List<Map<String, Object>> result = new ArrayList<>(); + + Map<Integer, CityAqiMonthly> dataMap = new HashMap<>(); + for (CityAqiMonthly cityAqiMonthly : list) { + dataMap.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); + } + + + for (Map.Entry<Integer, String> entry : areasMap.entrySet()) { + Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> map = result.get(i); + map.put("PM2_5YearOnYearRank", i + 1); + } + + //������������������ + for (Map<String, Object> 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<String, Object> map = result.get(i); + map.put("resultRank", i + 1); + } + for (Map<String, Object> map : result) { + for (Map.Entry<String, Object> 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<Map<String, Object>> cumulativeAirQualityRankingReport(List<CityAqiMonthly> list, Map<Integer, String> areasMap) { + List<Map<String, Object>> result = new ArrayList<>(); + + + Map<Integer, CityAqiMonthly> dataMap = new HashMap<>(); + for (CityAqiMonthly cityAqiMonthly : list) { + dataMap.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); + } + + for (Map.Entry<Integer, String> entry : areasMap.entrySet()) { + Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> map = result.get(i); + map.put("compositeIndexYearOnYearRank", i + 1); + } + for (Map<String, Object> map : result) { + for (Map.Entry<String, Object> 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<Map<String, Object>> currentFiveSensorsContrastReport(Date time, List<Integer> areaCodes, List<CityAqiMonthly> areaData, Map<Integer, String> areasMap) { + List<Map<String, Object>> result = new ArrayList<>(); + + //������������ + Map<Integer, CityAqiMonthly> dataCurrent = new HashMap<>(); + for (CityAqiMonthly cityAqiMonthly : areaData) { + dataCurrent.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); + } + + + //������������������������ + QueryWrapper<CityAqiMonthly> queryWrapper = new QueryWrapper<>(); + queryWrapper.clear(); + queryWrapper.select("city_code", "value") + .eq("time", DateUtils.addYears(time, -1)) + .in("city_code", areaCodes); + List<CityAqiMonthly> monthlyDataLast = cityAqiMonthlyMapper.selectList(queryWrapper); + Map<Integer, CityAqiMonthly> dataLast = new HashMap<>(); + for (CityAqiMonthly cityAqiMonthly : monthlyDataLast) { + dataLast.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); + } + + + //��������������������������������� + List<String> sensors = Arrays.asList("PM10", "SO2", "NO2", "CO", "O3"); + for (Map.Entry<Integer, String> entry : areasMap.entrySet()) { + Map<String, Object> 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<String, Object> 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<String, Object> lastValue = JSONObject.parseObject(dataLast.get(regionCode).getValue(), Map.class); + //��������������������������� + resultMap.put(sensor + "Last", lastValue.get(sensor)); + } + } + result.add(resultMap); + } + for (Map<String, Object> map : result) { + for (Map.Entry<String, Object> 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<Map<String, Object>> cumulativeFiveSensorsContrastReport(List<CityAqiMonthly> areaData, Map<Integer, String> areasMap) { + List<Map<String, Object>> result = new ArrayList<>(); + + //������������ + Map<Integer, CityAqiMonthly> dataCurrent = new HashMap<>(); + for (CityAqiMonthly cityAqiMonthly : areaData) { + dataCurrent.put(cityAqiMonthly.getCityCode(), cityAqiMonthly); + } + + + List<String> sensors = Arrays.asList("PM10", "SO2", "NO2", "CO", "O3"); + for (Map.Entry<Integer, String> entry : areasMap.entrySet()) { + Map<String, Object> 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<String, Object> 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<String, Object> map : result) { + for (Map.Entry<String, Object> entry : map.entrySet()) { + if (entry.getValue() == null) { + map.put(entry.getKey(), ""); + } + } + } + return result; + } } -- Gitblit v1.8.0