| | |
| | | package cn.gistack.sm.sjztmd.service.impl; |
| | | |
| | | import cn.gistack.sm.intelligentCall.mapper.CallTaskMapper; |
| | | import cn.gistack.sm.sjztmd.constant.RainfallConstant; |
| | | import cn.gistack.sm.sjztmd.dto.AttResBaseUserDTO; |
| | | import cn.gistack.sm.sjztmd.entity.AttAdBase; |
| | | import cn.gistack.sm.sjztmd.entity.AttResBase; |
| | |
| | | import cn.gistack.sm.sjztmd.service.IRelResLabelService; |
| | | import cn.gistack.sm.sjztmd.vo.*; |
| | | import cn.gistack.system.feign.ISysClient; |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.dynamic.datasource.annotation.DS; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.fasterxml.jackson.core.JsonProcessingException; |
| | | import com.fasterxml.jackson.databind.JsonNode; |
| | | import cn.hutool.http.HttpRequest; |
| | | import cn.hutool.http.HttpResponse; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springblade.core.log.exception.ServiceException; |
| | | import org.springblade.core.secure.BladeUser; |
| | | import org.springblade.core.secure.utils.AuthUtil; |
| | | import org.springblade.core.tool.utils.DateUtil; |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @ClassName AttResBaseServiceImpl |
| | |
| | | * @Date 2023/4/21 20:01 |
| | | * @Version 1.0 |
| | | */ |
| | | |
| | | @Slf4j |
| | | @Service |
| | | @DS("zt") |
| | | public class AttResBaseServiceImpl extends ServiceImpl<AttResBaseMapper, AttResBase> implements IAttResBaseService { |
| | | private static final ObjectMapper objectMapper = new ObjectMapper(); |
| | | |
| | | @Autowired |
| | | private CallTaskMapper callTaskMapper; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<AttResWithRainfall> getAttResByRainfall(String minRainfall, String maxRainfall, String dayIndex) { |
| | | if (StrUtil.isNotEmpty(dayIndex) && !Arrays.asList(0,1,2).contains(Integer.parseInt(dayIndex))) { |
| | | throw new ServiceException("无效的dayIndex"); |
| | | } |
| | | Double minRainfallDouble = null; |
| | | Double maxRainfallDouble = null; |
| | | if (StrUtil.isNotEmpty(minRainfall)) { |
| | | minRainfallDouble = Double.parseDouble(minRainfall); |
| | | } |
| | | if (StrUtil.isNotEmpty(minRainfall)) { |
| | | maxRainfallDouble = Double.parseDouble(maxRainfall); |
| | | } |
| | | // 调用气象预报服务接口 |
| | | String resJsonNodeStr; |
| | | try (HttpResponse httpResponse = HttpRequest.post(RainfallConstant.FORECAST_SERVICE_URL) |
| | | .header("Content-Type", "application/json") |
| | | .header("X-token", RainfallConstant.X_TOKEN) |
| | | .contentType("application/json") |
| | | .body(String.format(RainfallConstant.REQUEST_JSON_BODY, StrUtil.isEmpty(dayIndex) ? "0" : dayIndex)).execute()) { |
| | | JsonNode resJsonNode = objectMapper.readTree(httpResponse.body()); |
| | | resJsonNodeStr = resJsonNode.toString(); |
| | | } catch (Exception e) { |
| | | throw new ServiceException("调用气象预报服务接口失败,详情:" + e.getMessage()); |
| | | } |
| | | RainfallGridData gridData; |
| | | try { |
| | | gridData = objectMapper.readValue(resJsonNodeStr, RainfallGridData.class); |
| | | } catch (JsonProcessingException e) { |
| | | throw new ServiceException("转换降雨栅格数据失败,详情:" + e.getMessage()); |
| | | } |
| | | RainfallGridData.Data data = gridData.getData(); |
| | | RainfallGridData.GridInfo gridInfo = data.getGridInfo(); |
| | | List<List<Double>> gridDataList = data.getGridData(); |
| | | if (gridDataList == null || gridDataList.isEmpty()) { |
| | | log.warn("gridDataList为空!"); |
| | | return new ArrayList<>(); |
| | | } |
| | | // 获取网格信息 |
| | | int lonNum = gridInfo.getLonNum(); // 网格横向(经度) |
| | | double lonMax = gridInfo.getLonMax(); |
| | | double lonSpan = gridInfo.getLonSpan(); // 每个网格单元的经度跨度 |
| | | double latSpan = gridInfo.getLatSpan(); // 每个网格单元的纬度跨度 |
| | | double latMin = gridInfo.getLatMin(); // 网格的最小纬度 |
| | | double lonMin = gridInfo.getLonMin(); // 网格的最小经度 |
| | | double latMax = gridInfo.getLatMax(); |
| | | int latNum = gridInfo.getLatNum(); // 网格纵向(纬度) |
| | | |
| | | // 将网格数据转换为二维数组 |
| | | double[][] grid = new double[latNum][lonNum]; |
| | | for (int i = 0; i < latNum; i++) { |
| | | List<Double> row = gridDataList.get(i); |
| | | for (int j = 0; j < lonNum; j++) { |
| | | grid[i][j] = row.get(j); |
| | | } |
| | | } |
| | | |
| | | LambdaQueryWrapper<AttResBase> queryWrapper = Wrappers.<AttResBase>query().lambda(); |
| | | List<AttResBase> attResBases = baseMapper.selectList(queryWrapper); |
| | | List<AttResWithRainfall> attResWithRainfallList = new ArrayList<>(); |
| | | |
| | | for (AttResBase attResBase : attResBases) { |
| | | // 横向索引(lonIndex):(站点的经度 - 网格最小经度) / 每个网格单元的经度跨度 |
| | | int lonIndex = (int) ((Double.parseDouble(attResBase.getCenterLong()) - lonMin) / lonSpan); |
| | | // 纵向索引(latIndex):(站点的纬度 - 网格最小纬度) / 每个网格单元的纬度跨度 |
| | | int latIndex = (int) ((Double.parseDouble(attResBase.getCenterLat()) - latMin) / latSpan); |
| | | if (lonIndex >= 0 && lonIndex < lonNum && latIndex >= 0 && latIndex < latNum) { |
| | | double rainfall = grid[latIndex][lonIndex]; |
| | | // 降雨量 <= 最小值的站点,都过滤掉, 降雨量为0除外 |
| | | if (null != minRainfallDouble && rainfall != 0 && rainfall <= minRainfallDouble) { |
| | | continue; |
| | | } |
| | | // 降雨量 > 最大值的站点,都过滤掉 |
| | | if (null != maxRainfallDouble && rainfall > maxRainfallDouble) { |
| | | continue; |
| | | } |
| | | AttResWithRainfall attResWithRainfall = new AttResWithRainfall(); |
| | | BeanUtil.copyProperties(attResBase, attResWithRainfall); |
| | | attResWithRainfall.setRainfall(String.valueOf(rainfall)); |
| | | attResWithRainfallList.add(attResWithRainfall); |
| | | } else { |
| | | log.warn("AttRes {} is out of the grid range. centerLong: {}, centerLat: {}", attResBase.getName(), |
| | | attResBase.getCenterLong(), attResBase.getCenterLat()); |
| | | } |
| | | } |
| | | return attResWithRainfallList; |
| | | } |
| | | |
| | | @Override |
| | | public int[] getAttResNumByRainfall(String dayIndex) { |
| | | List<AttResWithRainfall> attResByRainfall; |
| | | // 获取站点降雨量失败或者返回站点列表为空时,直接返回空数组 |
| | | try { |
| | | attResByRainfall = getAttResByRainfall(null, null, dayIndex); |
| | | } catch (Exception e) { |
| | | return RainfallConstant.EMPTY_ATT_RES_NUM_ARRAY; |
| | | } |
| | | if (attResByRainfall == null || attResByRainfall.isEmpty()) { |
| | | return RainfallConstant.EMPTY_ATT_RES_NUM_ARRAY; |
| | | } |
| | | // 降雨范围-站点数量 |
| | | Map<String, Integer> rainfallRangeAttResNumMap = attResByRainfall.stream() |
| | | .collect(Collectors.groupingBy(attResWithRainfall -> { |
| | | int rainfall = Integer.parseInt(attResWithRainfall.getRainfall()); |
| | | if (rainfall > 250) { |
| | | return "(250,+)"; |
| | | } else if (rainfall > 100) { |
| | | return "(100,250]"; |
| | | } else if (rainfall > 50) { |
| | | return "(50,100]"; |
| | | } else if (rainfall > 25) { |
| | | return "(25,50]"; |
| | | } else if (rainfall > 10) { |
| | | return "(10,25]"; |
| | | } else if (rainfall > 5) { |
| | | return "(5,10]"; |
| | | } else if (rainfall > 0.1) { |
| | | return "(0.1,5]"; |
| | | } else if (rainfall >= 0) { |
| | | return "[0,0.1]"; |
| | | } else { |
| | | throw new ServiceException("无效的降雨值:" + rainfall); |
| | | } |
| | | }, Collectors.collectingAndThen(Collectors.counting(), Long::intValue))); |
| | | int[] attResNumArray = new int[RainfallConstant.RAIN_FALL_RANGES.size()]; |
| | | for (int i = 0; i < RainfallConstant.RAIN_FALL_RANGES.size(); i++) { |
| | | String range = RainfallConstant.RAIN_FALL_RANGES.get(i); |
| | | attResNumArray[i] = rainfallRangeAttResNumMap.getOrDefault(range, 0); |
| | | } |
| | | return attResNumArray; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean updateResBaseByGuid(AttResBase attResBase) { |
| | | attResBase.setUpdateTime(DateUtil.now()); |