package com.moral.api.service.impl; 
 | 
  
 | 
import com.alibaba.excel.util.StringUtils; 
 | 
import com.alibaba.fastjson.JSON; 
 | 
import com.alibaba.fastjson.JSONObject; 
 | 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 
 | 
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 
 | 
import com.moral.api.config.properties.SpecialCitiesProperties; 
 | 
import com.moral.api.dto.CityAqiDailyListDTO; 
 | 
import com.moral.api.entity.*; 
 | 
import com.moral.api.mapper.*; 
 | 
import com.moral.api.pojo.dto.cityAQI.CityPollutionLevel; 
 | 
import com.moral.api.pojo.dto.cityAQI.ConcentrationAndPercent; 
 | 
import com.moral.api.pojo.form.aqi.AirQualityComparisonForm; 
 | 
import com.moral.api.pojo.vo.cityAQI.AirQualityComparisonVO; 
 | 
import com.moral.api.pojo.vo.cityAQI.CityAreaRangeVO; 
 | 
import com.moral.api.service.*; 
 | 
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 
 | 
import com.moral.constant.Constants; 
 | 
import com.moral.constant.RedisConstants; 
 | 
import com.moral.pojo.AQI; 
 | 
import com.moral.util.AQIUtils; 
 | 
import com.moral.util.AmendUtils; 
 | 
import com.moral.util.ComprehensiveIndexUtils; 
 | 
import com.moral.util.DateUtils; 
 | 
  
 | 
import com.moral.util.MathUtils; 
 | 
  
 | 
import org.apache.commons.collections4.CollectionUtils; 
 | 
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.math.BigDecimal; 
 | 
import java.text.SimpleDateFormat; 
 | 
import java.util.*; 
 | 
import java.util.stream.Collectors; 
 | 
import java.util.stream.DoubleStream; 
 | 
  
 | 
/** 
 | 
 * <p> 
 | 
 * 城市aqi实测小时数据表 服务实现类 
 | 
 * </p> 
 | 
 * 
 | 
 * @author moral 
 | 
 * @since 2021-09-28 
 | 
 */ 
 | 
@Service 
 | 
public class CityAqiServiceImpl extends ServiceImpl<CityAqiMapper, CityAqi> implements CityAqiService { 
 | 
  
 | 
    @Autowired 
 | 
    private CityAqiMapper cityAqiMapper; 
 | 
    @Autowired 
 | 
    private CityAqiDailyMapper cityAqiDailyMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private ForecastMapper forecastMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private RedisTemplate redisTemplate; 
 | 
  
 | 
    @Autowired 
 | 
    private SysAreaService sysAreaService; 
 | 
  
 | 
    @Autowired 
 | 
    private CityAqiDailyService cityAqiDailyService; 
 | 
  
 | 
    @Autowired 
 | 
    private CityAqiMonthlyService cityAqiMonthlyService; 
 | 
  
 | 
    @Autowired 
 | 
    private CityAqiYearlyService cityAqiYearlyService; 
 | 
  
 | 
    @Autowired 
 | 
    private SpecialCitiesProperties specialCitiesProperties; 
 | 
  
 | 
    @Autowired 
 | 
    private CityWeatherService cityWeatherService; 
 | 
  
 | 
    @Autowired 
 | 
    private OrganizationService organizationService; 
 | 
  
 | 
    @Autowired 
 | 
    private DeviceMapper deviceMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private HistoryHourlyService historyHourlyService; 
 | 
  
 | 
    @Autowired 
 | 
    SpecialCitiesProperties citiesProperties; 
 | 
  
 | 
    @Autowired 
 | 
    private SysAreaMapper sysAreaMapper; 
 | 
  
