package com.zhgd.xmgl.util; import cn.hutool.http.HttpException; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.gexin.fastjson.JSON; import com.zhgd.redis.lock.RedisRepository; import com.zhgd.xmgl.modules.basicdata.entity.SystemCities; import com.zhgd.xmgl.modules.basicdata.mapper.SystemCitiesMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; /** * @program: wisdomSite * @description: 空气质量分析AQI * @author: Mr.Peng * @create: 2020-09-28 09:56 **/ @Slf4j @Component public class AqiUtil { private static SystemCitiesMapper systemCitiesMapper; private static RedisRepository redisRepository; public static String SYSTEM_CITIES_KEY = "SYSTEM_CITIES"; public static String WEATHER_DATA = "WEATHER_DATA:"; private static String tianqiUrl; /** * 天气质量 */ public static String WEATHER_QUALITY = "WEATHER_QUALITY:"; @Value("${tianqiUrl}") public void setTianqiUrl(String tianqiUrl) { AqiUtil.tianqiUrl = tianqiUrl; } @Autowired public void setSystemCitiesMapper(SystemCitiesMapper systemCitiesMapper) { AqiUtil.systemCitiesMapper = systemCitiesMapper; } @Autowired public void setRedisRepository(RedisRepository redisRepository) { AqiUtil.redisRepository = redisRepository; } /** * 计算aqi值对应的等级 * * @param aqi * @return */ public static int getPollutionDegree(Double aqi) { int pollutionDegree = 1; if (aqi <= 50) { pollutionDegree = 1; } else if (aqi > 50 && aqi <= 100) { pollutionDegree = 2; } else if (aqi > 100 && aqi <= 150) { pollutionDegree = 3; } else if (aqi > 150 && aqi <= 200) { pollutionDegree = 4; } else if (aqi > 200 && aqi <= 300) { pollutionDegree = 5; } else if (aqi > 300) { pollutionDegree = 6; } return pollutionDegree; } /** * @param @param pollutionDegree * @param @return * @return String @throws * @Title: getDegree * @Description: 计算aqi值对应的等级 */ public static String getDegree(int pollutionDegree) { if (pollutionDegree == 1) { return "优"; } else if (pollutionDegree == 2) { return "良"; } else if (pollutionDegree == 3) { return "轻度污染"; } else if (pollutionDegree == 4) { return "中度污染"; } else if (pollutionDegree == 5) { return "重度污染"; } else if (pollutionDegree == 6) { return "严重污染"; } return "数据错误"; } /** * 计算每种污染物项目 P的空气质量分指数 * * @param cp 污染物项目P的质量浓度 * @param r 污染物项目P所在数组中的行号 * @return */ public static double countPerIaqi(double cp, int r) { double bph = 0; // 与 cp相近的污染物浓度限值的高位值 double bpl = 0; // 与 cp相近的污染物浓度限值的低位值 double iaqih = 0; // 与 bph对应的空气质量分指数 double iaqil = 0; // 与 bpl对应的空气质量分指数 double iaqip = 0; // 当前污染物项目P的空气质量分指数 // 空气质量分指数及对应的污染物项目浓度限值 int[][] aqiArr = {{0, 50, 100, 150, 200, 300, 400, 500}, {0, 35, 75, 115, 150, 250, 350, 500}, {0, 50, 150, 250, 350, 420, 500, 600}, {0, 2, 4, 14, 24, 36, 48, 60}, {0, 40, 80, 180, 280, 565, 750, 940}, {0, 160, 200, 300, 400, 800, 1000, 1200}, {0, 50, 150, 475, 800, 1600, 2100, 2620}, {0, 100, 160, 215, 265, 800}}; double min = aqiArr[r][0]; int index = aqiArr[r].length - 1; double max = aqiArr[r][index]; if (cp <= min || cp >= max) { return 0; } else { // 对每种污染物的bph、bpl、iaqih、iaqil进行赋值 for (int i = r; i < r + 1; i++) { for (int j = 0; j < aqiArr[0].length; j++) { if (cp < aqiArr[i][j]) { bph = aqiArr[i][j]; bpl = aqiArr[i][j - 1]; iaqih = aqiArr[0][j]; iaqil = aqiArr[0][j - 1]; break; } } } // 计算污染物项目 P的空气质量分指数 iaqip = (iaqih - iaqil) / (bph - bpl) * (cp - bpl) + iaqil; BigDecimal bg = new BigDecimal(Math.ceil(iaqip)); double f1 = bg.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue(); return f1; } } public static double getPm10IAQI(double pmte) { if (pmte > 0) { long round = Math.round(pmte); return countPerIaqi(round, 2); } return 0; } public static double getPm25IAQI(double pmtw) { if (pmtw > 0) { long round = Math.round(pmtw); return countPerIaqi(round, 1); } return 0; } /** * 根据城市查询天气 * * @param cityCode 城市ID * @return */ public static Double getWeatherInfo(String cityCode) { List systemCities = redisRepository.getOrSet(SYSTEM_CITIES_KEY, () -> systemCitiesMapper.selectList(null), 60 * 60L); String key = WEATHER_QUALITY + cityCode; Object ro = redisRepository.get(key); if (ro != null) { return (Double) ro; } Map cityIdMap = systemCities.stream().collect(Collectors.toMap(e -> e.getCityid(), Function.identity(), (o, o2) -> o)); //空气指数 Double air = null; try { Map param = new HashMap<>(); param.put("appid", "41289558"); param.put("appsecret", "45CS7niV"); String cityId = Optional.ofNullable(cityIdMap.get(cityCode)).map(e -> e.getWeathercityid()).orElse(null); if (StringUtils.isNotBlank(cityId)) { param.put("cityid", cityId); } String result = HttpUtil.get("https://v0.yiketianqi.com/free/day", param, 5000); if (result != null && result.length() > 0) { JSONObject obj = JSONObject.parseObject(result); if (obj != null && obj.getString("air") != null) { air = Double.valueOf(obj.getString("air")); } } } catch (Exception e) { e.printStackTrace(); } if (air == null) { air = 80d; } redisRepository.set(key, air, 60 * 60L); return air; } public static String getWeatherData(String cityid) { String result = ""; try { result = redisRepository.getOrSet(WEATHER_DATA + cityid, () -> { Map param = new HashMap<>(); param.put("unescape", "1"); //param.put("appid", "79112751"); //param.put("appsecret", "EBqjU987"); param.put("appid", "41289558"); param.put("appsecret", "45CS7niV"); if (StringUtils.isNotEmpty(cityid)) { param.put("cityid", cityid); } String r = HttpUtil.get(tianqiUrl, param); JSONObject jsonObject = JSONObject.parseObject(r); JSONArray sevenDataArr = jsonObject.getJSONArray("data"); for (Object o : sevenDataArr) { JSONObject jo = (JSONObject) o; jo.put("cityid", jsonObject.get("cityid")); jo.put("city", jsonObject.get("city")); jo.put("cityEn", jsonObject.get("cityEn")); jo.put("country", jsonObject.get("country")); jo.put("countryEn", jsonObject.get("countryEn")); jo.put("update_time", jsonObject.get("update_time")); jo.put("tem1", jo.get("tem_day")); jo.put("tem2", jo.get("tem_night")); jo.put("day", jo.get("date")); } r = JSON.toJSONString(sevenDataArr); log.info(r); return r; }, 60 * 60L); } catch (Exception e) { e.printStackTrace(); result = "[{\"date\":\"2023-12-11\",\"tem_day\":\"29\",\"tem2\":\"20\",\"tem1\":\"29\",\"city\":\"深圳\",\"tem_night\":\"20\",\"cityid\":\"101280601\",\"wea\":\"多云\",\"update_time\":\"2023-12-11 10:47:17\",\"wea_img\":\"yun\",\"win_speed\":\"<3级\",\"win\":\"无持续风向\",\"day\":\"2023-12-11\"},{\"date\":\"2023-12-12\",\"tem_day\":\"27\",\"tem2\":\"20\",\"tem1\":\"27\",\"city\":\"深圳\",\"tem_night\":\"20\",\"cityid\":\"101280601\",\"wea\":\"多云转阴\",\"update_time\":\"2023-12-11 10:47:17\",\"wea_img\":\"yun\",\"win_speed\":\"<3级转3-4级\",\"win\":\"无持续风向\",\"day\":\"2023-12-12\"},{\"date\":\"2023-12-13\",\"tem_day\":\"25\",\"tem2\":\"20\",\"tem1\":\"25\",\"city\":\"深圳\",\"tem_night\":\"20\",\"cityid\":\"101280601\",\"wea\":\"多云\",\"update_time\":\"2023-12-11 10:47:17\",\"wea_img\":\"yun\",\"win_speed\":\"3-4级转<3级\",\"win\":\"东风\",\"day\":\"2023-12-13\"},{\"date\":\"2023-12-14\",\"tem_day\":\"26\",\"tem2\":\"23\",\"tem1\":\"26\",\"city\":\"深圳\",\"tem_night\":\"23\",\"cityid\":\"101280601\",\"wea\":\"阴\",\"update_time\":\"2023-12-11 10:47:17\",\"wea_img\":\"yin\",\"win_speed\":\"3-4级转<3级\",\"win\":\"东风\",\"day\":\"2023-12-14\"},{\"date\":\"2023-12-15\",\"tem_day\":\"28\",\"tem2\":\"16\",\"tem1\":\"28\",\"city\":\"深圳\",\"tem_night\":\"16\",\"cityid\":\"101280601\",\"wea\":\"多云转阴\",\"update_time\":\"2023-12-11 10:47:17\",\"wea_img\":\"yun\",\"win_speed\":\"<3级\",\"win\":\"无持续风向\",\"day\":\"2023-12-15\"},{\"date\":\"2023-12-16\",\"tem_day\":\"25\",\"tem2\":\"11\",\"tem1\":\"25\",\"city\":\"深圳\",\"tem_night\":\"11\",\"cityid\":\"101280601\",\"wea\":\"阴\",\"update_time\":\"2023-12-11 10:47:17\",\"wea_img\":\"yin\",\"win_speed\":\"3-4级\",\"win\":\"东北风\",\"day\":\"2023-12-16\"},{\"date\":\"2023-12-17\",\"tem_day\":\"15\",\"tem2\":\"10\",\"tem1\":\"15\",\"city\":\"深圳\",\"tem_night\":\"10\",\"cityid\":\"101280601\",\"wea\":\"小雨\",\"update_time\":\"2023-12-11 10:47:17\",\"wea_img\":\"yu\",\"win_speed\":\"3-4级\",\"win\":\"北风\",\"day\":\"2023-12-17\"}]"; } return result; } public static void main(String[] args) { /*double temp=getPm25IAQI(85d); log.info(temp); log.info(getDegree(getPollutionDegree(temp)));*/ //log.info(getWeatherInfo("110100")); //log.info(getWeatherData("110100")); //System.out.println(getWeatherInfo("11")); //log.info(getDegree(getPollutionDegree(39d))); try { String result = HttpUtil.get("https://v0.yiketianqi.com/free/day", 1000); } catch (HttpException e) { e.printStackTrace(); } System.out.println(123); } }