From 408406dff8f428e1439dbf909bc4f5d317cdaf5b Mon Sep 17 00:00:00 2001
From: xieb <vip_xiaobin810@163.com>
Date: Wed, 19 Jun 2024 16:27:40 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/jtdev' into jtdev

---
 skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/service/impl/AttResBaseServiceImpl.java |  148 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 148 insertions(+), 0 deletions(-)

diff --git a/skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/service/impl/AttResBaseServiceImpl.java b/skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/service/impl/AttResBaseServiceImpl.java
index 183a1dc..77be4f6 100644
--- a/skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/service/impl/AttResBaseServiceImpl.java
+++ b/skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/service/impl/AttResBaseServiceImpl.java
@@ -1,6 +1,7 @@
 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;
@@ -11,9 +12,20 @@
 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;
@@ -23,6 +35,7 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.RequestParam;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @ClassName AttResBaseServiceImpl
@@ -31,9 +44,12 @@
  * @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;
@@ -99,6 +115,138 @@
 	}
 
 	@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());

--
Gitblit v1.9.3