diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/TransportTaskModeEnum.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/TransportTaskModeEnum.java index 3cc5f1b..c681a15 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/TransportTaskModeEnum.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/TransportTaskModeEnum.java @@ -8,11 +8,11 @@ public enum TransportTaskModeEnum { /** * 正向 */ - FORWARD(-1), + FORWARD(1), /** * 反向 */ - BACK_FORWARD(1); + BACK_FORWARD(-1); private Integer key; diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/validgroup/QueryGroup.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/validgroup/QueryGroup.java new file mode 100644 index 0000000..2c1085d --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/validgroup/QueryGroup.java @@ -0,0 +1,7 @@ +package org.jeecg.common.validgroup; + +/** + * 查询验证组 + */ +public interface QueryGroup { +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/TransportTask.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/TransportTask.java index 5e30249..343838f 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/TransportTask.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/TransportTask.java @@ -67,7 +67,7 @@ public class TransportTask{ private Integer taskStatus; /** - * 气象数据类型(1-盘古模型,2-graphcast,3-cra40,4-ncep) + * 气象数据类型(1-盘古模型,2-graphcast,3-cra40,4-ncep,5-fnl,6-t1h) */ @NotNull(message = "气象数据类型不能为空",groups = {InsertGroup.class, UpdateGroup.class}) @TableField(value = "use_met_type") diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/TransportTaskChild.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/TransportTaskChild.java index 5c8daa4..6b7dabb 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/TransportTaskChild.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/TransportTaskChild.java @@ -38,7 +38,7 @@ public class TransportTaskChild{ /** * 台站编目 */ - @NotBlank(message = "释放量不能为空",groups = {InsertGroup.class, UpdateGroup.class}) + @NotBlank(message = "台站编码不能为空",groups = {InsertGroup.class, UpdateGroup.class}) @TableField(value = "station_code") private String stationCode; diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/configuration/GardsNuclearfacility.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/configuration/GardsNuclearfacility.java index 6dc8a53..63d57eb 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/configuration/GardsNuclearfacility.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/configuration/GardsNuclearfacility.java @@ -42,12 +42,18 @@ public class GardsNuclearfacility implements Serializable { @TableField(value = "LONGITUDE") private String longitude; + @TableField(exist = false) + private Double lonValue; + /** * 纬度 */ @TableField(value = "LATITUDE") private String latitude; + @TableField(exist = false) + private Double latValue; + /** * 状态 */ diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/GardsXeResultMapper.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/GardsXeResultMapper.java new file mode 100644 index 0000000..0497e90 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/GardsXeResultMapper.java @@ -0,0 +1,16 @@ +package org.jeecg.modules.base.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.lettuce.core.dynamic.annotation.Param; +import org.jeecg.modules.base.entity.rnauto.GardsXeResults; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public interface GardsXeResultMapper extends BaseMapper { + + List> getXeResults(@Param("stationId") Integer stationId, + @Param("startTime") Date startTime, + @Param("endTime") Date endTime, + @Param("nuclideName") String nuclideName); +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/GardsXeResultMapper.xml b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/GardsXeResultMapper.xml new file mode 100644 index 0000000..0ac5794 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/GardsXeResultMapper.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/jeecg-module-event/src/main/java/org/jeecg/diffusion/controller/DiffusionDataController.java b/jeecg-module-event/src/main/java/org/jeecg/diffusion/controller/DiffusionDataController.java index e59a282..c6928eb 100644 --- a/jeecg-module-event/src/main/java/org/jeecg/diffusion/controller/DiffusionDataController.java +++ b/jeecg-module-event/src/main/java/org/jeecg/diffusion/controller/DiffusionDataController.java @@ -14,7 +14,7 @@ import org.jeecg.common.api.vo.Result; @RestController @RequestMapping("diffusionData") @RequiredArgsConstructor -public class DiffusionDataController { +public class DiffusionDataController { private final DiffusionDataService diffusionDataService; diff --git a/jeecg-module-transport/src/main/java/org/jeecg/controller/StationDataController.java b/jeecg-module-transport/src/main/java/org/jeecg/controller/StationDataController.java new file mode 100644 index 0000000..8c7fc7b --- /dev/null +++ b/jeecg-module-transport/src/main/java/org/jeecg/controller/StationDataController.java @@ -0,0 +1,35 @@ +package org.jeecg.controller; + +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.jeecg.service.StationDataService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Validated +@RestController +@RequestMapping("station") +@RequiredArgsConstructor +public class StationDataController { + + private final StationDataService stationDataService; + + @AutoLog(value = "查询所有台站") + @Operation(summary = "查询所有台站") + @GetMapping("getAllStations") + public Result getAllStations(){ + return Result.OK(stationDataService.getAllStations()); + } + + @AutoLog(value = "查询所有台站") + @Operation(summary = "查询所有设施") + @GetMapping("getAllNuclearfacility") + public Result getAllNuclearfacility(){ + return Result.OK(stationDataService.getAllNuclearfacility()); + } + +} diff --git a/jeecg-module-transport/src/main/java/org/jeecg/controller/TransportResultDataController.java b/jeecg-module-transport/src/main/java/org/jeecg/controller/TransportResultDataController.java new file mode 100644 index 0000000..d371096 --- /dev/null +++ b/jeecg-module-transport/src/main/java/org/jeecg/controller/TransportResultDataController.java @@ -0,0 +1,53 @@ +package org.jeecg.controller; + +import io.swagger.v3.oas.annotations.Operation; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.jeecg.common.validgroup.QueryGroup; +import org.jeecg.service.TransportResultDataService; +import org.jeecg.vo.QueryDiffusionVO; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +@Validated +@RestController +@RequestMapping("transportResult") +@RequiredArgsConstructor +public class TransportResultDataController { + + private final TransportResultDataService transportResultDataService; + + @AutoLog(value = "分页查询输运任务数据") + @Operation(summary = "分页查询输运任务数据") + @GetMapping("getDiffusionData") + public Result getDiffusionData(@Validated(value= QueryGroup.class) QueryDiffusionVO queryDiffusionVO) { + return Result.OK(transportResultDataService.getDiffusionData(queryDiffusionVO)); + } + + @AutoLog(value = "查询模拟结果站点序号和高度层级") + @Operation(summary = "查询模拟结果站点序号和高度层级") + @GetMapping("getResultSiteAndHeightLevel") + public Result getResultSiteAndHeightLevel(@NotNull(message = "任务id不能为空") Integer taskId) { + return Result.OK(transportResultDataService.getResultSiteNums(taskId)); + } + + @AutoLog(value = "查询符合度分析数据") + @Operation(summary = "查询符合度分析数据") + @GetMapping("getConformityAnalysis") + public Result getConformityAnalysis(@NotNull(message = "任务id不能为空") Integer taskId, + @NotNull(message = "台站不能为空") Integer stationId, + @NotNull(message = "核素名称不能为空") String nuclideName, + String facilityName) { + return Result.OK(transportResultDataService.getConformityAnalysis(taskId,stationId,nuclideName,facilityName)); + } + + @AutoLog(value = "查询任务所属核设施数据") + @Operation(summary = "查询任务所属核设施数据") + @GetMapping("getTaskFacility") + public Result getTaskFacility(@NotNull(message = "任务id不能为空") Integer taskId) { + return Result.OK(transportResultDataService.getTaskFacility(taskId)); + } + +} diff --git a/jeecg-module-transport/src/main/java/org/jeecg/controller/TransportTaskController.java b/jeecg-module-transport/src/main/java/org/jeecg/controller/TransportTaskController.java index f5c0c85..a095cb9 100644 --- a/jeecg-module-transport/src/main/java/org/jeecg/controller/TransportTaskController.java +++ b/jeecg-module-transport/src/main/java/org/jeecg/controller/TransportTaskController.java @@ -29,10 +29,10 @@ public class TransportTaskController { @AutoLog(value = "分页查询输运任务数据") @Operation(summary = "分页查询输运任务数据") @GetMapping("page") - public Result page(PageRequest pageRequest, String taskName, Integer taskMode,Integer taskStatus, + public Result page(PageRequest pageRequest, String taskName, Integer taskMode,Integer taskStatus,Integer metType, @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate, @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) { - IPage page = transportTaskService.page(pageRequest,taskName,taskMode,taskStatus,startDate,endDate); + IPage page = transportTaskService.page(pageRequest,taskName,taskMode,taskStatus,metType,startDate,endDate); Map rspData = new HashMap<>(); rspData.put("rows", page.getRecords()); rspData.put("total", page.getTotal()); diff --git a/jeecg-module-transport/src/main/java/org/jeecg/service/StationDataService.java b/jeecg-module-transport/src/main/java/org/jeecg/service/StationDataService.java new file mode 100644 index 0000000..bc45762 --- /dev/null +++ b/jeecg-module-transport/src/main/java/org/jeecg/service/StationDataService.java @@ -0,0 +1,42 @@ +package org.jeecg.service; + +import org.jeecg.modules.base.entity.configuration.GardsNuclearfacility; +import org.jeecg.modules.base.entity.configuration.GardsStations; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 台站数据服务 + */ +public interface StationDataService { + + /** + * 获取所有台站 + * @return + */ + List getAllStations(); + + /** + * 获取所有核设施 + * @return + */ + List getAllNuclearfacility(); + + /** + * 获取指定样品在指定时间范围内的核素监测结果 + * @param stationId + * @param startTime + * @param endTime + * @param nuclideName + * @return + */ + List> getXeResults(Integer stationId,Date startTime,Date endTime,String nuclideName); + + /** + * 获取台站信息 + * @param stationId + * @return + */ + GardsStations getStationById(Integer stationId); +} diff --git a/jeecg-module-transport/src/main/java/org/jeecg/service/TransportResultDataService.java b/jeecg-module-transport/src/main/java/org/jeecg/service/TransportResultDataService.java new file mode 100644 index 0000000..44cd3bb --- /dev/null +++ b/jeecg-module-transport/src/main/java/org/jeecg/service/TransportResultDataService.java @@ -0,0 +1,40 @@ +package org.jeecg.service; + +import org.jeecg.vo.QueryDiffusionVO; +import java.util.List; +import java.util.Map; + +public interface TransportResultDataService { + + + /** + * 获取扩散数据 + * @param queryDiffusionVO + * @return + */ + List> getDiffusionData(QueryDiffusionVO queryDiffusionVO); + + /** + * 查询模拟结果站点序号和高度层级 + * @param taskId + * @return + */ + Map getResultSiteNums(Integer taskId); + + /** + * 查询符合度分析数据 + * @param taskId + * @param stationId + * @param nuclideName + * @param facilityName + * @return + */ + List> getConformityAnalysis(Integer taskId,Integer stationId,String nuclideName,String facilityName); + + /** + * 查询任务所属核设施数据 + * @param taskId + * @return + */ + List getTaskFacility(Integer taskId); +} diff --git a/jeecg-module-transport/src/main/java/org/jeecg/service/TransportTaskService.java b/jeecg-module-transport/src/main/java/org/jeecg/service/TransportTaskService.java index cd172df..d6a73b8 100644 --- a/jeecg-module-transport/src/main/java/org/jeecg/service/TransportTaskService.java +++ b/jeecg-module-transport/src/main/java/org/jeecg/service/TransportTaskService.java @@ -21,11 +21,12 @@ public interface TransportTaskService extends IService { * @param taskName * @param taskMode * @param taskStatus + * @param metType * @param startDate * @param endDate * @return */ - IPage page(PageRequest pageRequest,String taskName,Integer taskMode,Integer taskStatus,LocalDate startDate,LocalDate endDate); + IPage page(PageRequest pageRequest,String taskName,Integer taskMode,Integer taskStatus,Integer metType,LocalDate startDate,LocalDate endDate); /** * 创建输运模拟任务 diff --git a/jeecg-module-transport/src/main/java/org/jeecg/service/impl/StationDataServiceImpl.java b/jeecg-module-transport/src/main/java/org/jeecg/service/impl/StationDataServiceImpl.java new file mode 100644 index 0000000..9dbfc81 --- /dev/null +++ b/jeecg-module-transport/src/main/java/org/jeecg/service/impl/StationDataServiceImpl.java @@ -0,0 +1,129 @@ +package org.jeecg.service.impl; + +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.RequiredArgsConstructor; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.util.RedisUtil; +import org.jeecg.modules.base.entity.configuration.GardsNuclearfacility; +import org.jeecg.modules.base.entity.configuration.GardsStations; +import org.jeecg.modules.base.mapper.GardsNuclearfacilityMapper; +import org.jeecg.modules.base.mapper.GardsStationsMapper; +import org.jeecg.modules.base.mapper.GardsXeResultMapper; +import org.jeecg.service.StationDataService; +import org.springframework.stereotype.Service; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 台站数据服务 + */ +@DS("ora") +@Service +@RequiredArgsConstructor +public class StationDataServiceImpl implements StationDataService { + + private final GardsStationsMapper stationsMapper; + private final GardsNuclearfacilityMapper nuclearfacilityMapper; + private final GardsXeResultMapper gardsXeResultMapper; + private final RedisUtil redisUtil; + + /** + * 获取所有台站 + * @return + */ + @Override + public List getAllStations() { + if(redisUtil.hasKey(CommonConstant.ALL_STATIONS)){ + return (List) redisUtil.get(CommonConstant.ALL_STATIONS); + }else { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.select(GardsStations::getStationId,GardsStations::getStationCode,GardsStations::getLon,GardsStations::getLat); + List stations = stationsMapper.selectList(queryWrapper); + redisUtil.set(CommonConstant.ALL_STATIONS,stations); + return stations; + } + } + + /** + * 获取所有核设施 + * @return + */ + @Override + public List getAllNuclearfacility() { + if(redisUtil.hasKey(CommonConstant.ALL_NUCLEARFACILITY)){ + return (List) redisUtil.get(CommonConstant.ALL_NUCLEARFACILITY); + }else { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.select(GardsNuclearfacility::getFacilityId, GardsNuclearfacility::getFacilityName,GardsNuclearfacility::getLongitude,GardsNuclearfacility::getLatitude); + List nuclearfacilities = nuclearfacilityMapper.selectList(queryWrapper); + nuclearfacilities.forEach(nuclearfacility -> { + //数据库经纬度存储的是反的,所以这里反着处理 + Double lon = this.lonAndLatConversion(nuclearfacility.getLatitude()); + Double lat = this.lonAndLatConversion(nuclearfacility.getLongitude()); + nuclearfacility.setLonValue(lon); + nuclearfacility.setLatValue(lat); + }); + redisUtil.set(CommonConstant.ALL_NUCLEARFACILITY, nuclearfacilities); + return nuclearfacilities; + } + } + + /** + * 获取指定样品在指定时间范围内的核素监测结果 + * + * @param stationId + * @param startTime + * @param endTime + * @param nuclideName + * @return + */ + @Override + public List> getXeResults(Integer stationId, Date startTime, Date endTime, String nuclideName) { + List> xeResults = gardsXeResultMapper.getXeResults(stationId, startTime, endTime, nuclideName); + return xeResults; + } + + /** + * 获取台站信息 + * + * @param stationId + * @return + */ + @Override + public GardsStations getStationById(Integer stationId) { + return stationsMapper.selectById(stationId); + } + + /** + * 29°46’04”N + * 经纬度转换29°37′50″N -> 29.xxxxx + * @param lonOrLatStr + * @return + */ + private Double lonAndLatConversion(String lonOrLatStr) { + if(lonOrLatStr.contains("°") && lonOrLatStr.contains("′") && lonOrLatStr.contains("″")){ + String cleanStr = lonOrLatStr.replaceAll("[NSEW\\s]", ""); + String[] parts = cleanStr.split("[°′″:\\s]+"); + String deg = parts[0]; + String min = parts.length > 1 && !parts[1].isEmpty() ? parts[1] : "0"; + String sec = parts.length > 2 && !parts[2].isEmpty() ? parts[2] : "0"; + BigDecimal degBigDecimal = new BigDecimal(deg); + BigDecimal minBigDecimal = new BigDecimal(min); + BigDecimal secBigDecimal = new BigDecimal(sec); + minBigDecimal = minBigDecimal.divide(new BigDecimal("60"), 5, BigDecimal.ROUND_HALF_UP); + secBigDecimal = secBigDecimal.divide(new BigDecimal("3600"), 5, BigDecimal.ROUND_HALF_UP); + double value = degBigDecimal.doubleValue() + minBigDecimal.doubleValue() + secBigDecimal.doubleValue(); + return value; + }else { + if(lonOrLatStr.contains("°") && !lonOrLatStr.contains("′") && !lonOrLatStr.contains("″")){ + String cleanStr = lonOrLatStr.replaceAll("[NSEW°\\s]", ""); + return Double.parseDouble(cleanStr); + } + } + return 0D; + } + +} diff --git a/jeecg-module-transport/src/main/java/org/jeecg/service/impl/TransportResultDataServiceImpl.java b/jeecg-module-transport/src/main/java/org/jeecg/service/impl/TransportResultDataServiceImpl.java new file mode 100644 index 0000000..6de60e6 --- /dev/null +++ b/jeecg-module-transport/src/main/java/org/jeecg/service/impl/TransportResultDataServiceImpl.java @@ -0,0 +1,409 @@ +package org.jeecg.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.RequiredArgsConstructor; +import org.jeecg.common.constant.enums.TransportTaskModeEnum; +import org.jeecg.common.properties.TransportSimulationProperties; +import org.jeecg.common.util.NcUtil; +import org.jeecg.modules.base.entity.TransportTask; +import org.jeecg.modules.base.entity.TransportTaskChild; +import org.jeecg.modules.base.entity.configuration.GardsStations; +import org.jeecg.modules.base.mapper.TransportTaskChildMapper; +import org.jeecg.modules.base.mapper.TransportTaskMapper; +import org.jeecg.service.StationDataService; +import org.jeecg.service.TransportResultDataService; +import org.jeecg.vo.ConcModValVo; +import org.jeecg.vo.QueryDiffusionVO; +import org.springframework.stereotype.Service; +import ucar.ma2.Array; +import ucar.ma2.DataType; +import ucar.ma2.Index; +import ucar.ma2.InvalidRangeException; +import ucar.nc2.Attribute; +import ucar.nc2.Dimension; +import ucar.nc2.NetcdfFile; +import ucar.nc2.Variable; +import java.io.File; +import java.io.IOException; +import java.math.BigDecimal; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.*; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class TransportResultDataServiceImpl implements TransportResultDataService { + + private final TransportTaskMapper transportTaskMapper; + private final TransportSimulationProperties simulationProperties; + private final TransportTaskChildMapper transportTaskChildMapper; + private final StationDataService stationDataService; + private final static String FORWARD="forward"; + private final static String BACK_FORWARD="backward"; + + /** + * 获取扩散数据 + * @param queryDiffusionVO + * @return + */ + @Override + public List> getDiffusionData(QueryDiffusionVO queryDiffusionVO) { + //验证任务是否存在 + TransportTask transportTask = this.transportTaskMapper.selectById(queryDiffusionVO.getTaskId()); + if(Objects.isNull(transportTask)){ + throw new RuntimeException("此任务不存在"); + } + if(TransportTaskModeEnum.FORWARD.getKey().equals(transportTask.getTaskMode())){ + return this.getForwardData(transportTask,queryDiffusionVO); + }else if(TransportTaskModeEnum.BACK_FORWARD.getKey().equals(transportTask.getTaskMode())){ + return this.getBackwardData(transportTask,queryDiffusionVO); + } + return List.of(); + } + + /** + * 获取正演数据 + * @param transportTask + * @param queryDiffusionVO + * @return + */ + private List> getForwardData(TransportTask transportTask,QueryDiffusionVO queryDiffusionVO){ + //获取nc文件路径 + String path = this.getForwardTaskNCPath(transportTask); + try (NetcdfFile ncFile = NetcdfFile.open(path.toString())) { + List lonData = NcUtil.getNCList(ncFile, "longitude"); + List latData = NcUtil.getNCList(ncFile, "latitude"); + Variable spec001Mr = ncFile.findVariable("spec001_mr"); + List> result = new ArrayList<>(); + for(Integer pointNum : queryDiffusionVO.getPointspecs()){ + int[] origin = {0, pointNum,queryDiffusionVO.getTime(),queryDiffusionVO.getLevel(), 0, 0}; + int[] section = {1, 1,1,1,latData.size(),lonData.size()}; + Array data = spec001Mr.read(origin,section); + double[] pointData = (double[]) data.get1DJavaArray(DataType.DOUBLE); + for(int i=0;i0){ + int iy = i / lonData.size(); + int ix = i % lonData.size(); + Map valMap = new HashMap<>(); + valMap.put("lon",lonData.get(ix)); + valMap.put("lat",latData.get(iy)); + valMap.put("value",pointData[i]); + result.add(valMap); + } + } + } + return result; + } catch (IOException | InvalidRangeException e) { + throw new RuntimeException(e); + } + } + + /** + * 获取反演数据 + * @param transportTask + * @param queryDiffusionVO + * @return + */ + private List> getBackwardData(TransportTask transportTask,QueryDiffusionVO queryDiffusionVO){ + //验证任务子信息 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(TransportTaskChild::getTaskId,queryDiffusionVO.getTaskId()); + queryWrapper.select(TransportTaskChild::getId,TransportTaskChild::getStationCode); + queryWrapper.orderByAsc(TransportTaskChild::getId); + List transportTaskChildren = transportTaskChildMapper.selectList(queryWrapper); + if(CollUtil.isEmpty(transportTaskChildren)){ + throw new RuntimeException("此任务站点信息不存在,请确认任务配置信息"); + } + List> result = new ArrayList<>(); + for(Integer pointNum : queryDiffusionVO.getPointspecs()){ + //获取nc文件路径 + TransportTaskChild transportTaskChild = transportTaskChildren.get(pointNum); + String path = this.getBackForwardTaskNCPath(transportTask,transportTaskChild.getStationCode()); + try (NetcdfFile ncFile = NetcdfFile.open(path.toString())) { + List lonData = NcUtil.getNCList(ncFile, "longitude"); + List latData = NcUtil.getNCList(ncFile, "latitude"); + Variable spec001Mr = ncFile.findVariable("spec001_mr"); + int[] origin = {0, 0,queryDiffusionVO.getTime(),queryDiffusionVO.getLevel(), 0, 0}; + int[] section = {1, 1,1,1,latData.size(),lonData.size()}; + Array data = spec001Mr.read(origin,section); + double[] pointData = (double[]) data.get1DJavaArray(DataType.DOUBLE); + for(int i=0;i0){ + int iy = i / lonData.size(); + int ix = i % lonData.size(); + Map valMap = new HashMap<>(); + valMap.put("lon",lonData.get(ix)); + valMap.put("lat",latData.get(iy)); + valMap.put("value",pointData[i]); + result.add(valMap); + } + } + } catch (IOException | InvalidRangeException e) { + throw new RuntimeException(e); + } + } + return result; + } + + /** + * 查询模拟结果站点序号和高度层级 + * @param taskId + * @return + */ + @Override + public Map getResultSiteNums(Integer taskId) { + Map resultMap = new HashMap<>(); + + TransportTask transportTask = this.transportTaskMapper.selectById(taskId); + if(Objects.isNull(transportTask)){ + throw new RuntimeException("此任务不存在"); + } + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(TransportTaskChild::getTaskId,taskId); + queryWrapper.select(TransportTaskChild::getId,TransportTaskChild::getStationCode); + queryWrapper.orderByAsc(TransportTaskChild::getId); + List transportTaskChildren = transportTaskChildMapper.selectList(queryWrapper); + if(CollUtil.isEmpty(transportTaskChildren)){ + throw new RuntimeException("此任务站点信息不存在,请确认任务配置信息"); + } + //获取nc文件路径 + String path = ""; + if(TransportTaskModeEnum.FORWARD.getKey().equals(transportTask.getTaskMode())){ + path = this.getForwardTaskNCPath(transportTask); + }else if(TransportTaskModeEnum.BACK_FORWARD.getKey().equals(transportTask.getTaskMode())){ + path = this.getBackForwardTaskNCPath(transportTask,transportTaskChildren.get(0).getStationCode()); + } + if(!FileUtil.exist(path)){ + throw new RuntimeException("此任务模拟结果不存在,请确认任务运行状态"); + } + //本任务模拟的台站数据 + Map stationNumMap = new LinkedHashMap<>(); + for (int i = 0; i heights = new LinkedHashMap<>(); + //全局属性 + Map globalAttr = new LinkedHashMap<>(); + try (NetcdfFile ncFile = NetcdfFile.open(path.toString())) { + Attribute outlonVar = ncFile.findGlobalAttribute("outlon0"); + Attribute outlatVar = ncFile.findGlobalAttribute("outlat0"); + Attribute dxoutVar = ncFile.findGlobalAttribute("dxout"); + Attribute dyoutVar = ncFile.findGlobalAttribute("dyout"); + Variable heightVar = ncFile.findVariable("height"); + Variable timeVar = ncFile.findVariable("time"); + globalAttr.put("outlon",outlonVar.getNumericValue()); + globalAttr.put("outlat",outlatVar.getNumericValue()); + globalAttr.put("dxout",dxoutVar.getNumericValue()); + globalAttr.put("dyout",dyoutVar.getNumericValue()); + globalAttr.put("height",heightVar.getSize()); + globalAttr.put("time",timeVar.getSize()); + + Array data = heightVar.read(); + int[] shape = data.getShape(); + Index index = data.getIndex(); + for(int i=0;i> getConformityAnalysis(Integer taskId,Integer stationId,String nuclideName,String facilityName) { + TransportTask transportTask = transportTaskMapper.selectById(taskId); + if(Objects.isNull(transportTask)){ + throw new RuntimeException("此任务不存在"); + } + + List> xeResults = stationDataService.getXeResults(stationId, transportTask.getStartTime(), transportTask.getEndTime(), nuclideName); + System.out.println(xeResults); + //获取nc文件路径 + String path = this.getForwardTaskNCPath(transportTask); + try (NetcdfFile ncFile = NetcdfFile.open(path.toString())) { + int pointNum = -1; + int maxPointNum = -1; + if (StrUtil.isNotBlank(facilityName)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(TransportTaskChild::getTaskId,taskId); + queryWrapper.select(TransportTaskChild::getId,TransportTaskChild::getStationCode); + queryWrapper.orderByAsc(TransportTaskChild::getId); + List transportTaskChildren = transportTaskChildMapper.selectList(queryWrapper); + for(int i=0;i lonData = NcUtil.getNCList(ncFile, "longitude"); + List latData = NcUtil.getNCList(ncFile, "latitude"); + List timeData = NcUtil.getNCList(ncFile, "time"); + GardsStations station = this.stationDataService.getStationById(stationId); + Map lonRecentValMap = this.getRecentValue(lonData, station.getLon()); + Map latRecentValMap = this.getRecentValue(latData, station.getLat()); + Integer lonBestIndex = Integer.parseInt(lonRecentValMap.get("bestIndex").toString()); + Integer latBestIndex = Integer.parseInt(latRecentValMap.get("bestIndex").toString()); + + Variable spec001Mr = ncFile.findVariable("spec001_mr"); + List modValList = new ArrayList<>(); + for(int i=pointNum;i<=maxPointNum;i++){ + for(int k=0;k 0){ + Instant instant = transportTask.getStartTime().toInstant(); + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + localDateTime = localDateTime.plusSeconds(timeData.get(k).intValue()); + long second = localDateTime.atZone(ZoneId.systemDefault()).toEpochSecond(); + ConcModValVo concModValVo = new ConcModValVo(); + concModValVo.setSecond(second); + concModValVo.setPointDataVal(pointDataVal); + modValList.add(concModValVo); + }else { + ConcModValVo concModValVo = new ConcModValVo(); + concModValVo.setSecond(0L); + concModValVo.setPointDataVal(pointDataVal); + modValList.add(concModValVo); + } + } + } + if(CollUtil.isNotEmpty(modValList)){ + xeResults.parallelStream().forEach(resultMap -> { + Date acqStart = (Date)resultMap.get("acquisitionStart"); + Date acqEnd = (Date)resultMap.get("acquisitionStop"); + int acqStartSecond = (int)(acqStart.getTime()/1000); + int acqStopSecond = (int)(acqEnd.getTime()/1000); + int count = 0; + Double sumVodValue = 0D; + for (ConcModValVo modVal : modValList){ + if (modVal.getSecond() >= acqStartSecond && modVal.getSecond() <= acqStopSecond) { + sumVodValue += modVal.getPointDataVal(); + count +=1; + } + } + if (sumVodValue != 0){ + //纳克转换为毫克需除以1000000 + BigDecimal vodValue = new BigDecimal(sumVodValue); + BigDecimal finalVodValue = vodValue.divide(new BigDecimal(count)).divide(new BigDecimal(1000000)).setScale(5,BigDecimal.ROUND_HALF_UP); + resultMap.put("modValue", finalVodValue); + }else { + resultMap.put("modValue", sumVodValue); + } + }); + } + } catch (IOException | InvalidRangeException e) { + throw new RuntimeException(e); + } + return xeResults; + } + + /** + * 查询任务所属核设施数据 + * + * @param taskId + * @return + */ + @Override + public List getTaskFacility(Integer taskId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(TransportTaskChild::getTaskId,taskId); + queryWrapper.select(TransportTaskChild::getId,TransportTaskChild::getStationCode); + queryWrapper.orderByAsc(TransportTaskChild::getId); + List transportTaskChildren = transportTaskChildMapper.selectList(queryWrapper); + return transportTaskChildren.stream().map(TransportTaskChild::getStationCode).collect(Collectors.toList()); + } + + /** + * 找到集合中里最接近目标值的值 + * @param data + * @param target + * @return + */ + private Map getRecentValue(List data,Double target){ + if(CollUtil.isEmpty(data)){ + throw new RuntimeException("data集合数据为空"); + } + double targetVal = target.doubleValue(); + int bestIndex = 0; + double minDist = Math.abs(data.get(0).doubleValue() - targetVal); + + for (int i = 1; i < data.size(); i++) { + double dist = Math.abs(data.get(i).doubleValue() - targetVal); + if (dist < minDist) { + minDist = dist; + bestIndex = i; + } + + } + Map resultMap = new HashMap<>(); + resultMap.put("bestIndex",bestIndex); + resultMap.put("minDist",minDist); + return resultMap; + } + + /** + * 获取正演NC结果文件路径 + * @param transportTask + * @return + */ + private String getForwardTaskNCPath(TransportTask transportTask){ + //拼接nc文件路径 + StringBuilder path = new StringBuilder(); + path.append(simulationProperties.getOutputPath()); + path.append(File.separator); + path.append(transportTask.getTaskName()); + path.append(File.separator); + path.append(FORWARD); + path.append(File.separator); + path.append("grid_conc_"+DateUtil.format(transportTask.getStartTime(),"yyyyMMddHHmmss")+".nc"); + return path.toString(); + } + + /** + * 获取反演NC结果文件路径 + * @param transportTask + * @return + */ + private String getBackForwardTaskNCPath(TransportTask transportTask,String stationCode){ + //拼接nc文件路径 + StringBuilder path = new StringBuilder(); + path.append(simulationProperties.getOutputPath()); + path.append(File.separator); + path.append(transportTask.getTaskName()); + path.append(File.separator); + path.append(BACK_FORWARD); + path.append(File.separator); + path.append(stationCode); + path.append(File.separator); + path.append("grid_time_"+DateUtil.format(transportTask.getEndTime(),"yyyyMMddHHmmss")+".nc"); + return path.toString(); + } +} diff --git a/jeecg-module-transport/src/main/java/org/jeecg/service/impl/TransportTaskServiceImpl.java b/jeecg-module-transport/src/main/java/org/jeecg/service/impl/TransportTaskServiceImpl.java index 5c14702..732c5ed 100644 --- a/jeecg-module-transport/src/main/java/org/jeecg/service/impl/TransportTaskServiceImpl.java +++ b/jeecg-module-transport/src/main/java/org/jeecg/service/impl/TransportTaskServiceImpl.java @@ -53,10 +53,11 @@ public class TransportTaskServiceImpl extends ServiceImpl page(PageRequest pageRequest, String taskName, Integer taskMode,Integer taskStatus, LocalDate startDate, LocalDate endDate) { + public IPage page(PageRequest pageRequest, String taskName, Integer taskMode,Integer taskStatus,Integer metType, LocalDate startDate, LocalDate endDate) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Objects.nonNull(taskMode),TransportTask::getTaskMode, taskMode); queryWrapper.eq(Objects.nonNull(taskStatus),TransportTask::getTaskStatus, taskStatus); + queryWrapper.eq(Objects.nonNull(metType),TransportTask::getUseMetType, metType); if(Objects.nonNull(startDate) && Objects.nonNull(endDate)){ LocalDateTime startDateTime = startDate.atTime(0, 0, 0); LocalDateTime endDateTime = endDate.atTime(23, 59, 59); @@ -185,6 +186,7 @@ public class TransportTaskServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(TransportTaskChild::getTaskId,id); + queryWrapper.orderByAsc(TransportTaskChild::getId); List transportTaskChildren = transportTaskChildMapper.selectList(queryWrapper); if(Objects.isNull(transportTaskChildren)){ throw new RuntimeException("此任务对应的flexpart模型配置信息不存在,请确认"); diff --git a/jeecg-module-transport/src/main/java/org/jeecg/vo/ConcModValVo.java b/jeecg-module-transport/src/main/java/org/jeecg/vo/ConcModValVo.java new file mode 100644 index 0000000..fdc21a7 --- /dev/null +++ b/jeecg-module-transport/src/main/java/org/jeecg/vo/ConcModValVo.java @@ -0,0 +1,11 @@ +package org.jeecg.vo; + +import lombok.Data; + +@Data +public class ConcModValVo { + + private Long second; + private Double pointDataVal; + +} diff --git a/jeecg-module-transport/src/main/java/org/jeecg/vo/QueryDiffusionVO.java b/jeecg-module-transport/src/main/java/org/jeecg/vo/QueryDiffusionVO.java new file mode 100644 index 0000000..c1466b1 --- /dev/null +++ b/jeecg-module-transport/src/main/java/org/jeecg/vo/QueryDiffusionVO.java @@ -0,0 +1,31 @@ +package org.jeecg.vo; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import java.util.List; + +@Data +public class QueryDiffusionVO { + + /** + * 任务id + */ + @NotNull(message = "任务id不能为空",groups = {QueryDiffusionVO.class}) + private Integer taskId; + /** + * 数据层级序号 + */ + @NotNull(message = "数据层级不能为空",groups = {QueryDiffusionVO.class}) + private Integer level; + /** + * 时间序号 + */ + @NotNull(message = "时间序号不能为空",groups = {QueryDiffusionVO.class}) + private Integer time; + + /** + * 站点序号 + */ + @NotNull(message = "站点序号不能为空",groups = {QueryDiffusionVO.class}) + private List pointspecs; +} diff --git a/jeecg-module-weather/src/main/java/org/jeecg/controller/WeatherDataController.java b/jeecg-module-weather/src/main/java/org/jeecg/controller/WeatherDataController.java index 4e0b169..845e210 100644 --- a/jeecg-module-weather/src/main/java/org/jeecg/controller/WeatherDataController.java +++ b/jeecg-module-weather/src/main/java/org/jeecg/controller/WeatherDataController.java @@ -39,10 +39,10 @@ public class WeatherDataController { @AutoLog(value = "分页查询气象文件数据") @Operation(summary = "分页查询气象文件数据") @GetMapping("page") - public Result page(PageRequest pageRequest, String fileExt, String dataSource, + public Result page(PageRequest pageRequest, String fileName,String fileExt, String dataSource, @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate, @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) { - IPage page = weatherDataService.page(pageRequest,fileExt,dataSource,startDate,endDate); + IPage page = weatherDataService.page(pageRequest,fileName,fileExt,dataSource,startDate,endDate); Map rspData = new HashMap<>(); rspData.put("rows", page.getRecords()); rspData.put("total", page.getTotal()); diff --git a/jeecg-module-weather/src/main/java/org/jeecg/service/WeatherDataService.java b/jeecg-module-weather/src/main/java/org/jeecg/service/WeatherDataService.java index aa6c736..d8bbf5a 100644 --- a/jeecg-module-weather/src/main/java/org/jeecg/service/WeatherDataService.java +++ b/jeecg-module-weather/src/main/java/org/jeecg/service/WeatherDataService.java @@ -29,7 +29,7 @@ public interface WeatherDataService extends IService { * @param endDate * @return */ - IPage page(PageRequest pageRequest, String fileExt, String dataSource, LocalDate startDate, LocalDate endDate); + IPage page(PageRequest pageRequest,String fileName, String fileExt, String dataSource, LocalDate startDate, LocalDate endDate); /** * 验证文件是否存在 diff --git a/jeecg-module-weather/src/main/java/org/jeecg/service/impl/WeatherDataServiceImpl.java b/jeecg-module-weather/src/main/java/org/jeecg/service/impl/WeatherDataServiceImpl.java index abbb81a..aed44f0 100644 --- a/jeecg-module-weather/src/main/java/org/jeecg/service/impl/WeatherDataServiceImpl.java +++ b/jeecg-module-weather/src/main/java/org/jeecg/service/impl/WeatherDataServiceImpl.java @@ -302,7 +302,7 @@ public class WeatherDataServiceImpl extends ServiceImpl page(PageRequest pageRequest, String fileExt, String dataSource, LocalDate startDate, LocalDate endDate) { + public IPage page(PageRequest pageRequest,String fileName, String fileExt, String dataSource, LocalDate startDate, LocalDate endDate) { LocalDateTime startTime = null; if(Objects.nonNull(startDate)){ startTime = LocalDateTime.of(startDate.getYear(), startDate.getMonth(), startDate.getDayOfMonth(), 0, 0, 0); @@ -322,6 +322,7 @@ public class WeatherDataServiceImpl extends ServiceImpl iPage = new Page<>(pageRequest.getPageNum(),pageRequest.getPageSize()); return this.baseMapper.selectPage(iPage, queryWrapper); diff --git a/jeecg-server-cloud/jeecg-event-start/src/main/resources/application.yml b/jeecg-server-cloud/jeecg-event-start/src/main/resources/application.yml index d6bc16d..34f1b75 100644 --- a/jeecg-server-cloud/jeecg-event-start/src/main/resources/application.yml +++ b/jeecg-server-cloud/jeecg-event-start/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 8003 + port: 8004 spring: application: diff --git a/jeecg-server-cloud/jeecg-sync-start/src/main/resources/application.yml b/jeecg-server-cloud/jeecg-sync-start/src/main/resources/application.yml index 27d3cc6..f18d17d 100644 --- a/jeecg-server-cloud/jeecg-sync-start/src/main/resources/application.yml +++ b/jeecg-server-cloud/jeecg-sync-start/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 8004 + port: 8005 spring: application: diff --git a/pom.xml b/pom.xml index f4cba04..6758b80 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ 0.17.0 4.5.0 - 42.2.25 + 42.7.5 11.2.0.3 4.0 8.0.27