 | 
    @Override 
 | 
    public List<Map<String, Object>> measuredCompareForecastOfO3(Map<String, Object> params) { 
 | 
        String regionCode = params.get("regionCode").toString(); 
 | 
        String time = params.get("time").toString(); 
 | 
        //预测数据 
 | 
        QueryWrapper<Forecast> forecastQueryWrapper = new QueryWrapper<>(); 
 | 
        forecastQueryWrapper.select("time", "value") 
 | 
                .eq("city_code", regionCode) 
 | 
                .likeRight("time", time); 
 | 
        List<Map<String, Object>> forecastData = forecastMapper.selectMaps(forecastQueryWrapper); 
 | 
        //实测数据 
 | 
        QueryWrapper<CityAqi> cityAqiQueryWrapper = new QueryWrapper<>(); 
 | 
        cityAqiQueryWrapper.select("time", "value") 
 | 
                .eq("city_code", regionCode) 
 | 
                .likeRight("time", time); 
 | 
        List<Map<String, Object>> measuredData = cityAqiMapper.selectMaps(cityAqiQueryWrapper); 
 | 
  
 | 
        List<Map<String, Object>> result = new ArrayList<>(); 
 | 
        for (int i = 0; i < 48; i++) { 
 | 
            Map<String, Object> map = new HashMap<>(); 
 | 
            if (i % 2 == 0) { 
 | 
                map.put("type", "预测"); 
 | 
                Date d = DateUtils.addHours(DateUtils.getDate(time), i / 2); 
 | 
                map.put("time", DateUtils.dateToDateString(d, DateUtils.yyyy_MM_dd_HH_EN)); 
 | 
                for (Map<String, Object> forecastDatum : forecastData) { 
 | 
                    Date date = (Date) forecastDatum.get("time"); 
 | 
                    String value = forecastDatum.get("value").toString(); 
 | 
                    Map<String, Object> data = JSONObject.parseObject(value, Map.class); 
 | 
                    Object o3 = data.get("O3"); 
 | 
                    if (i == DateUtils.getHour(date) * 2) { 
 | 
                        if (!ObjectUtils.isEmpty(o3)) { 
 | 
                            map.put("O3", o3); 
 | 
                        } 
 | 
                    } 
 | 
                } 
 | 
            } else { 
 | 
                map.put("type", "实测"); 
 | 
                Date d = DateUtils.addHours(DateUtils.getDate(time), (i - 1) / 2); 
 | 
                map.put("time", DateUtils.dateToDateString(d, DateUtils.yyyy_MM_dd_HH_EN)); 
 | 
                for (Map<String, Object> measuredDatum : measuredData) { 
 | 
                    Date date = (Date) measuredDatum.get("time"); 
 | 
                    String value = measuredDatum.get("value").toString(); 
 | 
                    Map<String, Object> data = JSONObject.parseObject(value, Map.class); 
 | 
                    Object o3 = data.get("O3"); 
 | 
                    if (i == (DateUtils.getHour(date) * 2 + 1)) { 
 | 
                        if (!ObjectUtils.isEmpty(o3)) { 
 | 
                            map.put("O3", o3); 
 | 
                        } 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
            result.add(map); 
 | 
        } 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
  
 | 
    @Override 
 | 
    public List<Map<String, Object>> measuredCompareForecastOfO3_8H(Map<String, Object> params) { 
 | 
        String regionCode = params.get("regionCode").toString(); 
 | 
        String time = params.get("time").toString(); 
 | 
        Date endTime = DateUtils.getDate(time+" "+"23:00:00",DateUtils.yyyy_MM_dd_HH_mm_ss_EN); 
 | 
        Date startDate = DateUtils.getDate(time+" "+"00:00:00",DateUtils.yyyy_MM_dd_HH_mm_ss_EN); 
 | 
        Date startTime = DateUtils.addHours(startDate,-7); 
 | 
        //预测数据 
 | 
        QueryWrapper<Forecast> forecastQueryWrapper = new QueryWrapper<>(); 
 | 
        forecastQueryWrapper.select("time", "value") 
 | 
                .eq("city_code", regionCode) 
 | 
        .between("time",startTime,endTime) 
 | 
                .orderByAsc("time"); 
 | 
        List<Map<String, Object>> forecastData = forecastMapper.selectMaps(forecastQueryWrapper); 
 | 
        //实测数据 
 | 
        QueryWrapper<CityAqi> cityAqiQueryWrapper = new QueryWrapper<>(); 
 | 
        cityAqiQueryWrapper.select("time", "value") 
 | 
                .eq("city_code", regionCode) 
 | 
                .between("time",startTime,endTime).orderByAsc("time"); 
 | 
        List<Map<String, Object>> measuredData = cityAqiMapper.selectMaps(cityAqiQueryWrapper); 
 | 
  
 | 
        List<Map<String, Object>> result = getO3_8H(forecastData,0,time); 
 | 
        result.addAll(getO3_8H(measuredData,1,time)); 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
  
 | 
    @Override 
 | 
    public Map<String, Object> queryCityAqiByRegionCode(Integer regionCode) { 
 | 
        Map<String, Object> value = (Map<String, Object>) redisTemplate.opsForHash().get(RedisConstants.CITY_AQI, String.valueOf(regionCode)); 
 | 
        if (value == null) 
 | 
            value = queryCityAqiByRegionCodeFromDB(regionCode); 
 | 
        //如果地区码是县级市则转换到市级在进行查询 
 | 
        if (value == null) { 
 | 
            String regionCodeStr = String.valueOf(regionCode); 
 | 
            String end = regionCodeStr.substring(regionCodeStr.length() - 2, regionCodeStr.length()); 
 | 
            if (!end.equals(00)) { 
 | 
                regionCodeStr = regionCodeStr.substring(0, regionCodeStr.length() - 2); 
 | 
                regionCodeStr += "00"; 
 | 
                regionCode = Integer.parseInt(regionCodeStr); 
 | 
                value = (Map<String, Object>) redisTemplate.opsForHash().get(RedisConstants.CITY_AQI, String.valueOf(regionCode)); 
 | 
                if (value == null) 
 | 
                    value = queryCityAqiByRegionCodeFromDB(regionCode); 
 | 
            } else { 
 | 
                return null; 
 | 
            } 
 | 
        } 
 | 
        //根据AQI计算污染等级 
 | 
        if (value == null || value.get("AQI") == null) 
 | 
            return null; 
 | 
        Integer aqi = Integer.parseInt(value.get("AQI").toString()); 
 | 
        String category = AQIUtils.classOfPollutionByAqi(aqi); 
 | 
        value.put("category", category); 
 | 
        return value; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public Map<String, Object> query24HoursAqiByRegionCode(Integer regionCode) { 
 | 
        //查询最新一条数据,用于获取最新的时间 
 | 
        /*QueryWrapper<CityAqi> lastDataWrapper = new QueryWrapper<>(); 
 | 
        lastDataWrapper.eq("city_code", regionCode); 
 | 
        lastDataWrapper.orderByDesc("time"); 
 | 
        lastDataWrapper.last(true, "limit 1"); 
 | 
        CityAqi cityAqi = cityAqiMapper.selectOne(lastDataWrapper); 
 | 
        if (cityAqi == null) 
 | 
            return null; 
 | 
        //算出前24小时的时间点 
 | 
        Date endDate = cityAqi.getTime(); 
 | 
        Date startDate = DateUtils.addHours(endDate, -23); 
 | 
        //查询数据 
 | 
        QueryWrapper<CityAqi> wrapper = new QueryWrapper<>(); 
 | 
        wrapper.between("time", startDate, endDate); 
 | 
        wrapper.eq("city_code", regionCode);*/ 
 | 
        List<CityAqi> cityAqis = cityAqiMapper.listCity(regionCode); 
 | 
        //如果数据不足24小时则补全 
 | 
        if(CollectionUtils.isEmpty(cityAqis)){ 
 | 
            return new HashMap<>(); 
 | 
        } 
 | 
        Date startDate = cityAqis.get(0).getTime(); 
 | 
        if(cityAqis.size()<24){ 
 | 
            for (int i = 0; i < 24; i++) { 
 | 
                Date dateTime = DateUtils.addHours(startDate, i); 
 | 
                if(cityAqis.size()-1 <i){ 
 | 
                    CityAqi newCityAqi = new CityAqi(); 
 | 
                    newCityAqi.setTime(dateTime); 
 | 
                    newCityAqi.setValue("0"); 
 | 
                    cityAqis.add(newCityAqi); 
 | 
                    continue; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
            //按照时间进行排序 
 | 
        cityAqis.sort(Comparator.comparing(CityAqi::getTime)); 
 | 
  
 | 
        //封装返回数据,map的key为yyyy-MM-dd HH:mm格式的时间,value为aqi的数值 
 | 
        Map<String, Object> result = new LinkedHashMap<>(); 
 | 
        for (CityAqi aqi : cityAqis) { 
 | 
            String key = DateUtils.dateToDateString(aqi.getTime(), "yyyy-MM-dd HH:mm"); 
 | 
            result.put(key,aqi.getValue()); 
 | 
        } 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public Map<String, Object> queryTodayAqiAndPollutant(Integer regionCode) { 
 | 
        //获取今天的9点时间 
 | 
        Date startDate = new Date(DateUtils.getTodayTime()); 
 | 
        Date endDate = new Date(); 
 | 
        //查询当天数据 
 | 
        QueryWrapper<CityAqi> wrapper = new QueryWrapper<>(); 
 | 
        wrapper.between("time", startDate, endDate); 
 | 
        wrapper.eq("city_code", regionCode); 
 | 
        wrapper.select("DISTINCT city_code,time,value"); 
 | 
        List<CityAqi> cityAqis = cityAqiMapper.selectList(wrapper); 
 | 
        //计算平均数 
 | 
        Map<String, Object> sixParamAvg = calculate6ParamAvg(cityAqis); 
 | 
        //计算累计aqi和首要污染物 
 | 
        Map<String, Object> result = new HashMap<>(); 
 | 
        AQI aqi = AQIUtils.hourlyAQI(sixParamAvg); 
 | 
        result.put("aqi", aqi.getAQIValue()); 
 | 
        result.put("pollutant", aqi.getPrimaryPollutantNames()); 
 | 
        //结果集添加时间 
 | 
        CityAqi lastCityAqi = cityAqis.get(cityAqis.size() - 1); 
 | 
        String time = DateUtils.dateToDateString(lastCityAqi.getTime(), "HH:mm"); 
 | 
        result.put("time", time); 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public List<Map<String, Object>> rankingDetails(Map<String, Object> params) { 
 | 
        List<Map<String, Object>> result = new ArrayList<>(); 
 | 
        int regionCode = Integer.parseInt(params.get("regionCode").toString()); 
 | 
        String type = params.get("type").toString(); 
 | 
        String time = null; 
 | 
        if (!ObjectUtils.isEmpty(params.get("time"))) { 
 | 
            time = params.get("time").toString(); 
 | 
        } 
 | 
        String start = null; 
 | 
        String end = null; 
 | 
        if (!ObjectUtils.isEmpty(params.get("start")) || !ObjectUtils.isEmpty(params.get("end"))) { 
 | 
            start = params.get("start").toString(); 
 | 
            end = params.get("end").toString(); 
 | 
        } 
 | 
        String cityType = params.get("cityType").toString(); 
 | 
  
 | 
        String s = String.valueOf(regionCode); 
 | 
        //获取当前省,市code 
 | 
        Integer curProvinceCode = Integer.parseInt(s.substring(0, 2) + "0000"); 
 | 
        Integer curCityCode = Integer.parseInt(s.substring(0, 4) + "00"); 
 | 
  
 | 
        QueryWrapper<SysArea> areaWrapper = new QueryWrapper<>(); 
 | 
  
 | 
        List<SysArea> sysAreas; 
 | 
        if ("28".equals(cityType)) { 
 | 
            //获取2+26城市 
 | 
            sysAreas = specialCitiesProperties.getTwentyEightCities(); 
 | 
        } else { 
 | 
            if ("province".equals(cityType)) { 
 | 
                //获取省内所有市 
 | 
                areaWrapper.select("area_code", "area_name").eq("parent_code", curProvinceCode); 
 | 
            } else { 
 | 
                //获取市内所有县区 
 | 
                areaWrapper.select("area_code", "area_name").eq("parent_code", curCityCode); 
 | 
            } 
 | 
            sysAreas = sysAreaService.list(areaWrapper); 
 | 
        } 
 | 
  
 | 
        switch (type) { 
 | 
            case "today": 
 | 
                result = accumulatedTodayRank(sysAreas); 
 | 
                break; 
 | 
            case "hour": 
 | 
                time = new StringBuilder(time).replace(10, 11, " ").toString() + ":00:00"; 
 | 
                result = hourRank(sysAreas, time); 
 | 
                break; 
 | 
            case "day": 
 | 
                time = time + " 00:00:00"; 
 | 
                result = dayRank(sysAreas, time); 
 | 
                break; 
 | 
            case "month": 
 | 
                time = time + "-01 00:00:00"; 
 | 
                result = monthRank(sysAreas, time); 
 | 
                break; 
 | 
            case "year": 
 | 
                time = time + "-01-01 00:00:00"; 
 | 
                result = yearRank(sysAreas, time); 
 | 
                break; 
 | 
            case "custom": 
 | 
                start = start + " 00:00:00"; 
 | 
                end = end + " :00:00"; 
 | 
                result = customRank(sysAreas, start, end); 
 | 
                break; 
 | 
            default: 
 | 
                break; 
 | 
        } 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param sysAreas 所要获取城市集合 
 | 
     * @return 功能:今日累计排名 
 | 
     */ 
 | 
    private List<Map<String, Object>> accumulatedTodayRank(List<SysArea> sysAreas) { 
 | 
        List<Integer> regionCodes = sysAreas.stream() 
 | 
                .map(SysArea::getAreaCode) 
 | 
                .collect(Collectors.toList()); 
 | 
  
 | 
        List<Map<String, Object>> result = new ArrayList<>(); 
 | 
        List<String> sensors = Arrays.asList("PM2_5", "PM10", "SO2", "NO2", "CO", "O3"); 
 | 
        Date now = new Date(); 
 | 
        String today = DateUtils.dateToDateString(now, DateUtils.yyyy_MM_dd_EN); 
 | 
        QueryWrapper<CityAqi> wrapper = new QueryWrapper<>(); 
 | 
        wrapper.select("city_code", "value") 
 | 
                .ge("time", today) 
 | 
                .in("city_code", regionCodes); 
 | 
        List<Map<String, Object>> cumulativeData = cityAqiMapper.selectMaps(wrapper); 
 | 
        //按city_code分组 
 | 
        Map<Integer, List<Map<String, Object>>> data = cumulativeData.parallelStream().collect(Collectors.groupingBy(o -> Integer.parseInt(o.get("city_code").toString()))); 
 | 
        data.forEach((cityCode, value) -> { 
 | 
            List<Double> doubles = new ArrayList<>(); 
 | 
            for (Map<String, Object> objectMap : value) { 
 | 
                Object o = JSONObject.parseObject((String) objectMap.get("value"), Map.class).get("O3_8H"); 
 | 
                if (!ObjectUtils.isEmpty(o)) { 
 | 
                    double v = Double.parseDouble(o.toString()); 
 | 
                    doubles.add(v); 
 | 
                } 
 | 
            } 
 | 
  
 | 
            Map<String, Object> dataMap = new HashMap<>(); 
 | 
            sensors.forEach(sensor -> { 
 | 
                OptionalDouble optionalDouble = value.parallelStream().flatMapToDouble(v -> { 
 | 
                    Map<String, Object> sensorValue = JSONObject.parseObject((String) v.get("value"), Map.class); 
 | 
                    Object o = sensorValue.get(sensor); 
 | 
                    if (ObjectUtils.isEmpty(o)) { 
 | 
                        return null; 
 | 
                    } 
 | 
                    double aDouble = Double.parseDouble(o.toString()); 
 | 
                    return DoubleStream.of(aDouble); 
 | 
                }).average(); 
 | 
  
 | 
                if (optionalDouble.isPresent()) { 
 | 
                    //银行家算法修约 
 | 
                    double sciCal = AmendUtils.sciCal(optionalDouble.getAsDouble(), 0); 
 | 
                    if ("CO".equals(sensor)) { 
 | 
                        sciCal = AmendUtils.sciCal(optionalDouble.getAsDouble(), 1); 
 | 
                    } 
 | 
                    dataMap.put(sensor, sciCal); 
 | 
                } 
 | 
            }); 
 | 
  
 | 
            //今日累计O3_8H计算,取每小时O3——8H最大值 
 | 
            if (!ObjectUtils.isEmpty(doubles)) { 
 | 
                dataMap.put("O3_8H", Collections.max(doubles)); 
 | 
            } 
 | 
  
 | 
            //今日累计aqi,首要污染物计算 
 | 
            Map<String, Object> sixParamMap = new HashMap<>(); 
 | 
            sixParamMap.put(Constants.SENSOR_CODE_PM25, dataMap.get("PM2_5")); 
 | 
            sixParamMap.put(Constants.SENSOR_CODE_PM10, dataMap.get("PM10")); 
 | 
            sixParamMap.put(Constants.SENSOR_CODE_SO2, dataMap.get("SO2")); 
 | 
            sixParamMap.put(Constants.SENSOR_CODE_NO2, dataMap.get("NO2")); 
 | 
            sixParamMap.put(Constants.SENSOR_CODE_CO, dataMap.get("CO")); 
 | 
            sixParamMap.put(Constants.SENSOR_CODE_O3, dataMap.get("O3")); 
 | 
            AQI aqi = AQIUtils.dailyAQI(sixParamMap); 
 | 
            dataMap.put("AQI", aqi.getAQIValue()); 
 | 
            List<String> primaryPollutantNames = aqi.getPrimaryPollutantNames(); 
 | 
            String primaryPollutant = ""; 
 | 
            if (!ObjectUtils.isEmpty(primaryPollutantNames)) { 
 | 
                primaryPollutant = primaryPollutantNames.stream().map(String::valueOf).collect(Collectors.joining(",")); 
 | 
            } 
 | 
            dataMap.put("primaryPollutant", primaryPollutant); 
 | 
  
 | 
            //今日累计综合指数计算,O3分综指用O3_8H计算 
 | 
            Map<String, Object> compositeIndexMap = new HashMap<>(dataMap); 
 | 
            compositeIndexMap.put("O3", compositeIndexMap.get("O3_8H")); 
 | 
            Double compositeIndex = ComprehensiveIndexUtils.dailyData(compositeIndexMap); 
 | 
            dataMap.put("compositeIndex", compositeIndex); 
 | 
  
 | 
            //城市名 
 | 
            for (SysArea sysArea : sysAreas) { 
 | 
                if (cityCode.equals(sysArea.getAreaCode())) { 
 | 
                    dataMap.put("cityName", sysArea.getAreaName()); 
 | 
                    break; 
 | 
                } 
 | 
            } 
 | 
            result.add(dataMap); 
 | 
        }); 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param sysAreas 所要获取城市集合 
 | 
     * @param time     所要获取数据的时间 2021-11-04 13:00:00 
 | 
     * @return 功能:小时排名 
 | 
     */ 
 | 
    private List<Map<String, Object>> hourRank(List<SysArea> sysAreas, String time) { 
 | 
        List<Integer> regionCodes = sysAreas.stream() 
 | 
                .map(SysArea::getAreaCode) 
 | 
                .collect(Collectors.toList()); 
 | 
  
 | 
        List<Map<String, Object>> result = new ArrayList<>(); 
 | 
        QueryWrapper<CityAqi> wrapper = new QueryWrapper<>(); 
 | 
        wrapper.select("value") 
 | 
                .eq("time", time) 
 | 
                .in("city_code", regionCodes); 
 | 
        List<Map<String, Object>> hourData = cityAqiMapper.selectMaps(wrapper); 
 | 
        for (Map<String, Object> hourDatum : hourData) { 
 | 
            Map<String, Object> value = JSONObject.parseObject((String) hourDatum.get("value"), Map.class); 
 | 
            List<String> primaryPollutantNames = (List<String>) value.get("primaryPollutant"); 
 | 
            String primaryPollutant = ""; 
 | 
            if (!ObjectUtils.isEmpty(primaryPollutantNames)) { 
 | 
                primaryPollutant = primaryPollutantNames.stream().map(String::valueOf).collect(Collectors.joining(",")); 
 | 
            } 
 | 
            value.put("primaryPollutant", primaryPollutant); 
 | 
            value.remove("pubtime"); 
 | 
            value.remove("rank"); 
 | 
            result.add(value); 
 | 
        } 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param sysAreas 所要获取城市集合 
 | 
     * @param time     所要获取数据的时间 2021-11-04 00:00:00 
 | 
     * @return 功能:日排名 
 | 
     */ 
 | 
    private List<Map<String, Object>> dayRank(List<SysArea> sysAreas, String time) { 
 | 
        List<Integer> regionCodes = sysAreas.stream() 
 | 
                .map(SysArea::getAreaCode) 
 | 
                .collect(Collectors.toList()); 
 | 
  
 | 
        List<Map<String, Object>> result = new ArrayList<>(); 
 | 
        QueryWrapper<CityAqiDaily> wrapper = new QueryWrapper<>(); 
 | 
        wrapper.select("city_code", "value") 
 | 
                .eq("time", time) 
 | 
                .in("city_code", regionCodes); 
 | 
        List<CityAqiDaily> dayData = cityAqiDailyService.list(wrapper); 
 | 
        for (CityAqiDaily cityAqiDaily : dayData) { 
 | 
            Map<String, Object> resultMap = JSONObject.parseObject(cityAqiDaily.getValue(), Map.class); 
 | 
            resultMap.put("O3_8H", resultMap.remove("O3")); 
 | 
            List<String> primaryPollutantNames = (List<String>) resultMap.get("primaryPollutant"); 
 | 
            String primaryPollutant = ""; 
 | 
            if (!ObjectUtils.isEmpty(primaryPollutantNames)) { 
 | 
                primaryPollutant = primaryPollutantNames.stream().map(String::valueOf).collect(Collectors.joining(",")); 
 | 
            } 
 | 
            resultMap.put("primaryPollutant", primaryPollutant); 
 | 
  
 | 
  
 | 
            //城市名 
 | 
            for (SysArea sysArea : sysAreas) { 
 | 
                if (cityAqiDaily.getCityCode().equals(sysArea.getAreaCode())) { 
 | 
                    resultMap.put("cityName", sysArea.getAreaName()); 
 | 
                    break; 
 | 
                } 
 | 
            } 
 | 
            result.add(resultMap); 
 | 
        } 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param sysAreas 所要获取城市集合 
 | 
     * @param time     所要获取数据的时间 2021-11-01 00:00:00 
 | 
     * @return 功能:月排名 
 | 
     */ 
 | 
    private List<Map<String, Object>> monthRank(List<SysArea> sysAreas, String time) { 
 | 
        List<Integer> regionCodes = sysAreas.stream() 
 | 
                .map(SysArea::getAreaCode) 
 | 
                .collect(Collectors.toList()); 
 | 
  
 | 
        List<Map<String, Object>> result = new ArrayList<>(); 
 | 
        QueryWrapper<CityAqiMonthly> cityAqiMonthlyQueryWrapper = new QueryWrapper<>(); 
 | 
        cityAqiMonthlyQueryWrapper.select("city_code", "value") 
 | 
                .eq("time", time) 
 | 
                .in("city_code", regionCodes); 
 | 
        List<CityAqiMonthly> list = cityAqiMonthlyService.list(cityAqiMonthlyQueryWrapper); 
 | 
        for (CityAqiMonthly cityAqiMonthly : list) { 
 | 
            Map<String, Object> resultMap = JSONObject.parseObject(cityAqiMonthly.getValue(), Map.class); 
 | 
            resultMap.put("O3_8H", resultMap.remove("O3")); 
 | 
            //城市名 
 | 
            for (SysArea sysArea : sysAreas) { 
 | 
                if (cityAqiMonthly.getCityCode().equals(sysArea.getAreaCode())) { 
 | 
                    resultMap.put("cityName", sysArea.getAreaName()); 
 | 
                    break; 
 | 
                } 
 | 
            } 
 | 
            result.add(resultMap); 
 | 
        } 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param sysAreas 所要获取城市集合 
 | 
     * @param time     所要获取数据的时间 2021-11-01 00:00:00 每年1月1号 
 | 
     * @return 功能:年排名 
 | 
     */ 
 | 
    private List<Map<String, Object>> yearRank(List<SysArea> sysAreas, String time) { 
 | 
        List<Integer> regionCodes = sysAreas.stream() 
 | 
                .map(SysArea::getAreaCode) 
 | 
                .collect(Collectors.toList()); 
 | 
  
 | 
        List<Map<String, Object>> result = new ArrayList<>(); 
 | 
        QueryWrapper<CityAqiYearly> cityAqiYearlyQueryWrapper = new QueryWrapper<>(); 
 | 
        cityAqiYearlyQueryWrapper.select("city_code", "value") 
 | 
                .in("city_code", regionCodes) 
 | 
                .eq("time", time); 
 | 
        List<CityAqiYearly> list = cityAqiYearlyService.list(cityAqiYearlyQueryWrapper); 
 | 
        for (CityAqiYearly cityAqiYearly : list) { 
 | 
            Map<String, Object> resultMap = JSONObject.parseObject(cityAqiYearly.getValue(), Map.class); 
 | 
            resultMap.put("O3_8H", resultMap.remove("O3")); 
 | 
            for (SysArea sysArea : sysAreas) { 
 | 
                if (cityAqiYearly.getCityCode().equals(sysArea.getAreaCode())) { 
 | 
                    resultMap.put("cityName", sysArea.getAreaName()); 
 | 
                    break; 
 | 
                } 
 | 
            } 
 | 
            result.add(resultMap); 
 | 
        } 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param sysAreas 所要获取城市集合 
 | 
     * @param start    所要获取数据的开始时间,精确到日,2021-11-03 00:00:00 
 | 
     * @param end      所要获取数据的结束时间,精确到日,2021-11-25 00:00:00 
 | 
     * @return 功能:自定义排名 
 | 
     */ 
 | 
    private List<Map<String, Object>> customRank(List<SysArea> sysAreas, String start, String end) { 
 | 
        List<Integer> regionCodes = sysAreas.stream() 
 | 
                .map(SysArea::getAreaCode) 
 | 
                .collect(Collectors.toList()); 
 | 
  
 | 
        //需要均值计算的因子 
 | 
        List<String> sensors = Arrays.asList("PM2_5", "PM10", "SO2", "NO2"); 
 | 
        List<Map<String, Object>> result = new ArrayList<>(); 
 | 
        QueryWrapper<CityAqiDaily> cityAqiDailyQueryWrapper = new QueryWrapper<>(); 
 | 
        cityAqiDailyQueryWrapper.select("city_code", "value") 
 | 
                .ge("time", start) 
 | 
                .le("time", end) 
 | 
                .in("city_code", regionCodes); 
 | 
        List<Map<String, Object>> thisMonthData = cityAqiDailyService.listMaps(cityAqiDailyQueryWrapper); 
 | 
        //按city_code分组 
 | 
        Map<Integer, List<Map<String, Object>>> customMap = thisMonthData.parallelStream() 
 | 
                .collect(Collectors.groupingBy(o -> Integer.parseInt(o.get("city_code").toString()))); 
 | 
        customMap.forEach((cityCode, value) -> { 
 | 
            Map<String, Object> resultMap = new HashMap<>(); 
 | 
  
 | 
            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)) { 
 | 
                resultMap.put("CO", coAvgOfWeekOrMonth.get(Constants.SENSOR_CODE_CO)); 
 | 
            } 
 | 
  
 | 
            //2. O3 90百分位计算并修约 
 | 
            Map<String, Object> o3AvgOfWeekOrMonth = AmendUtils.getO3AvgOfWeekOrMonth(params); 
 | 
            if (!ObjectUtils.isEmpty(o3AvgOfWeekOrMonth)) { 
 | 
                resultMap.put("O3", o3AvgOfWeekOrMonth.get(Constants.SENSOR_CODE_O3)); 
 | 
            } 
 | 
  
 | 
            sensors.forEach(sensor -> { 
 | 
                OptionalDouble optionalDouble = value.parallelStream().flatMapToDouble(v -> { 
 | 
                    Map<String, Object> sensorValue = JSONObject.parseObject((String) v.get("value"), Map.class); 
 | 
                    Object o = sensorValue.get(sensor); 
 | 
                    if (ObjectUtils.isEmpty(o)) { 
 | 
                        return null; 
 | 
                    } 
 | 
                    double aDouble = Double.parseDouble(o.toString()); 
 | 
                    return DoubleStream.of(aDouble); 
 | 
                }).average(); 
 | 
  
 | 
                if (optionalDouble.isPresent()) { 
 | 
                    //银行家算法修约 
 | 
                    double sciCal = AmendUtils.sciCal(optionalDouble.getAsDouble(), 0); 
 | 
                    resultMap.put(sensor, sciCal); 
 | 
                } 
 | 
            }); 
 | 
  
 | 
            //自定义综指计算 
 | 
            Double compositeIndex = ComprehensiveIndexUtils.dailyData(resultMap); 
 | 
            resultMap.put("compositeIndex", compositeIndex); 
 | 
  
 | 
            //前端O3用O3_8H显示 
 | 
            resultMap.put("O3_8H", resultMap.remove("O3")); 
 | 
  
 | 
            //城市名 
 | 
            for (SysArea sysArea : sysAreas) { 
 | 
                if (cityCode.equals(sysArea.getAreaCode())) { 
 | 
                    resultMap.put("cityName", sysArea.getAreaName()); 
 | 
                    break; 
 | 
                } 
 | 
            } 
 | 
            result.add(resultMap); 
 | 
        }); 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
  
 | 
    /** 
 | 
     * @Description: 从数据库查询数据 
 | 
     * @Param: [regionCode] 
 | 
     * @return: java.util.Map<java.lang.String                                                               ,                                                                                                                               java.lang.Object> 
 | 
     * @Author: 陈凯裕 
 | 
     * @Date: 2021/10/28 
 | 
     */ 
 | 
    private Map<String, Object> queryCityAqiByRegionCodeFromDB(Integer regionCode) { 
 | 
        QueryWrapper<CityAqi> wrapper = new QueryWrapper(); 
 | 
        wrapper.eq("city_code", regionCode); 
 | 
        wrapper.orderByDesc("time"); 
 | 
        wrapper.last(true, "limit 1"); 
 | 
        CityAqi cityAqi = cityAqiMapper.selectOne(wrapper); 
 | 
        if (cityAqi == null) 
 | 
            return null; 
 | 
        String value = cityAqi.getValue(); 
 | 
        redisTemplate.opsForHash().put(RedisConstants.CITY_AQI, regionCode, value); 
 | 
        return JSON.parseObject(value, Map.class); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public Map<String, Object> provincialRanking(Integer regionCode) { 
 | 
        //结果集 
 | 
        Map<String, Object> result = new HashMap<>(); 
 | 
  
 | 
        Date now = new Date(); 
 | 
        //昨日 
 | 
        Date yesterday = DateUtils.dataToTimeStampTime(DateUtils.getDateOfDay(now, -1), DateUtils.yyyy_MM_dd_EN); 
 | 
        String dateString = DateUtils.dateToDateString(yesterday, DateUtils.yyyy_MM_dd_EN); 
 | 
  
 | 
        String s = String.valueOf(regionCode); 
 | 
        //获取省,市code 
 | 
        Integer provinceCode = Integer.parseInt(s.substring(0, 2) + "0000"); 
 | 
        Integer cityCode = Integer.parseInt(s.substring(0, 4) + "00"); 
 | 
        Map<String,Object> params = new HashMap<>(); 
 | 
        params.put("cityCode",provinceCode); 
 | 
        params.put("start",dateString); 
 | 
        params.put("end",dateString); 
 | 
        params.put("type",1); 
 | 
        List<CityAqiDailyListDTO> dayList = cityAqiDailyMapper.CityAqiDailyMap(params); 
 | 
        String start = DateUtils.dateToDateString(DateUtils.addMonths(DateUtils.getFirstDayOfLastMonth(), 1)); 
 | 
        params.put("start",start); 
 | 
        params.put("type",2); 
 | 
        List<CityAqiDailyListDTO> monList = cityAqiDailyMapper.CityAqiDailyMap(params); 
 | 
        start =DateUtils.dateToDateString(now, DateUtils.yyyy); 
 | 
        params.put("start",start); 
 | 
        params.put("end",start); 
 | 
        params.put("type",3); 
 | 
        List<CityAqiDailyListDTO> yearList = cityAqiDailyMapper.CityAqiDailyMap(params); 
 | 
        int indexDay = dayList.stream().map(CityAqiDailyListDTO::getCityCode).collect(Collectors.toList()).indexOf(cityCode.toString()); 
 | 
        int indexMon = monList.stream().map(CityAqiDailyListDTO::getCityCode).collect(Collectors.toList()).indexOf(cityCode.toString()); 
 | 
        int indexYear = yearList.stream().map(CityAqiDailyListDTO::getCityCode).collect(Collectors.toList()).indexOf(cityCode.toString()); 
 | 
        result.put("day",mapResult(dayList,indexDay)); 
 | 
        result.put("month",mapResult(monList,indexMon)); 
 | 
        result.put("year",mapResult(yearList,indexYear)); 
 | 
       /* //获取省内所有city_code 
 | 
        QueryWrapper<SysArea> wrapper = new QueryWrapper<>(); 
 | 
        wrapper.select("area_code").eq("parent_code", provinceCode); 
 | 
        List<Object> cityCodes = sysAreaService.listObjs(wrapper); 
 | 
  
 | 
        List<Map<String, Object>> ranks = new ArrayList<>(); 
 | 
        for (Object code : cityCodes) { 
 | 
            Map<String, Object> rankMap = new HashMap<>(); 
 | 
            rankMap.put("cityCode", code); 
 | 
            QueryWrapper<CityAqiDaily> queryWrapper = new QueryWrapper<>(); 
 | 
            queryWrapper.select("value").eq("city_code", code).eq("time", dateString); 
 | 
  
 | 
            //1.昨日数据 
 | 
            CityAqiDaily one = cityAqiDailyService.getOne(queryWrapper); 
 | 
            if (!ObjectUtils.isEmpty(one)) { 
 | 
                String value = one.getValue(); 
 | 
                Map<String, Object> valueMap = JSONObject.parseObject(value, Map.class); 
 | 
                rankMap.put("AQI", valueMap.get("AQI")); 
 | 
            } 
 | 
  
 | 
            //2.本月累计综合指数计算,截止到昨日 
 | 
            queryWrapper.clear(); 
 | 
            //开始时间:本月1号,结束时间:昨日 
 | 
            Date start = DateUtils.addMonths(DateUtils.getFirstDayOfLastMonth(), 1); 
 | 
            queryWrapper.select("value").eq("city_code", code).ge("time", start).le("time", yesterday); 
 | 
            List<CityAqiDaily> listMonth = cityAqiDailyService.list(queryWrapper); 
 | 
            OptionalDouble averageMonth = listMonth.parallelStream().flatMapToDouble(v -> { 
 | 
                Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class); 
 | 
                Double compositeIndex = Double.parseDouble(dataValue.get("compositeIndex").toString()); 
 | 
                return DoubleStream.of(compositeIndex); 
 | 
            }).average(); 
 | 
            if (averageMonth.isPresent()) { 
 | 
                //银行家算法修约 
 | 
                double compositeIndexAvgMonth = AmendUtils.sciCal(averageMonth.getAsDouble(), 2); 
 | 
                rankMap.put("compositeIndexMonth", compositeIndexAvgMonth); 
 | 
            } 
 | 
  
 | 
            //3.本年累计综合指数计算,截止到昨日 
 | 
            queryWrapper.clear(); 
 | 
            //开始时间:本年1.1号,结束时间:昨日 
 | 
            String yearStart = DateUtils.dateToDateString(now, DateUtils.yyyy); 
 | 
            queryWrapper.select("value").eq("city_code", code).ge("time", yearStart).le("time", yesterday); 
 | 
            List<CityAqiDaily> listYear = cityAqiDailyService.list(queryWrapper); 
 | 
            OptionalDouble averageYear = listYear.parallelStream().flatMapToDouble(v -> { 
 | 
                Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class); 
 | 
                Double compositeIndex = Double.parseDouble(dataValue.get("compositeIndex").toString()); 
 | 
                return DoubleStream.of(compositeIndex); 
 | 
            }).average(); 
 | 
            if (averageYear.isPresent()) { 
 | 
                //银行家算法修约 
 | 
                double compositeIndexAvgYear = AmendUtils.sciCal(averageYear.getAsDouble(), 2); 
 | 
                rankMap.put("compositeIndexYear", compositeIndexAvgYear); 
 | 
            } 
 | 
            ranks.add(rankMap); 
 | 
        } 
 | 
  
 | 
        //日排名,按aqi排序 
 | 
        ranks.removeIf(o -> o.get("AQI") == null); 
 | 
        sortByField(ranks, "AQI"); 
 | 
        //日排名结果 
 | 
        Map<String, Object> dayMap = rankByField(ranks, cityCode, "AQI", cityCodes.size()); 
 | 
        if (ObjectUtils.isEmpty(dayMap)) { 
 | 
            dayMap.put("rank", null); 
 | 
            dayMap.put("size", null); 
 | 
        } 
 | 
        dayMap.put("AQI", dayMap.remove("value")); 
 | 
        result.put("day", dayMap); 
 | 
  
 | 
        //月排名,按累计综指排 
 | 
        ranks.removeIf(o -> o.get("compositeIndexMonth") == null); 
 | 
        sortByField(ranks, "compositeIndexMonth"); 
 | 
        //月排名结果 
 | 
        Map<String, Object> monthMap = rankByField(ranks, cityCode, "compositeIndexMonth", cityCodes.size()); 
 | 
        if (ObjectUtils.isEmpty(monthMap)) { 
 | 
            monthMap.put("rank", null); 
 | 
            monthMap.put("size", null); 
 | 
        } 
 | 
        monthMap.put("compositeIndex", monthMap.remove("value")); 
 | 
        result.put("month", monthMap); 
 | 
  
 | 
        //年排名,按累计综指排 
 | 
        sortByField(ranks, "compositeIndexYear"); 
 | 
        Map<String, Object> yearMap = rankByField(ranks, cityCode, "compositeIndexYear", cityCodes.size()); 
 | 
        if (ObjectUtils.isEmpty(yearMap)) { 
 | 
            yearMap.put("rank", null); 
 | 
            yearMap.put("size", null); 
 | 
        } 
 | 
        yearMap.put("compositeIndex", yearMap.remove("value")); 
 | 
        result.put("year", yearMap);*/ 
 | 
  
 | 
        //时间,昨日 
 | 
        result.put("time", DateUtils.dateToDateString(yesterday, DateUtils.yyyy_MM_dd_EN)); 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    private Map<String,Object> mapResult(List<CityAqiDailyListDTO> list, int length){ 
 | 
        Map<String,Object> map = new HashMap<>(); 
 | 
        map.put("AQI",CollectionUtils.isNotEmpty(list)&&length>0&&Objects.nonNull(list.get(length-1))?list.get(length-1).getAqi():0); 
 | 
        map.put("rank",CollectionUtils.isNotEmpty(list)&&length>0?length:0); 
 | 
        map.put("size",CollectionUtils.isNotEmpty(list)&&length>0?list.size():0); 
 | 
        return map; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public List<AirQualityComparisonVO> queryAirQualityComparison(AirQualityComparisonForm form) { 
 | 
        //取参 
 | 
        Integer regionCode = form.getRegionCode(); 
 | 
        String regionType = form.getRegionType(); 
 | 
        Date startDate = form.getStartDate(); 
 | 
        Date endDate = form.getEndDate(); 
 | 
        Date comparisonStartDate = form.getComparisonStartDate(); 
 | 
        Date comparisonEndDate = form.getComparisonEndDate(); 
 | 
        String dateType = form.getDateType(); 
 | 
        //获取城市/区县 
 | 
        List<SysArea> areas = getSysAreasByRegionType(regionType, regionCode); 
 | 
        if (ObjectUtils.isEmpty(areas)) 
 | 
            return null; 
 | 
        List<AirQualityComparisonVO> vos = new ArrayList<>(); 
 | 
        for (SysArea area : areas) { 
 | 
            //获取查询时间和对比时间的6参和综合指数 
 | 
            Map<String, Object> data = getDataByTimeTypeAndRegionCode(dateType, startDate, endDate, area.getAreaCode()); 
 | 
            Map<String, Object> comparisonData = getDataByTimeTypeAndRegionCode(dateType, comparisonStartDate, comparisonEndDate, area.getAreaCode()); 
 | 
            if (ObjectUtils.isEmpty(data) || ObjectUtils.isEmpty(comparisonData)) 
 | 
                continue; 
 | 
            //查询优良天数以及重污染天数 
 | 
            CityPollutionLevel days = cityAqiDailyService.calculateDaysByTimeAndSysArea(area, startDate, endDate); 
 | 
            CityPollutionLevel comparisonDays = cityAqiDailyService.calculateDaysByTimeAndSysArea(area, comparisonStartDate, comparisonEndDate); 
 | 
            int fineDays = days.getExcellentWeatherDays() + days.getGoodWeatherDays(); 
 | 
            int serverDays = days.getSeriousWeatherDays() + days.getServerWeatherDays(); 
 | 
            int comparisonFineDays = comparisonDays.getExcellentWeatherDays() + comparisonDays.getGoodWeatherDays(); 
 | 
            int comparisonServerDays = comparisonDays.getSeriousWeatherDays() + comparisonDays.getServerWeatherDays(); 
 | 
            //对比6参和综合指数 
 | 
            Map<String, ConcentrationAndPercent> sixParamAndComIndexResult = contrastSixParamAndComIndex(data, comparisonData); 
 | 
            //对比优良天数以及重污染天气数 
 | 
            ConcentrationAndPercent fine = contrastDays(fineDays, comparisonFineDays); 
 | 
            ConcentrationAndPercent server = contrastDays(serverDays, comparisonServerDays); 
 | 
            //创建返回对象 
 | 
            AirQualityComparisonVO vo = new AirQualityComparisonVO(); 
 | 
            vo.setFineDays(fine); 
 | 
            vo.setServerDays(server); 
 | 
            vo.setCO(sixParamAndComIndexResult.get("CO")); 
 | 
            vo.setO3(sixParamAndComIndexResult.get("O3")); 
 | 
            vo.setPM25(sixParamAndComIndexResult.get("PM2_5")); 
 | 
            vo.setPM10(sixParamAndComIndexResult.get("PM10")); 
 | 
            vo.setSO2(sixParamAndComIndexResult.get("SO2")); 
 | 
            vo.setNO2(sixParamAndComIndexResult.get("NO2")); 
 | 
            vo.setCompositeIndex(sixParamAndComIndexResult.get("compositeIndex")); 
 | 
            vo.setCityName(area.getAreaName()); 
 | 
            vos.add(vo); 
 | 
        } 
 | 
        return vos; 
 | 
    } 
 | 
  
 | 
    //环比数据 
 | 
    @Override 
 | 
    public Map<String, Object> momData(Integer regionCode, Integer size, Integer current, Integer orgId) { 
 | 
        Map<String,Object> result = new HashMap<>(); 
 | 
        Page<CityAqi> page = new Page<>(current, size); 
 | 
        Page<CityAqi> pageNext = new Page<>(current+1, size); 
 | 
        QueryWrapper<CityAqi> cityAqiQueryWrapper = new QueryWrapper<>(); 
 | 
        cityAqiQueryWrapper.eq("city_code",regionCode); 
 | 
        Integer count = cityAqiMapper.selectCount(cityAqiQueryWrapper); 
 | 
        if (count==0){ 
 | 
            return result; 
 | 
        } 
 | 
        cityAqiQueryWrapper.orderByDesc("time"); 
 | 
        Page<CityAqi> resultPage = cityAqiMapper.selectPage(page, cityAqiQueryWrapper); 
 | 
        List<CityAqi> cityAqiList = resultPage.getRecords(); 
 | 
        Page<CityAqi> resultPageNext = cityAqiMapper.selectPage(pageNext, cityAqiQueryWrapper); 
 | 
        List<CityAqi> cityAqiListNext = resultPageNext.getRecords(); 
 | 
        List<Map<String,Object>> resultList = new ArrayList<>(); 
 | 
        if (cityAqiList.size()==0){ 
 | 
            return result; 
 | 
        } 
 | 
        for (int i=0; i<cityAqiList.size(); i++) { 
 | 
            Map<String,Object> resultMap = new HashMap<>(); 
 | 
            String hour = cityAqiList.get(i).getTime().toString().substring(11,13); 
 | 
            String previousHour = null; 
 | 
            Date previousTtime = null; 
 | 
            Double PM2_5 = null; 
 | 
            Double PM10 = null; 
 | 
            Double O3 = null; 
 | 
            Integer AQI = null; 
 | 
            String AQIIndex = null; 
 | 
            Double TVOC = null; 
 | 
            Double previousPM2_5 = null; 
 | 
            Double previousPM10 = null; 
 | 
            Double previousO3 = null; 
 | 
            String PM2_5_change = null; 
 | 
            String PM10_change = null; 
 | 
            String O3_change = null; 
 | 
            String value = cityAqiList.get(i).getValue(); 
 | 
            if (!ObjectUtils.isEmpty(value)){ 
 | 
                JSONObject jsonObject = JSONObject.parseObject(value); 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("PM2_5"))){ 
 | 
                    PM2_5 = Double.parseDouble(jsonObject.get("PM2_5").toString()); 
 | 
                } 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("PM10"))){ 
 | 
                    PM10 = Double.parseDouble(jsonObject.get("PM10").toString()); 
 | 
                } 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("O3"))){ 
 | 
                    O3 = Double.parseDouble(jsonObject.get("O3").toString()); 
 | 
                } 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("AQI"))){ 
 | 
                    AQI = Integer.parseInt(jsonObject.get("AQI").toString()); 
 | 
                    AQIIndex = AQIUtils.classCodeOfPollutionByAqi(AQI); 
 | 
                } 
 | 
            } 
 | 
            if (i<cityAqiList.size()-1){ 
 | 
                previousHour = cityAqiList.get(i+1).getTime().toString().substring(11,13); 
 | 
                previousTtime = cityAqiList.get(i+1).getTime(); 
 | 
                String previousValue = cityAqiList.get(i+1).getValue(); 
 | 
                if (!ObjectUtils.isEmpty(previousValue)){ 
 | 
                    JSONObject jsonObject = JSONObject.parseObject(previousValue); 
 | 
                    if (!ObjectUtils.isEmpty(jsonObject.get("PM2_5"))){ 
 | 
                        previousPM2_5 = Double.parseDouble(jsonObject.get("PM2_5").toString()); 
 | 
                    } 
 | 
                    if (!ObjectUtils.isEmpty(jsonObject.get("PM10"))){ 
 | 
                        previousPM10 = Double.parseDouble(jsonObject.get("PM10").toString()); 
 | 
                    } 
 | 
                    if (!ObjectUtils.isEmpty(jsonObject.get("O3"))){ 
 | 
                        previousO3 = Double.parseDouble(jsonObject.get("O3").toString()); 
 | 
                    } 
 | 
                } 
 | 
            }else if (cityAqiListNext.size()>0){ 
 | 
                previousHour = cityAqiListNext.get(0).getTime().toString().substring(11,13); 
 | 
                previousTtime = cityAqiListNext.get(0).getTime(); 
 | 
                String previousValue = cityAqiListNext.get(0).getValue(); 
 | 
                if (!ObjectUtils.isEmpty(previousValue)){ 
 | 
                    JSONObject jsonObject = JSONObject.parseObject(previousValue); 
 | 
                    if (!ObjectUtils.isEmpty(jsonObject.get("PM2_5"))){ 
 | 
                        previousPM2_5 = Double.parseDouble(jsonObject.get("PM2_5").toString()); 
 | 
                    } 
 | 
                    if (!ObjectUtils.isEmpty(jsonObject.get("PM10"))){ 
 | 
                        previousPM10 = Double.parseDouble(jsonObject.get("PM10").toString()); 
 | 
                    } 
 | 
                    if (!ObjectUtils.isEmpty(jsonObject.get("O3"))){ 
 | 
                        previousO3 = Double.parseDouble(jsonObject.get("O3").toString()); 
 | 
                    } 
 | 
                } 
 | 
            }else { 
 | 
                continue; 
 | 
            } 
 | 
            if (!ObjectUtils.isEmpty(PM2_5) && !ObjectUtils.isEmpty(previousPM2_5)){ 
 | 
                Double difference_PM2_5 = PM2_5-previousPM2_5; 
 | 
                if (difference_PM2_5==0){ 
 | 
                    PM2_5_change = "持平"; 
 | 
                } 
 | 
                if (difference_PM2_5>0){ 
 | 
                    PM2_5_change = "上升"+difference_PM2_5; 
 | 
                } 
 | 
                if (difference_PM2_5<0){ 
 | 
                    PM2_5_change = "下降"+Math.abs(difference_PM2_5); 
 | 
                } 
 | 
            } 
 | 
            if (!ObjectUtils.isEmpty(PM10) && !ObjectUtils.isEmpty(previousPM10)){ 
 | 
                Double difference_PM10 = PM10-previousPM10; 
 | 
                if (difference_PM10==0){ 
 | 
                    PM10_change = "持平"; 
 | 
                } 
 | 
                if (difference_PM10>0){ 
 | 
                    PM10_change = "上升"+difference_PM10; 
 | 
                } 
 | 
                if (difference_PM10<0){ 
 | 
                    PM10_change = "下降"+Math.abs(difference_PM10); 
 | 
                } 
 | 
            } 
 | 
            if (!ObjectUtils.isEmpty(O3) && !ObjectUtils.isEmpty(previousO3)){ 
 | 
                Double difference_O3 = O3-previousO3; 
 | 
                if (difference_O3==0){ 
 | 
                    O3_change = "持平"; 
 | 
                } 
 | 
                if (difference_O3>0){ 
 | 
                    O3_change = "上升"+difference_O3; 
 | 
                } 
 | 
                if (difference_O3<0){ 
 | 
                    O3_change = "下降"+Math.abs(difference_O3); 
 | 
                } 
 | 
            } 
 | 
            //定义一个集合,存放所有id 
 | 
            List<Integer> allOrgId = new ArrayList<>(); 
 | 
            allOrgId.add(orgId); 
 | 
            //循环集合 
 | 
            //所有子组织 
 | 
            List<Organization> allChildrenOrganization = organizationService.getChildrenOrganizationsById(orgId); 
 | 
            if (!ObjectUtils.isEmpty(allChildrenOrganization) || allChildrenOrganization.size() < 1){ 
 | 
                for (Organization organization:allChildrenOrganization) { 
 | 
                    allOrgId.add(organization.getId()); 
 | 
                } 
 | 
            } 
 | 
            //集合去重 
 | 
            List<Integer> allOrgIdWithoutDuplicates = allOrgId.stream().distinct().collect(Collectors.toList()); 
 | 
            //声明一个list,存放设备Mac 
 | 
            List<String> deviceMacList = new ArrayList<>(); 
 | 
            for (Integer orgIdWithoutDuplicates:allOrgIdWithoutDuplicates) { 
 | 
                //根据id查询所属设备 
 | 
                QueryWrapper<Device> wrapper_device = new QueryWrapper<>(); 
 | 
                wrapper_device.eq("is_delete",Constants.NOT_DELETE).eq("organization_id",orgIdWithoutDuplicates); 
 | 
                List<Device> devices = new ArrayList<>(); 
 | 
                devices = deviceMapper.selectList(wrapper_device); 
 | 
                if (devices.size()>0){ 
 | 
                    for (Device device:devices) { 
 | 
                        String deviceMac = device.getMac(); 
 | 
                        deviceMacList.add(deviceMac); 
 | 
                    } 
 | 
                }else { 
 | 
                    continue; 
 | 
                } 
 | 
            } 
 | 
            //获取时间 
 | 
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
 | 
            String time = df.format(cityAqiList.get(i).getTime()); 
 | 
            if (deviceMacList.size()>0){ 
 | 
                List<HistoryHourly> valueByMacs = historyHourlyService.getValueByMacs(deviceMacList, time); 
 | 
                if (valueByMacs.size()>0){ 
 | 
                    for (HistoryHourly historyHourly:valueByMacs) { 
 | 
                        String value_historyHourly = historyHourly.getValue(); 
 | 
                        if (!ObjectUtils.isEmpty(value_historyHourly)){ 
 | 
                            JSONObject jsonObject = JSONObject.parseObject(value_historyHourly); 
 | 
                            if (!ObjectUtils.isEmpty(jsonObject.get("a99054"))){ 
 | 
                                TVOC = Double.parseDouble(jsonObject.get("a99054").toString()); 
 | 
                            } 
 | 
                        } 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
            resultMap.put("time",time.substring(0,13)); 
 | 
            resultMap.put("title","【"+hour+"时数据提醒】"); 
 | 
            String PM2_5_string = subZeroAndDot(PM2_5.toString()); 
 | 
            String PM10_string = subZeroAndDot(PM10.toString()); 
 | 
            String O3_string = subZeroAndDot(O3.toString()); 
 | 
            String PM2_5_change_string = subZeroAndDot(PM2_5_change.toString()); 
 | 
            String PM10_change_string = subZeroAndDot(PM10_change.toString()); 
 | 
            String O3_change_string = subZeroAndDot(O3_change.toString()); 
 | 
            resultMap.put("info",hour+"时,我市AQI:"+AQI+",等级:"+AQIIndex+"。与"+previousHour+"时相比,PM10:"+PM10_string+"微克/立方米,"+PM10_change_string+";PM2.5:"+PM2_5_string+"微克/立方米,"+PM2_5_change_string+";TVOC总量:"+String.format("%.2f", TVOC)+"毫克/立方米;O3:"+O3_string+"微克/立方米,"+O3_change_string+"。"); 
 | 
            QueryWrapper<CityWeather> cityWeatherQueryWrapper = new QueryWrapper<>(); 
 | 
            cityWeatherQueryWrapper.eq("city_code",regionCode); 
 | 
            cityWeatherQueryWrapper.eq("time",cityAqiList.get(i).getTime()); 
 | 
            CityWeather cityWeather = cityWeatherService.getOne(cityWeatherQueryWrapper); 
 | 
            Integer temp = null; 
 | 
            Integer humidity = null; 
 | 
            String windDir = ""; 
 | 
            Integer windScale = null; 
 | 
            if (!ObjectUtils.isEmpty(cityWeather)){ 
 | 
                String cityWeatherValue = cityWeather.getValue(); 
 | 
                if (!ObjectUtils.isEmpty(cityWeatherValue)){ 
 | 
                    JSONObject jsonObject = JSONObject.parseObject(cityWeatherValue); 
 | 
                    if (!ObjectUtils.isEmpty(jsonObject.get("temp"))){ 
 | 
                        temp = Integer.parseInt(jsonObject.get("temp").toString()); 
 | 
                    } 
 | 
                    if (!ObjectUtils.isEmpty(jsonObject.get("humidity"))){ 
 | 
                        humidity = Integer.parseInt(jsonObject.get("humidity").toString()); 
 | 
                    } 
 | 
                    if (!ObjectUtils.isEmpty(jsonObject.get("windDir"))){ 
 | 
                        windDir = jsonObject.get("windDir").toString(); 
 | 
                    } 
 | 
                    if (!ObjectUtils.isEmpty(jsonObject.get("windScale"))){ 
 | 
                        windScale = Integer.parseInt(jsonObject.get("windScale").toString()); 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
            String temp_string = ""; 
 | 
            if (temp!=null){ 
 | 
                temp_string = temp.toString(); 
 | 
            } 
 | 
            String humidity_string = ""; 
 | 
            if (humidity!=null){ 
 | 
                humidity_string = humidity.toString(); 
 | 
            } 
 | 
            String windScale_string = ""; 
 | 
            if (windScale!=null){ 
 | 
                windScale_string = windScale.toString(); 
 | 
            } 
 | 
            resultMap.put("weatherCondition","当前天气状况:温度"+temp_string+"℃,湿度"+humidity_string+"%,"+windDir+windScale_string+"级。"); 
 | 
            resultMap.put("auther","(七星瓢虫专家组)"); 
 | 
            resultList.add(resultMap); 
 | 
        } 
 | 
        Integer totel = count-1; 
 | 
        result.put("totel",totel); 
 | 
        result.put("resultList",resultList); 
 | 
        result.put("current",current); 
 | 
        int totalPageNumber = totel/size; 
 | 
        if(totel%size != 0){ 
 | 
            totalPageNumber += 1; 
 | 
        } 
 | 
        result.put("totalPageNumber",totalPageNumber); 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public Map<String, Object> countyData(Integer regionCode) { 
 | 
        Map<String,Object> resultMap = new HashMap<>(); 
 | 
        //获取时间 
 | 
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH"); 
 | 
        Calendar calendar = Calendar.getInstance(); 
 | 
        int minute = calendar.get(Calendar.MINUTE); 
 | 
        if (minute >= 45){ 
 | 
            calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-1); 
 | 
        }else { 
 | 
            calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-2); 
 | 
        } 
 | 
        String time = df.format(calendar.getTime())+":00:00"; 
 | 
        QueryWrapper<CityAqi> cityAqiQueryWrapper = new QueryWrapper<>(); 
 | 
        cityAqiQueryWrapper.likeRight("city_code",regionCode.toString().substring(0,4)); 
 | 
        cityAqiQueryWrapper.ne("city_code",regionCode); 
 | 
        cityAqiQueryWrapper.eq("time",time); 
 | 
        List<CityAqi> cityAqis = cityAqiMapper.selectList(cityAqiQueryWrapper); 
 | 
        QueryWrapper<SysArea> sysAreaQueryWrapper = new QueryWrapper<>(); 
 | 
        sysAreaQueryWrapper.eq("parent_code",regionCode); 
 | 
        List<SysArea> sysAreas = sysAreaMapper.selectList(sysAreaQueryWrapper); 
 | 
        Map<Integer, Object> sysAreaMap = new HashMap<>(); 
 | 
        for (SysArea sysarea:sysAreas) { 
 | 
            sysAreaMap.put(sysarea.getAreaCode(),sysarea.getAreaName()); 
 | 
        } 
 | 
        List<Map<String,Object>> resultList = new ArrayList<>(); 
 | 
        for (CityAqi cityAqi:cityAqis) { 
 | 
            if (!ObjectUtils.isEmpty(cityAqi.getValue())){ 
 | 
                Map<String, Object> cityAqiMap = new HashMap<>(); 
 | 
                String cityAqiValue = cityAqi.getValue(); 
 | 
                JSONObject jsonObject = JSONObject.parseObject(cityAqiValue); 
 | 
                String AQI = "--"; 
 | 
                String PM10 = "--"; 
 | 
                String PM2_5 = "--"; 
 | 
                String SO2 = "--"; 
 | 
                String NO2 = "--"; 
 | 
                String CO = "--"; 
 | 
                String O3 = "--"; 
 | 
                String thirty = "--"; 
 | 
                String forty = "--"; 
 | 
                String fifty = "--"; 
 | 
                String city_name = "--"; 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("AQI"))){ 
 | 
                    AQI = jsonObject.get("AQI").toString(); 
 | 
                    BigDecimal AQI_base = BigDecimal.valueOf(Double.parseDouble(AQI)); 
 | 
                    BigDecimal thirty_percent = BigDecimal.valueOf(1.3); 
 | 
                    BigDecimal forty_percent = BigDecimal.valueOf(1.4); 
 | 
                    BigDecimal fifty_percent = BigDecimal.valueOf(1.5); 
 | 
                    Double AQI_thirty = AQI_base.multiply(thirty_percent).doubleValue(); 
 | 
                    Double AQI_forty = AQI_base.multiply(forty_percent).doubleValue(); 
 | 
                    Double AQI_fifty = AQI_base.multiply(fifty_percent).doubleValue(); 
 | 
                    thirty = String.valueOf(Math.round(AQI_thirty)); 
 | 
                    forty = String.valueOf(Math.round(AQI_forty)); 
 | 
                    fifty = String.valueOf(Math.round(AQI_fifty)); 
 | 
                } 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("PM10"))){ 
 | 
                    PM10 = String.valueOf(Math.round(Double.parseDouble(jsonObject.get("PM10").toString()))); 
 | 
                } 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("PM2_5"))){ 
 | 
                    PM2_5 = String.valueOf(Math.round(Double.parseDouble(jsonObject.get("PM2_5").toString()))); 
 | 
                } 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("SO2"))){ 
 | 
                    SO2 = String.valueOf(Math.round(Double.parseDouble(jsonObject.get("SO2").toString()))); 
 | 
                } 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("NO2"))){ 
 | 
                    NO2 = String.valueOf(Math.round(Double.parseDouble(jsonObject.get("NO2").toString()))); 
 | 
                } 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("CO"))){ 
 | 
                    CO = String.valueOf(Math.round(Double.parseDouble(jsonObject.get("CO").toString()))); 
 | 
                } 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("O3"))){ 
 | 
                    O3 = String.valueOf(Math.round(Double.parseDouble(jsonObject.get("O3").toString()))); 
 | 
                } 
 | 
                if (!ObjectUtils.isEmpty(jsonObject.get("cityName"))){ 
 | 
                    city_name = jsonObject.get("cityName").toString(); 
 | 
                } 
 | 
                cityAqiMap.put("AQI",AQI); 
 | 
                cityAqiMap.put("PM10",PM10); 
 | 
                cityAqiMap.put("PM2_5",PM2_5); 
 | 
                cityAqiMap.put("SO2",SO2); 
 | 
                cityAqiMap.put("NO2",NO2); 
 | 
                cityAqiMap.put("CO",CO); 
 | 
                cityAqiMap.put("O3",O3); 
 | 
                cityAqiMap.put("thirty",thirty); 
 | 
                cityAqiMap.put("forty",forty); 
 | 
                cityAqiMap.put("fifty",fifty); 
 | 
                cityAqiMap.put("city_name",city_name); 
 | 
                resultList.add(cityAqiMap); 
 | 
            } 
 | 
            sysAreaMap.remove(cityAqi.getCityCode()); 
 | 
        } 
 | 
        if (sysAreaMap.size()>0){ 
 | 
            for(Integer key:sysAreaMap.keySet()){ 
 | 
                Map<String,Object> nullMap = new HashMap<>(); 
 | 
                nullMap.put("AQI","--"); 
 | 
                nullMap.put("PM10","--"); 
 | 
                nullMap.put("PM2_5","--"); 
 | 
                nullMap.put("SO2","--"); 
 | 
                nullMap.put("NO2","--"); 
 | 
                nullMap.put("CO","--"); 
 | 
                nullMap.put("O3","--"); 
 | 
                nullMap.put("thirty","--"); 
 | 
                nullMap.put("forty","--"); 
 | 
                nullMap.put("fifty","--"); 
 | 
                nullMap.put("city_name",sysAreaMap.get(key)); 
 | 
                resultList.add(nullMap); 
 | 
            } 
 | 
        } 
 | 
        resultMap.put("resultList",resultList); 
 | 
        resultMap.put("time",time); 
 | 
        QueryWrapper<SysArea> areaQueryWrapper = new QueryWrapper<>(); 
 | 
        areaQueryWrapper.eq("area_code",regionCode); 
 | 
        SysArea sysArea = sysAreaMapper.selectOne(areaQueryWrapper); 
 | 
        resultMap.put("areaName",sysArea.getAreaName()); 
 | 
        return resultMap; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @Description: 计算6参和综合指数对比的百分比 
 | 
     * @Param: [data, comparisonData] 
 | 
     * @return: java.util.Map<java.lang.String, com.moral.api.pojo.dto.cityAQI.ConcentrationAndPercent> 
 | 
     * @Author: 陈凯裕 
 | 
     * @Date: 2022/1/17 
 | 
     */ 
 | 
    private Map<String, ConcentrationAndPercent> contrastSixParamAndComIndex(Map<String, Object> data, Map<String, Object> comparisonData) { 
 | 
        Map<String, ConcentrationAndPercent> result = new HashMap<>(); 
 | 
        result.put("CO", contrastParam(Double.parseDouble(data.get("CO").toString()), Double.parseDouble(comparisonData.get("CO").toString()), "CO")); 
 | 
        result.put("NO2", contrastParam(Double.parseDouble(data.get("NO2").toString()), Double.parseDouble(comparisonData.get("NO2").toString()), "NO2")); 
 | 
        result.put("SO2", contrastParam(Double.parseDouble(data.get("SO2").toString()), Double.parseDouble(comparisonData.get("SO2").toString()), "SO2")); 
 | 
        result.put("O3", contrastParam(Double.parseDouble(data.get("O3").toString()), Double.parseDouble(comparisonData.get("O3").toString()), "O3")); 
 | 
        result.put("PM2_5", contrastParam(Double.parseDouble(data.get("PM2_5").toString()), Double.parseDouble(comparisonData.get("PM2_5").toString()), "PM2_5")); 
 | 
        result.put("PM10", contrastParam(Double.parseDouble(data.get("PM10").toString()), Double.parseDouble(comparisonData.get("PM10").toString()), "PM10")); 
 | 
        result.put("compositeIndex", contrastParam(Double.parseDouble(data.get("compositeIndex").toString()), Double.parseDouble(comparisonData.get("compositeIndex").toString()), "compositeIndex")); 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @Description: 计算6参和综合指数同比/环比百分比数据 
 | 
     * @Param: [data, comparisonData] 
 | 
     * @return: com.moral.api.pojo.dto.cityAQI.ConcentrationAndPercent 
 | 
     * @Author: 陈凯裕 
 | 
     * @Date: 2022/1/17 
 | 
     */ 
 | 
    private ConcentrationAndPercent contrastParam(Double data, Double comparisonData, String sensor) { 
 | 
        double percentD = MathUtils.division(data - comparisonData, comparisonData, 4); 
 | 
        String percent = MathUtils.mul(percentD,100d) + "%"; 
 | 
        ConcentrationAndPercent concentrationAndPercent = new ConcentrationAndPercent(); 
 | 
        concentrationAndPercent.setPercent(percent); 
 | 
        if (sensor.equals("CO")) {//CO小数点保留一位 
 | 
            Double CO = AmendUtils.sciCal(data, 1); 
 | 
            concentrationAndPercent.setConcentration(CO.toString()); 
 | 
        }else if (sensor.equals("compositeIndex")){ 
 | 
            concentrationAndPercent.setConcentration(data.toString()); 
 | 
        }else{ 
 | 
            Double sensorD = AmendUtils.sciCal(data, 0); 
 | 
            Integer sensorI = new Double(sensorD).intValue(); 
 | 
            concentrationAndPercent.setConcentration(sensorI.toString()); 
 | 
        } 
 | 
        return concentrationAndPercent; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @Description: 对比天数,返回天数差值 
 | 
     * @Param: [days, comparisonDays] 
 | 
     * @return: com.moral.api.pojo.dto.cityAQI.ConcentrationAndPercent 
 | 
     * @Author: 陈凯裕 
 | 
     * @Date: 2022/1/17 
 | 
     */ 
 | 
    private ConcentrationAndPercent contrastDays(Integer days, Integer comparisonDays) { 
 | 
        ConcentrationAndPercent concentrationAndPercent = new ConcentrationAndPercent(); 
 | 
        concentrationAndPercent.setConcentration(days.toString()); 
 | 
        Integer result = days - comparisonDays; 
 | 
        concentrationAndPercent.setPercent(result.toString() + "天"); 
 | 
        return concentrationAndPercent; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @Description: 根据时间类型查询对应的6参以及综合指数,自定义时间类型用日数据做均值处理 
 | 
     * @Param: [comparisonType, startDate, endDate, regionCode] 
 | 
     * @return: java.util.Map<java.lang.String                                                               ,                                                               java.lang.Object> 
 | 
     * @Author: 陈凯裕 
 | 
     * @Date: 2022/1/17 
 | 
     */ 
 | 
    private Map<String, Object> getDataByTimeTypeAndRegionCode(String TimeType, Date startDate, Date endDate, Integer regionCode) { 
 | 
        Map<String, Object> data; 
 | 
        if (Constants.MONTH.equals(TimeType) && (!DateUtils.isCurrentMonth(startDate) || !DateUtils.isCurrentYear(startDate))) {//月数据处理 不包括本月 
 | 
            List<CityAqiMonthly> cityAqis = cityAqiMonthlyService.getCityAqiMonthByRegionCodeAndTime(regionCode, startDate, endDate); 
 | 
            if (ObjectUtils.isEmpty(cityAqis)) 
 | 
                return null; 
 | 
            data = JSON.parseObject(cityAqis.get(0).getValue(), Map.class); 
 | 
        } else if (Constants.YEAR.equals(TimeType) && (!DateUtils.isCurrentYear(startDate))) {//年数据处理 不包括本年 
 | 
            List<CityAqiYearly> cityAqis = cityAqiYearlyService.getCityAqiYearlyByRegionCodeAndTime(regionCode, startDate, endDate); 
 | 
            if (ObjectUtils.isEmpty(cityAqis)) 
 | 
                return null; 
 | 
            data = JSON.parseObject(cityAqis.get(0).getValue(), Map.class); 
 | 
        } else {//自定义数据处理 
 | 
            List<CityAqiDaily> cityAqis = cityAqiDailyService.getCityAqiDailyByRegionCodeAndTime(regionCode, startDate, endDate); 
 | 
            if (ObjectUtils.isEmpty(cityAqis)) 
 | 
                return null; 
 | 
            List<CityAqi> newCityAqis = new ArrayList<>(); 
 | 
            List<Map<String, Object>> dailyDataMaps = new ArrayList<>(); 
 | 
            cityAqis.forEach((value) -> { 
 | 
                newCityAqis.add(new CityAqi(value)); 
 | 
                dailyDataMaps.add(JSON.parseObject(value.getValue(), Map.class)); 
 | 
            }); 
 | 
            //计算均值 
 | 
            data = calculate6ParamAvg(newCityAqis); 
 | 
            //小数点处理 
 | 
            data.put("CO", Double.parseDouble(data.remove(Constants.SENSOR_CODE_CO).toString())); 
 | 
            data.put("NO2", Double.parseDouble(data.remove(Constants.SENSOR_CODE_NO2).toString())); 
 | 
            data.put("SO2", Double.parseDouble(data.remove(Constants.SENSOR_CODE_SO2).toString())); 
 | 
            data.put("O3", Double.parseDouble(data.remove(Constants.SENSOR_CODE_O3).toString())); 
 | 
            data.put("PM2_5", Double.parseDouble(data.remove(Constants.SENSOR_CODE_PM25).toString())); 
 | 
            data.put("PM10", Double.parseDouble(data.remove(Constants.SENSOR_CODE_PM10).toString())); 
 | 
            //计算综合指数 
 | 
            Double compositeIndex = ComprehensiveIndexUtils.dailyData(data); 
 | 
            data.put("compositeIndex", compositeIndex); 
 | 
        } 
 | 
        return data; 
 | 
    } 
 | 
  
 | 
  
 | 
    //按某字段排序 
 | 
    private void sortByField(List<Map<String, Object>> list, String sortField) { 
 | 
        list.sort((o1, o2) -> { 
 | 
            double v1 = Double.parseDouble(o1.get(sortField).toString()); 
 | 
            double v2 = Double.parseDouble(o2.get(sortField).toString()); 
 | 
            if (v1 > v2) { 
 | 
                return -1; 
 | 
            } else if (v1 < v2) { 
 | 
                return 1; 
 | 
            } 
 | 
            return 0; 
 | 
        }); 
 | 
    } 
 | 
  
 | 
    //排名 
 | 
    private Map<String, Object> rankByField(List<Map<String, Object>> list, Integer cityCode, String rankField, Integer size) { 
 | 
        Map<String, Object> result = new HashMap<>(); 
 | 
        for (int i = 0; i < list.size(); i++) { 
 | 
            Map<String, Object> map = list.get(i); 
 | 
            if (cityCode == (int) map.get("cityCode")) { 
 | 
                int rank = i + 1; 
 | 
                result.put("rank", rank); 
 | 
                result.put("size", size); 
 | 
                Object value = map.get(rankField); 
 | 
                result.put("value", value); 
 | 
                break; 
 | 
            } 
 | 
        } 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @Description: 根据类型和地区码获取所有的城市或者区县 
 | 
     * @Param: [regionType, regionCode] 
 | 
     * @return: java.util.List<com.moral.api.entity.SysArea> 
 | 
     * @Author: 陈凯裕 
 | 
     * @Date: 2022/1/14 
 | 
     */ 
 | 
    private List<SysArea> getSysAreasByRegionType(String regionType, Integer regionCode) { 
 | 
        List<SysArea> areas; 
 | 
        if (regionType.equals(Constants.TWENTY_EIGHT_CITIES)) { 
 | 
            areas = citiesProperties.getTwentyEightCities(); 
 | 
        } else { 
 | 
            areas = sysAreaService.getChildren(regionCode); 
 | 
        } 
 | 
        return areas; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @Description: 计算6参平均值 
 | 
     * @Param: [cityAqiList] 
 | 
     * @return: java.util.Map<java.lang.String                                                               ,                                                                                                                               java.lang.Double> 
 | 
     * 返回值key为sensorCode,value为值 
 | 
     * @Author: 陈凯裕 
 | 
     * @Date: 2021/11/2 
 | 
     */ 
 | 
    private Map<String, Object> calculate6ParamAvg(List<CityAqi> cityAqiList) { 
 | 
        Double co = calculateSensorAvg(cityAqiList, "CO"); 
 | 
        Double pm2_5 = calculateSensorAvg(cityAqiList, "PM2_5"); 
 | 
        Double pm10 = calculateSensorAvg(cityAqiList, "PM10"); 
 | 
        Double so2 = calculateSensorAvg(cityAqiList, "SO2"); 
 | 
        Double no2 = calculateSensorAvg(cityAqiList, "NO2"); 
 | 
        Double o3 = calculateSensorAvg(cityAqiList, "O3"); 
 | 
        Map<String, Object> result = new HashMap<>(); 
 | 
        result.put(Constants.SENSOR_CODE_CO, co); 
 | 
        result.put(Constants.SENSOR_CODE_NO2, no2); 
 | 
        result.put(Constants.SENSOR_CODE_SO2, so2); 
 | 
        result.put(Constants.SENSOR_CODE_O3, o3); 
 | 
        result.put(Constants.SENSOR_CODE_PM25, pm2_5); 
 | 
        result.put(Constants.SENSOR_CODE_PM10, pm10); 
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @Description: 计算因子的平均值 
 | 
     * @Param: [cityAqiList, sensor] 
 | 
     * ,sensor是要计算的因子名称 
 | 
     * @return: java.lang.Double 
 | 
     * @Author: 陈凯裕 
 | 
     * @Date: 2021/11/2 
 | 
     */ 
 | 
    private Double calculateSensorAvg(List<CityAqi> cityAqiList, String sensor) { 
 | 
        Double sum = 0d; 
 | 
        int num = 0; 
 | 
        for (CityAqi cityAqi : cityAqiList) { 
 | 
            String value = cityAqi.getValue(); 
 | 
            if (value == null) 
 | 
                continue; 
 | 
            Map<String, Object> valueMap = JSON.parseObject(value, Map.class); 
 | 
            Object sensorValueObject = valueMap.get(sensor); 
 | 
            if (sensorValueObject == null) 
 | 
                continue; 
 | 
            Double sensorValue = Double.valueOf(sensorValueObject.toString()); 
 | 
            sum = MathUtils.add(sum, sensorValue); 
 | 
            num++; 
 | 
        } 
 | 
        if (num == 0) 
 | 
            return null; 
 | 
        Double avg = MathUtils.division(sum, num, 2); 
 | 
        return avg; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 使用java正则表达式去掉多余的.与0 
 | 
     * @param s 
 | 
     * @return 
 | 
     */ 
 | 
    public static String subZeroAndDot(String s){ 
 | 
        if(s.indexOf(".") > 0){ 
 | 
            s = s.replaceAll("0+?$", "");//去掉多余的0 
 | 
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉 
 | 
        } 
 | 
        return s; 
 | 
    } 
 | 
  
 | 
    public  List<Map<String, Object>> getO3_8H(List<Map<String, Object>> data , int type,String day) { 
 | 
        List<Map<String, Object>> list = new ArrayList<>(); 
 | 
        for(int i = 0 ;i<=23;i++){ 
 | 
            Map<String, Object> map = new HashMap<>(); 
 | 
            if(type == 0){ 
 | 
                map.put("type","预测"); 
 | 
            }else { 
 | 
                map.put("type","实测"); 
 | 
            } 
 | 
            String times = day+" "+i; 
 | 
            Date endDate = DateUtils.getDate(times,DateUtils.yyyy_MM_dd_HH_EN); 
 | 
            Date startDate = DateUtils.addHours(DateUtils.getDate(day+" "+i,DateUtils.yyyy_MM_dd_HH_EN),-7); 
 | 
            List<Double> value = new ArrayList<>(); 
 | 
            for(Map<String, Object> m : data){ 
 | 
                Date time = (Date) m.get("time"); 
 | 
                if(DateUtils.isTimeBeforE(time,startDate) && DateUtils.isTimeBeforE(endDate,time)){ 
 | 
                    Map<String, Object> sensorValue = JSONObject.parseObject((String) m.get("value"), Map.class); 
 | 
                    Double o3 = Double.parseDouble(sensorValue.get("O3").toString()); 
 | 
                    value.add(o3); 
 | 
  
 | 
                } 
 | 
            } 
 | 
            if (value.size() < 6) { 
 | 
                continue; 
 | 
            } 
 | 
            double average = value.stream().mapToDouble(aDouble -> aDouble).summaryStatistics().getAverage(); 
 | 
            map.put("O3", new BigDecimal(average).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue()); 
 | 
            map.put("time",times); 
 | 
            list.add(map); 
 | 
        } 
 | 
  
 | 
        return list; 
 | 
  
 | 
    } 
 | 
  
 | 
} 
 |