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;
|
|
/**
|
* <p>
|
* 城市aqi月数据表 服务实现类
|
* </p>
|
*
|
* @author moral
|
* @since 2021-11-05
|
*/
|
@Service
|
public class CityAqiMonthlyServiceImpl extends ServiceImpl<CityAqiMonthlyMapper, CityAqiMonthly> 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<CityAqiMonthly> getCityAqiMonthByRegionCodeAndTime(Integer regionCode, Date startDate, Date endDate) {
|
QueryWrapper<CityAqiMonthly> 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<CityAqiMonthly> queryWrapper = new QueryWrapper<>();
|
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;
|
Double 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 = 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<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;
|
Double 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 = 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, Double 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;
|
}
|
}
|