|
|
@@ -4,57 +4,83 @@ import com.ruoyi.base.domain.WeatherDataStatistics;
|
|
|
import com.ruoyi.base.domain.WeatherRealtimeData;
|
|
|
import com.ruoyi.base.mapper.WeatherRealtimeDataMapper;
|
|
|
import com.ruoyi.base.service.IWeatherRealtimeDataService;
|
|
|
+import com.ruoyi.base.vo.WeatherDataStatisticsVo;
|
|
|
import com.ruoyi.common.core.utils.DateUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.util.ObjectUtils;
|
|
|
|
|
|
-import java.util.List;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.LocalTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 气象站实时数据Service业务层处理
|
|
|
- *
|
|
|
+ *
|
|
|
* @author ruoyi
|
|
|
* @date 2025-06-18
|
|
|
*/
|
|
|
@Service
|
|
|
-public class WeatherRealtimeDataServiceImpl implements IWeatherRealtimeDataService
|
|
|
-{
|
|
|
+public class WeatherRealtimeDataServiceImpl implements IWeatherRealtimeDataService {
|
|
|
@Autowired
|
|
|
private WeatherRealtimeDataMapper weatherRealtimeDataMapper;
|
|
|
|
|
|
/**
|
|
|
* 查询气象站实时数据
|
|
|
- *
|
|
|
+ *
|
|
|
* @param id 气象站实时数据主键
|
|
|
* @return 气象站实时数据
|
|
|
*/
|
|
|
@Override
|
|
|
- public WeatherRealtimeData selectWeatherRealtimeDataById(Long id)
|
|
|
- {
|
|
|
+ public WeatherRealtimeData selectWeatherRealtimeDataById(Long id) {
|
|
|
return weatherRealtimeDataMapper.selectWeatherRealtimeDataById(id);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public WeatherRealtimeData selectWeatherRealtimeDataLatestTimeById(String deviceId) {
|
|
|
+ WeatherRealtimeData weatherRealtimeData = weatherRealtimeDataMapper.selectWeatherRealtimeDataLatestTimeById(deviceId);
|
|
|
+
|
|
|
+ // 添加空值判断,避免空指针异常
|
|
|
+ if (weatherRealtimeData != null && weatherRealtimeData.getWindDirection() != null) {
|
|
|
+ try {
|
|
|
+ // 尝试转换风向值并设置中文风向
|
|
|
+ int windDirection = Integer.parseInt(weatherRealtimeData.getWindDirection());
|
|
|
+ weatherRealtimeData.setWindDirection(getFX(windDirection));
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ // 如果转换失败,设置默认值或保持原值
|
|
|
+ weatherRealtimeData.setWindDirection("未知");
|
|
|
+ }
|
|
|
+ } else if (weatherRealtimeData != null) {
|
|
|
+ // 如果 windDirection 为 null,设置默认值
|
|
|
+ weatherRealtimeData.setWindDirection("未知");
|
|
|
+ }
|
|
|
+
|
|
|
+ return weatherRealtimeData;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 查询气象站实时数据列表
|
|
|
- *
|
|
|
+ *
|
|
|
* @param weatherRealtimeData 气象站实时数据
|
|
|
* @return 气象站实时数据
|
|
|
*/
|
|
|
@Override
|
|
|
- public List<WeatherRealtimeData> selectWeatherRealtimeDataList(WeatherRealtimeData weatherRealtimeData)
|
|
|
- {
|
|
|
+ public List<WeatherRealtimeData> selectWeatherRealtimeDataList(WeatherRealtimeData weatherRealtimeData) {
|
|
|
return weatherRealtimeDataMapper.selectWeatherRealtimeDataList(weatherRealtimeData);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 新增气象站实时数据
|
|
|
- *
|
|
|
+ *
|
|
|
* @param weatherRealtimeData 气象站实时数据
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@Override
|
|
|
- public int insertWeatherRealtimeData(WeatherRealtimeData weatherRealtimeData)
|
|
|
- {
|
|
|
+ public int insertWeatherRealtimeData(WeatherRealtimeData weatherRealtimeData) {
|
|
|
weatherRealtimeData.setCreateTime(DateUtils.getNowDate());
|
|
|
return weatherRealtimeDataMapper.insertWeatherRealtimeData(weatherRealtimeData);
|
|
|
}
|
|
|
@@ -67,38 +93,461 @@ public class WeatherRealtimeDataServiceImpl implements IWeatherRealtimeDataServi
|
|
|
|
|
|
/**
|
|
|
* 修改气象站实时数据
|
|
|
- *
|
|
|
+ *
|
|
|
* @param weatherRealtimeData 气象站实时数据
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@Override
|
|
|
- public int updateWeatherRealtimeData(WeatherRealtimeData weatherRealtimeData)
|
|
|
- {
|
|
|
+ public int updateWeatherRealtimeData(WeatherRealtimeData weatherRealtimeData) {
|
|
|
weatherRealtimeData.setUpdateTime(DateUtils.getNowDate());
|
|
|
return weatherRealtimeDataMapper.updateWeatherRealtimeData(weatherRealtimeData);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 批量删除气象站实时数据
|
|
|
- *
|
|
|
+ *
|
|
|
* @param ids 需要删除的气象站实时数据主键
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@Override
|
|
|
- public int deleteWeatherRealtimeDataByIds(Long[] ids)
|
|
|
- {
|
|
|
+ public int deleteWeatherRealtimeDataByIds(Long[] ids) {
|
|
|
return weatherRealtimeDataMapper.deleteWeatherRealtimeDataByIds(ids);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 删除气象站实时数据信息
|
|
|
- *
|
|
|
+ *
|
|
|
* @param id 气象站实时数据主键
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@Override
|
|
|
- public int deleteWeatherRealtimeDataById(Long id)
|
|
|
- {
|
|
|
+ public int deleteWeatherRealtimeDataById(Long id) {
|
|
|
return weatherRealtimeDataMapper.deleteWeatherRealtimeDataById(id);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public WeatherDataStatisticsVo selectWeatherStatisticsList(WeatherDataStatistics weatherRealtimeData) {
|
|
|
+ WeatherDataStatisticsVo weatherDataStatisticsVo = new WeatherDataStatisticsVo();
|
|
|
+ LocalDate currentDate = LocalDate.now();
|
|
|
+ LocalDate previousDate = null;
|
|
|
+ if (weatherRealtimeData.getNumberDay() == null) {
|
|
|
+ previousDate = currentDate.minusDays(7);
|
|
|
+ } else {
|
|
|
+ if (weatherRealtimeData.getNumberDay() == 30) {
|
|
|
+ previousDate = currentDate.minusDays(30);
|
|
|
+ }
|
|
|
+ if (weatherRealtimeData.getNumberDay() == 24) {
|
|
|
+
|
|
|
+ return twentyFourHours(weatherRealtimeData.getDeviceId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ LocalDateTime startOfPreviousDay = LocalDateTime.of(previousDate, LocalTime.MIDNIGHT);
|
|
|
+ LocalDateTime endOfPreviousDay = LocalDateTime.of(currentDate, LocalTime.MAX);
|
|
|
+ weatherRealtimeData.setBeginCollectTime(startOfPreviousDay);
|
|
|
+ weatherRealtimeData.setEndCollectTime(endOfPreviousDay);
|
|
|
+
|
|
|
+ List<String> dateList = new ArrayList<>();
|
|
|
+ for (LocalDate date = previousDate; !date.isAfter(currentDate); date = date.plusDays(1)) {
|
|
|
+ String formattedDate = date.format(DateTimeFormatter.ofPattern("M/d"));
|
|
|
+ dateList.add(formattedDate);
|
|
|
+ }
|
|
|
+ weatherDataStatisticsVo.setWeatherDate(dateList);
|
|
|
+
|
|
|
+
|
|
|
+ List<BigDecimal> weatherMaxTemperature = new ArrayList<>();
|
|
|
+ List<BigDecimal> weatherMinTemperature = new ArrayList<>();
|
|
|
+ List<Double> weatherHumidity = new ArrayList<>();
|
|
|
+ List<Double> weatherRainfall = new ArrayList<>();
|
|
|
+ List<Double> weatherWindSpeed = new ArrayList<>();
|
|
|
+
|
|
|
+ List<Double> weatherAvgSoilN = new ArrayList<>();
|
|
|
+ List<Double> weatherAvgSoilP = new ArrayList<>();
|
|
|
+ List<Double> weatherAvgSoilK = new ArrayList<>();
|
|
|
+
|
|
|
+
|
|
|
+ List<WeatherDataStatistics> weatherDataStatisticsList = weatherRealtimeDataMapper.selectWeatherStatisticsList(weatherRealtimeData);
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d");
|
|
|
+
|
|
|
+ Map<String, WeatherDataStatistics> dateStrToStatisticsMap = weatherDataStatisticsList.stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ statistic -> statistic.getDate().format(formatter),
|
|
|
+ statistic -> statistic,
|
|
|
+ (existing, replacement) -> existing
|
|
|
+ ));
|
|
|
+
|
|
|
+
|
|
|
+ for (String s : dateList) {
|
|
|
+ WeatherDataStatistics weatherDataStatistics1 = dateStrToStatisticsMap.get(s);
|
|
|
+ if (ObjectUtils.isEmpty(weatherDataStatistics1)) {
|
|
|
+ weatherMaxTemperature.add(null);
|
|
|
+ weatherMinTemperature.add(null);
|
|
|
+ weatherHumidity.add(null);
|
|
|
+ weatherRainfall.add(null);
|
|
|
+ weatherWindSpeed.add(null);
|
|
|
+ weatherAvgSoilN.add(null);
|
|
|
+ weatherAvgSoilP.add(null);
|
|
|
+ weatherAvgSoilK.add(null);
|
|
|
+ } else {
|
|
|
+ weatherMaxTemperature.add(weatherDataStatistics1.getMaxTemperature());
|
|
|
+ weatherMinTemperature.add(weatherDataStatistics1.getMinTemperature());
|
|
|
+ weatherHumidity.add(weatherDataStatistics1.getAvgHumidity());
|
|
|
+ weatherRainfall.add(weatherDataStatistics1.getAvgRainfall());
|
|
|
+ weatherWindSpeed.add(weatherDataStatistics1.getAvgWindSpeed());
|
|
|
+ weatherAvgSoilN.add(weatherDataStatistics1.getAvgSoilN());
|
|
|
+ weatherAvgSoilP.add(weatherDataStatistics1.getAvgSoilP());
|
|
|
+ weatherAvgSoilK.add(weatherDataStatistics1.getAvgSoilK());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ BigDecimal avgHumidityAverage = weatherDataStatisticsList.stream()
|
|
|
+ .map(WeatherDataStatistics::getAvgHumidity)
|
|
|
+ .filter(d -> !Double.isNaN(d)) // 过滤掉无效值
|
|
|
+ .reduce(Double::sum)
|
|
|
+ .flatMap(sum -> !weatherDataStatisticsList.isEmpty() ?
|
|
|
+ Optional.of(BigDecimal.valueOf(sum / weatherDataStatisticsList.size())) : Optional.empty())
|
|
|
+ .map(avg -> avg.setScale(2, BigDecimal.ROUND_HALF_UP))
|
|
|
+ .orElse(BigDecimal.ZERO);
|
|
|
+
|
|
|
+ BigDecimal avgTemperatureAverage = weatherDataStatisticsList.stream()
|
|
|
+ .map(WeatherDataStatistics::getAvgTemperature) // 假设WeatherDataStatistics类中有getAvgTemperature方法
|
|
|
+ .filter(Objects::nonNull) // 过滤掉空值
|
|
|
+ .filter(temp -> temp.compareTo(BigDecimal.ZERO) >= 0) // 过滤掉无效值
|
|
|
+ .reduce(BigDecimal::add)
|
|
|
+ .flatMap(sum -> !weatherDataStatisticsList.isEmpty() ?
|
|
|
+ Optional.of(sum.divide(BigDecimal.valueOf(weatherDataStatisticsList.size()), 2, BigDecimal.ROUND_HALF_UP)) : Optional.empty())
|
|
|
+ .orElse(BigDecimal.ZERO);
|
|
|
+
|
|
|
+ BigDecimal avgSoilNAverage = weatherDataStatisticsList.stream()
|
|
|
+ .map(WeatherDataStatistics::getAvgSoilN)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .filter(d -> !d.isNaN()) // 如果是Double类型
|
|
|
+ .map(BigDecimal::valueOf) // 转换为BigDecimal
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(Math.max(1, weatherDataStatisticsList.size())), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+ BigDecimal avgSoilPAverage = weatherDataStatisticsList.stream()
|
|
|
+ .map(WeatherDataStatistics::getAvgSoilP)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .filter(d -> !d.isNaN()) // 如果是Double类型
|
|
|
+ .map(BigDecimal::valueOf) // 转换为BigDecimal
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(Math.max(1, weatherDataStatisticsList.size())), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+ BigDecimal avgSoilKAverage = weatherDataStatisticsList.stream()
|
|
|
+ .map(WeatherDataStatistics::getAvgSoilK)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .filter(d -> !d.isNaN()) // 如果是Double类型
|
|
|
+ .map(BigDecimal::valueOf) // 转换为BigDecimal
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(Math.max(1, weatherDataStatisticsList.size())), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ BigDecimal avgWindSpeedAverage = weatherDataStatisticsList.stream()
|
|
|
+ .map(WeatherDataStatistics::getAvgWindSpeed)
|
|
|
+ .filter(d -> !Double.isNaN(d))
|
|
|
+ .reduce(Double::sum)
|
|
|
+ .flatMap(sum -> !weatherDataStatisticsList.isEmpty() ?
|
|
|
+ Optional.of(BigDecimal.valueOf(sum / weatherDataStatisticsList.size())) : Optional.empty())
|
|
|
+ .map(avg -> avg.setScale(2, BigDecimal.ROUND_HALF_UP))
|
|
|
+ .orElse(BigDecimal.ZERO);
|
|
|
+
|
|
|
+ BigDecimal totalRainfallAccumulated = weatherDataStatisticsList.stream()
|
|
|
+ .map(WeatherDataStatistics::getDateRainfallA)
|
|
|
+ .filter(rainfall -> rainfall != null && rainfall.compareTo(BigDecimal.ZERO) >= 0)
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+
|
|
|
+ WeatherRealtimeData weatherRealtimeDataVo = new WeatherRealtimeData();
|
|
|
+ weatherRealtimeDataVo.setHumidity(avgHumidityAverage);
|
|
|
+ weatherRealtimeDataVo.setTemperature(avgTemperatureAverage);
|
|
|
+ weatherRealtimeDataVo.setWindSpeed(avgWindSpeedAverage);
|
|
|
+ weatherRealtimeDataVo.setRainfallA(totalRainfallAccumulated);
|
|
|
+ weatherRealtimeDataVo.setSoilN(avgSoilNAverage);
|
|
|
+ weatherRealtimeDataVo.setSoilP(avgSoilPAverage);
|
|
|
+ weatherRealtimeDataVo.setSoilK(avgSoilKAverage);
|
|
|
+ weatherDataStatisticsVo.setWeatherRealtimeData(weatherRealtimeDataVo);
|
|
|
+
|
|
|
+ weatherDataStatisticsVo.setWeatherMinTemperature(weatherMinTemperature);
|
|
|
+ weatherDataStatisticsVo.setWeatherMaxTemperature(weatherMaxTemperature);
|
|
|
+ weatherDataStatisticsVo.setWeatherHumidity(weatherHumidity);
|
|
|
+ weatherDataStatisticsVo.setWeatherRainfall(weatherRainfall);
|
|
|
+ weatherDataStatisticsVo.setWeatherWindSpeed(weatherWindSpeed);
|
|
|
+ weatherDataStatisticsVo.setWeatherAvgSoilN(weatherAvgSoilN);
|
|
|
+ weatherDataStatisticsVo.setWeatherAvgSoilP(weatherAvgSoilP);
|
|
|
+ weatherDataStatisticsVo.setWeatherAvgSoilK(weatherAvgSoilK);
|
|
|
+ return weatherDataStatisticsVo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private WeatherDataStatisticsVo twentyFourHours(String deviceId) {
|
|
|
+
|
|
|
+ WeatherDataStatisticsVo weatherDataStatisticsVo = new WeatherDataStatisticsVo();
|
|
|
+
|
|
|
+ List<String> hours = java.util.Arrays.asList(
|
|
|
+ "00:00", "02:00", "04:00", "06:00",
|
|
|
+ "08:00", "10:00", "12:00", "14:00",
|
|
|
+ "16:00", "18:00", "20:00", "22:00"
|
|
|
+ );
|
|
|
+
|
|
|
+ // 气象设备温度数据
|
|
|
+ List<BigDecimal> weatherMaxTemperature = new ArrayList<>();
|
|
|
+ List<BigDecimal> weatherMinTemperature = new ArrayList<>();
|
|
|
+ // 气象设备温度数据
|
|
|
+ List<BigDecimal> weatherAvgTemperature = new ArrayList<>();
|
|
|
+ // 气象设备湿度数据
|
|
|
+ List<Double> weatherHumidity = new ArrayList<>();
|
|
|
+ // 气象设备降雨量数据
|
|
|
+ List<Double> weatherRainfall = new ArrayList<>();
|
|
|
+ // 气象设备风速数据
|
|
|
+ List<Double> weatherWindSpeed = new ArrayList<>();
|
|
|
+
|
|
|
+
|
|
|
+ List<Double> weatherAvgSoilN = new ArrayList<>();
|
|
|
+ List<Double> weatherAvgSoilP = new ArrayList<>();
|
|
|
+ List<Double> weatherAvgSoilK = new ArrayList<>();
|
|
|
+
|
|
|
+
|
|
|
+ WeatherRealtimeData weatherRealtimeData = new WeatherRealtimeData();
|
|
|
+ LocalDate currentDate = LocalDate.now();
|
|
|
+ LocalDate previousDate = LocalDateTime.now().minusHours(24).toLocalDate();
|
|
|
+ LocalDateTime startOfPreviousDay = LocalDateTime.of(previousDate, LocalTime.MIDNIGHT);
|
|
|
+ LocalDateTime endOfPreviousDay = LocalDateTime.of(previousDate, LocalTime.MAX);
|
|
|
+ weatherRealtimeData.setBeginWeatherTime(startOfPreviousDay);
|
|
|
+ weatherRealtimeData.setEndWeatherTime(endOfPreviousDay);
|
|
|
+ weatherRealtimeData.setDeviceId(deviceId);
|
|
|
+ List<WeatherRealtimeData> weatherRealtime = weatherRealtimeDataMapper.selectWeatherRealtimeDataList(weatherRealtimeData);
|
|
|
+
|
|
|
+ weatherRealtime.stream()
|
|
|
+ .filter(data -> data.getCollectTime() != null && data.getTemperature() != null)
|
|
|
+ .collect(Collectors.groupingBy(data -> {
|
|
|
+ // 提取小时数并划分时段(每2小时为一个时段)
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
+ calendar.setTime(data.getCollectTime());
|
|
|
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
|
|
|
+ return hour / 2; // 0~23 → 0~11
|
|
|
+ }, Collectors.collectingAndThen(Collectors.toList(), list -> {
|
|
|
+ // 提取气温列表
|
|
|
+ List<BigDecimal> temps = list.stream()
|
|
|
+ .map(WeatherRealtimeData::getTemperature)
|
|
|
+ .filter(temperature -> temperature != null)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 提取湿度列表
|
|
|
+ List<BigDecimal> hums = list.stream()
|
|
|
+ .map(WeatherRealtimeData::getHumidity)
|
|
|
+ .filter(humidity -> humidity != null)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<BigDecimal> soilN = list.stream()
|
|
|
+ .map(WeatherRealtimeData::getSoilN)
|
|
|
+ .filter(humidity -> humidity != null)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<BigDecimal> soilP = list.stream()
|
|
|
+ .map(WeatherRealtimeData::getSoilP)
|
|
|
+ .filter(humidity -> humidity != null)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<BigDecimal> soilK = list.stream()
|
|
|
+ .map(WeatherRealtimeData::getSoilK)
|
|
|
+ .filter(humidity -> humidity != null)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 提取降雨量列表
|
|
|
+ List<BigDecimal> rains = list.stream()
|
|
|
+ .map(WeatherRealtimeData::getRainfall)
|
|
|
+ .filter(rain -> rain != null)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 提取风速列表
|
|
|
+ List<BigDecimal> winds = list.stream()
|
|
|
+ .map(WeatherRealtimeData::getWindSpeed)
|
|
|
+ .filter(wind -> wind != null)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 计算最大值、最小值、平均值
|
|
|
+ BigDecimal maxTemp = temps.stream()
|
|
|
+ .max(BigDecimal::compareTo)
|
|
|
+ .orElse(null);
|
|
|
+
|
|
|
+ BigDecimal minTemp = temps.stream()
|
|
|
+ .min(BigDecimal::compareTo)
|
|
|
+ .orElse(null);
|
|
|
+
|
|
|
+ BigDecimal avgTemp = temps.isEmpty() ? BigDecimal.ZERO :
|
|
|
+ temps.stream().reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(temps.size()), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ BigDecimal avgHumidity = hums.isEmpty() ? BigDecimal.ZERO :
|
|
|
+ hums.stream().reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(hums.size()), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ BigDecimal avgRainfall = rains.isEmpty() ? BigDecimal.ZERO :
|
|
|
+ rains.stream().reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(rains.size()), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ BigDecimal avgWindSpeed = winds.isEmpty() ? BigDecimal.ZERO :
|
|
|
+ winds.stream().reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(winds.size()), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ BigDecimal avgSoilN = soilN.isEmpty() ? BigDecimal.ZERO :
|
|
|
+ soilN.stream().reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(soilN.size()), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ BigDecimal avgSoilP = soilP.isEmpty() ? BigDecimal.ZERO :
|
|
|
+ soilP.stream().reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(soilP.size()), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ BigDecimal avgSoilK = soilK.isEmpty() ? BigDecimal.ZERO :
|
|
|
+ soilK.stream().reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(soilK.size()), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+ weatherMaxTemperature.add(maxTemp);
|
|
|
+ weatherMinTemperature.add(minTemp);
|
|
|
+ weatherAvgTemperature.add(avgTemp);
|
|
|
+ weatherHumidity.add(avgHumidity.doubleValue());
|
|
|
+ weatherRainfall.add(avgRainfall.doubleValue());
|
|
|
+ weatherWindSpeed.add(avgWindSpeed.doubleValue());
|
|
|
+ weatherAvgSoilN.add(avgSoilN.doubleValue());
|
|
|
+ weatherAvgSoilP.add(avgSoilP.doubleValue());
|
|
|
+ weatherAvgSoilK.add(avgSoilK.doubleValue());
|
|
|
+ return null;
|
|
|
+ })));
|
|
|
+ weatherDataStatisticsVo.setWeatherDate(hours);
|
|
|
+ weatherDataStatisticsVo.setWeatherMaxTemperature(weatherMaxTemperature);
|
|
|
+ weatherDataStatisticsVo.setWeatherMinTemperature(weatherMinTemperature);
|
|
|
+ weatherDataStatisticsVo.setWeatherHumidity(weatherHumidity);
|
|
|
+ weatherDataStatisticsVo.setWeatherRainfall(weatherRainfall);
|
|
|
+ weatherDataStatisticsVo.setWeatherWindSpeed(weatherWindSpeed);
|
|
|
+ weatherDataStatisticsVo.setWeatherAvgSoilN(weatherAvgSoilN);
|
|
|
+ weatherDataStatisticsVo.setWeatherAvgSoilP(weatherAvgSoilP);
|
|
|
+ weatherDataStatisticsVo.setWeatherAvgSoilK(weatherAvgSoilK);
|
|
|
+
|
|
|
+ // 计算平均温度
|
|
|
+ BigDecimal avgTemperature = weatherAvgTemperature.isEmpty() ? BigDecimal.ZERO :
|
|
|
+ weatherAvgTemperature.stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .divide(BigDecimal.valueOf(weatherAvgTemperature.size()), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ // 计算平均湿度
|
|
|
+ BigDecimal avgHumidity = weatherHumidity.isEmpty() ? BigDecimal.ZERO :
|
|
|
+ BigDecimal.valueOf(weatherHumidity.stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .mapToDouble(Double::doubleValue)
|
|
|
+ .average()
|
|
|
+ .orElse(0.0))
|
|
|
+ .setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ // 计算累计降雨量
|
|
|
+ BigDecimal totalRainfall = BigDecimal.valueOf(weatherRainfall.stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .mapToDouble(Double::doubleValue)
|
|
|
+ .sum())
|
|
|
+ .setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ // 计算平均风速
|
|
|
+ BigDecimal avgWindSpeed = BigDecimal.valueOf(weatherWindSpeed.stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .mapToDouble(Double::doubleValue)
|
|
|
+ .average()
|
|
|
+ .orElse(0.0))
|
|
|
+ .setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ // 计算平均氮
|
|
|
+ BigDecimal avgN = BigDecimal.valueOf(weatherAvgSoilN.stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .mapToDouble(Double::doubleValue)
|
|
|
+ .average()
|
|
|
+ .orElse(0.0))
|
|
|
+ .setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ // 计算平均磷
|
|
|
+ BigDecimal avgP = BigDecimal.valueOf(weatherAvgSoilP.stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .mapToDouble(Double::doubleValue)
|
|
|
+ .average()
|
|
|
+ .orElse(0.0))
|
|
|
+ .setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ // 计算平均钾
|
|
|
+ BigDecimal avgK = BigDecimal.valueOf(weatherAvgSoilK.stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .mapToDouble(Double::doubleValue)
|
|
|
+ .average()
|
|
|
+ .orElse(0.0))
|
|
|
+ .setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+
|
|
|
+ WeatherRealtimeData weatherRealtimeDataVo = new WeatherRealtimeData();
|
|
|
+ weatherRealtimeDataVo.setHumidity(avgHumidity);
|
|
|
+ weatherRealtimeDataVo.setTemperature(avgTemperature);
|
|
|
+ weatherRealtimeDataVo.setWindSpeed(avgWindSpeed);
|
|
|
+ weatherRealtimeDataVo.setRainfallA(totalRainfall);
|
|
|
+ weatherRealtimeDataVo.setSoilN(avgN);
|
|
|
+ weatherRealtimeDataVo.setSoilP(avgP);
|
|
|
+ weatherRealtimeDataVo.setSoilK(avgK);
|
|
|
+ weatherDataStatisticsVo.setWeatherRealtimeData(weatherRealtimeDataVo);
|
|
|
+
|
|
|
+ return weatherDataStatisticsVo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 风向度数转为中文
|
|
|
+ *
|
|
|
+ * @param FX
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String getFX(int FX) {
|
|
|
+
|
|
|
+ if (FX > 348 || FX < 11) {
|
|
|
+ return "北";
|
|
|
+ }
|
|
|
+ if (FX > 11 && FX <= 33) {
|
|
|
+ return "北东北";
|
|
|
+ }
|
|
|
+ if (FX > 33 && FX <= 56) {
|
|
|
+ return "东北";
|
|
|
+ }
|
|
|
+ if (FX > 56 && FX <= 78) {
|
|
|
+ return "东东北";
|
|
|
+ }
|
|
|
+ if (FX > 78 && FX <= 101) {
|
|
|
+ return "东";
|
|
|
+ }
|
|
|
+ if (FX > 101 && FX <= 123) {
|
|
|
+ return "东东南";
|
|
|
+ }
|
|
|
+ if (FX > 123 && FX <= 146) {
|
|
|
+ return "东南";
|
|
|
+ }
|
|
|
+ if (FX > 146 && FX <= 168) {
|
|
|
+ return "南东南";
|
|
|
+ }
|
|
|
+ if (FX > 168 && FX <= 191) {
|
|
|
+ return "南";
|
|
|
+ }
|
|
|
+ if (FX > 191 && FX <= 213) {
|
|
|
+ return "南西南";
|
|
|
+ }
|
|
|
+ if (FX > 213 && FX <= 236) {
|
|
|
+ return "西南";
|
|
|
+ }
|
|
|
+ if (FX > 236 && FX <= 258) {
|
|
|
+ return "西西南";
|
|
|
+ }
|
|
|
+ if (FX > 258 && FX <= 281) {
|
|
|
+ return "西";
|
|
|
+ }
|
|
|
+ if (FX > 281 && FX <= 303) {
|
|
|
+ return "西西北";
|
|
|
+ }
|
|
|
+ if (FX > 303 && FX <= 326) {
|
|
|
+ return "西北";
|
|
|
+ }
|
|
|
+ if (FX > 326 && FX <= 348) {
|
|
|
+ return "北西北";
|
|
|
+ }
|
|
|
+
|
|
|
+ return "";
|
|
|
+ }
|
|
|
}
|