package com.moral.api.service.impl;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.moral.api.entity.CityAqiDaily;
|
import com.moral.api.entity.CityAqiMonthly;
|
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.constant.Constants;
|
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 org.springframework.util.ObjectUtils;
|
|
import java.text.DecimalFormat;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.OptionalDouble;
|
import java.util.stream.Collectors;
|
import java.util.stream.DoubleStream;
|
|
/**
|
* <p>
|
* 城市aqi月数据表 服务实现类
|
* </p>
|
*
|
* @author moral
|
* @since 2021-11-04
|
*/
|
@Service
|
public class CityAqiMonthlyServiceImpl extends ServiceImpl<CityAqiMonthlyMapper, CityAqiMonthly> implements CityAqiMonthlyService {
|
|
@Autowired
|
private CityAqiMonthlyMapper cityAqiMonthlyMapper;
|
|
@Autowired
|
private CityAqiDailyService cityAqiDailyService;
|
|
@Override
|
public void insertCityAqiMonthly() {
|
//需要均值计算的因子
|
List<String> sensors = Arrays.asList("PM2_5", "PM10", "SO2", "NO2");
|
|
//开始时间,上月1号
|
Date start = DateUtils.getFirstDayOfLastMonth();
|
//上上月
|
Date lastLastMonth = DateUtils.addMonths(start, -1);
|
//结束时间,本月1号
|
Date end = DateUtils.addMonths(start, 1);
|
|
//如果是1号,先删除上月数据再统计
|
//不是1号,统计的是本月累计值,先删除本月数据
|
int day = DateUtils.getDay(new Date());
|
UpdateWrapper<CityAqiMonthly> cityAqiMonthlyUpdateWrapper = new UpdateWrapper<>();
|
if (day == 1) {
|
cityAqiMonthlyUpdateWrapper.eq("time", start);
|
} else {
|
start = end;
|
end = DateUtils.addMonths(start, 1);
|
lastLastMonth = DateUtils.addMonths(start, -1);
|
cityAqiMonthlyUpdateWrapper.eq("time", start);
|
}
|
cityAqiMonthlyMapper.delete(cityAqiMonthlyUpdateWrapper);
|
|
|
//获取所有城市aqi小时数据
|
QueryWrapper<CityAqiDaily> wrapper = new QueryWrapper<>();
|
wrapper.select("city_code", "time", "value")
|
.ge("time", start)
|
.lt("time", end);
|
List<Map<String, Object>> monthlyData = cityAqiDailyService.listMaps(wrapper);
|
|
if (monthlyData.size() == 0) {
|
return;
|
}
|
//按city_code分组
|
Map<Integer, List<Map<String, Object>>> data = monthlyData.stream()
|
.collect(Collectors.groupingBy(o ->Integer.parseInt(o.get("city_code").toString()) ));
|
|
//获取上月数据,本月综指同上月对比
|
QueryWrapper<CityAqiMonthly> queryWrapper = new QueryWrapper<>();
|
queryWrapper.select("city_code", "value")
|
.eq("time", lastLastMonth);
|
//获取上月数据
|
List<CityAqiMonthly> lastCityAqiMonthlyList = cityAqiMonthlyMapper.selectList(queryWrapper);
|
Map<Integer, CityAqiMonthly> lastMonthData = new HashMap<>();
|
for (CityAqiMonthly cityAqiMonthly : lastCityAqiMonthlyList) {
|
lastMonthData.put(cityAqiMonthly.getCityCode(), cityAqiMonthly);
|
}
|
|
|
//获取去年本月数据
|
Date thisMonthOfLastYear = DateUtils.addYears(start, -1);
|
queryWrapper.clear();
|
queryWrapper.select("city_code", "value")
|
.eq("time", thisMonthOfLastYear);
|
List<CityAqiMonthly> thisMonthOfLastYearList = cityAqiMonthlyMapper.selectList(queryWrapper);
|
Map<Integer, CityAqiMonthly> thisMonthOfLastYearData = new HashMap<>();
|
for (CityAqiMonthly cityAqiMonthly : thisMonthOfLastYearList) {
|
thisMonthOfLastYearData.put(cityAqiMonthly.getCityCode(), cityAqiMonthly);
|
}
|
|
|
List<CityAqiMonthly> cityAqiMonthlyList = new ArrayList<>();
|
|
Date finalStart = start;
|
data.forEach((cityCode, value) -> {
|
CityAqiMonthly cityAqiMonthly = new CityAqiMonthly();
|
Map<String, Object> jsonMap = new HashMap<>();
|
cityAqiMonthly.setCityCode(cityCode);
|
cityAqiMonthly.setTime(finalStart);
|
|
Map<String, Object> params = new HashMap<>();
|
List<Map<String, Object>> temp = new ArrayList<>();
|
for (Map<String, Object> map : value) {
|
Map<String, Object> sensorsValue = JSONObject.parseObject(map.get("value").toString(), Map.class);
|
Map<String, Object> tempMap = new HashMap<>();
|
tempMap.put(Constants.SENSOR_CODE_CO, sensorsValue.get("CO"));
|
tempMap.put(Constants.SENSOR_CODE_O3, sensorsValue.get("O3"));
|
Map<String, Object> hashMap = new HashMap<>();
|
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 = value.stream().flatMapToDouble(v -> {
|
Map<String, Object> dataValue = JSONObject.parseObject((String) v.get("value"), 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));
|
}
|
});
|
|
//本月月综指计算
|
Double compositeIndex = ComprehensiveIndexUtils.dailyData(jsonMap);
|
jsonMap.put("compositeIndex", compositeIndex);
|
|
//本月综指同上月对比(综合指数环比)
|
CityAqiMonthly lastCityAqiMonthly = lastMonthData.get(cityCode);
|
if (lastCityAqiMonthly != null) {
|
Map<String, Object> map = JSONObject.parseObject(lastCityAqiMonthly.getValue(), Map.class);
|
double lastCompositeIndex = Double.parseDouble(map.get("compositeIndex").toString());
|
DecimalFormat decimalFormat = new DecimalFormat("0.00%");
|
String format = decimalFormat.format((compositeIndex - lastCompositeIndex) / lastCompositeIndex);
|
jsonMap.put("monthContrast", format);
|
}
|
|
//获取去年本月数据,用于计算同比
|
CityAqiMonthly thisMonthOfLastYears = thisMonthOfLastYearData.get(cityCode);
|
|
//各因子同比计算
|
Map<String, Object> yearOnYearValue = yearOnYearOfSensor(thisMonthOfLastYears, jsonMap);
|
if (yearOnYearValue != null) {
|
jsonMap.putAll(yearOnYearValue);
|
}
|
|
cityAqiMonthly.setValue(JSONObject.toJSONString(jsonMap));
|
cityAqiMonthlyList.add(cityAqiMonthly);
|
});
|
cityAqiMonthlyMapper.insertCityAqiMonthly(cityAqiMonthlyList);
|
}
|
|
|
/**
|
* @param thisMonthOfLastYearData 去年本月数据
|
* @param currentData 当前月该数据
|
*/
|
private Map<String, Object> yearOnYearOfSensor(CityAqiMonthly thisMonthOfLastYearData, Map<String, Object> currentData) {
|
Map<String, Object> result = null;
|
//需要计算同比的因子
|
List<String> sensors = Arrays.asList("PM2_5", "PM10", "SO2", "NO2", "CO", "O3", "compositeIndex");
|
if (thisMonthOfLastYearData != null) {
|
result = new HashMap<>();
|
Map<String, Object> map = JSONObject.parseObject(thisMonthOfLastYearData.getValue(), Map.class);
|
for (String sensor : sensors) {
|
//去年本月该因子值
|
double thisMonthOfLeastYearValue = Double.parseDouble(map.get(sensor).toString());
|
//当前该因子值
|
double currentValue = Double.parseDouble(currentData.get(sensor).toString());
|
DecimalFormat decimalFormat = new DecimalFormat("0.00%");
|
String format = decimalFormat.format((currentValue - thisMonthOfLeastYearValue) / thisMonthOfLeastYearValue);
|
result.put(sensor + "_yearOnYear", format);
|
}
|
}
|
return result;
|
}
|
}
|