¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.se.nsl.service; |
| | | |
| | | import com.fasterxml.jackson.core.JsonProcessingException; |
| | | import com.fasterxml.jackson.databind.JsonNode; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.se.nsl.config.PropertiesConfig; |
| | | import com.se.nsl.config.RealTimeSimulationConfig; |
| | | import com.se.nsl.domain.dto.*; |
| | | import com.se.nsl.domain.po.RainGauge; |
| | | import com.se.nsl.domain.po.Simu; |
| | | import com.se.nsl.domain.po.SimuData; |
| | | import com.se.nsl.domain.vo.ConfigVo; |
| | | import com.se.nsl.domain.vo.ResultVo; |
| | | import com.se.nsl.mapper.SimuMapper; |
| | | import com.se.nsl.utils.HttpRequestUtil; |
| | | import com.se.nsl.utils.TimeFormatUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | import org.springframework.scheduling.annotation.EnableAsync; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.io.*; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Paths; |
| | | import java.nio.file.StandardOpenOption; |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.Future; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Slf4j |
| | | @Service |
| | | @EnableAsync |
| | | public class RealTimeSimulationAsyncService { |
| | | |
| | | public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; |
| | | public static final String JSON_EXT = ".json"; |
| | | public static final String DEM_TIF = "DEM.tif"; |
| | | public static final String RESULT_ZARR = "result.zarr"; |
| | | @Resource |
| | | PropertiesConfig config; |
| | | @Resource |
| | | TestService testService; |
| | | @Resource |
| | | ResolveService resolveService; |
| | | @Resource |
| | | SimuMapper simuMapper; |
| | | |
| | | private final ObjectMapper mapper = new ObjectMapper(); |
| | | @Resource |
| | | private RealTimeSimulationConfig rtsConfig; |
| | | private static final long MILLIS_OF_ONE_DAY = 86400000; |
| | | |
| | | // åå¨ä»»å¡æ§è¡ç¶æ |
| | | private final Map<Integer, TaskStatus> taskStatusMap = new ConcurrentHashMap<>(); |
| | | // åå¨ä»»å¡æ§è¡çFuture对象ï¼ç¨äºåæ¶ä»»å¡ |
| | | private final Map<String, Future<?>> taskFutureMap = new ConcurrentHashMap<>(); |
| | | // @Autowired |
| | | // private ThreadPoolTaskExecutor taskExecutor; |
| | | |
| | | @Async("realTimeExecutor") |
| | | public void startSimulation(Simu simu) throws IOException { |
| | | int taskId = simu.getId().intValue(); |
| | | // æ£æ¥ä»»å¡æ¯å¦å·²åå¨ |
| | | if (taskStatusMap.containsKey(taskId) && |
| | | taskStatusMap.get(taskId).getStatus() == TaskStatus.Status.RUNNING) { |
| | | throw new IllegalStateException("Task " + taskId + " is already running"); |
| | | } |
| | | |
| | | // åå§åä»»å¡ç¶æ |
| | | TaskStatus status = new TaskStatus(); |
| | | status.setTaskId(taskId); |
| | | status.setStatus(TaskStatus.Status.RUNNING); |
| | | taskStatusMap.put(taskId, status); |
| | | |
| | | updateTaskStatus(simu, "è¿è¡ä¸"); |
| | | |
| | | boolean shouldRun = true; |
| | | while(shouldRun) { |
| | | InputStream stream = RealTimeSimulationAsyncService.class.getResourceAsStream("/device_info.json"); |
| | | List<DeviceInfo> deviceInfos = mapper.readValue(stream, |
| | | mapper.getTypeFactory().constructCollectionType(List.class, DeviceInfo.class)); |
| | | String serviceName = simu.getServiceName(); |
| | | long currentTime = getCurrentTime(); |
| | | if (serviceName == null) { //没æè¿è¡è¿æ¨¡æè®¡ç® |
| | | serviceName = TimeFormatUtil.formatTime(currentTime, "yyyyMMddHHmmss"); |
| | | simu.setServiceName(serviceName); |
| | | File serviceNameDir = new File(config.getInPath(), serviceName); |
| | | serviceNameDir.mkdir(); |
| | | executeSimulateTask(simu, deviceInfos, serviceNameDir, currentTime, serviceName, true); |
| | | simuMapper.updates(Collections.singletonList(simu)); |
| | | } else { |
| | | File serviceNameDir = new File(config.getInPath(), serviceName); |
| | | executeSimulateTask(simu, deviceInfos, serviceNameDir, currentTime, serviceName, false); |
| | | } |
| | | try { |
| | | Thread.sleep(TimeUnit.MINUTES.toMillis(5)); //æå5åé |
| | | } catch (InterruptedException e) { |
| | | log.error("executing real time simulation exception:", e); |
| | | } |
| | | if (taskStatusMap.get(taskId).getStatus() == TaskStatus.Status.CANCELLED) { |
| | | shouldRun = false; |
| | | } |
| | | } |
| | | updateTaskStatus(simu, "已忢"); |
| | | log.info("id为{}çæ¨¡æä»»å¡å·²åæ¢", taskId); |
| | | } |
| | | |
| | | //æ´æ°æ¨¡æä»»å¡çè¿è¡ç¶æå°æ°æ®åº |
| | | private void updateTaskStatus(Simu simu, String result) { |
| | | simu.setResult(result); |
| | | simuMapper.updateResult(simu); |
| | | } |
| | | |
| | | public void stopSimulation(int taskId) { |
| | | TaskStatus status = taskStatusMap.get(taskId); |
| | | if (status == null) { |
| | | throw new IllegalArgumentException("æªæ¾å°id为" + taskId + "模æä»»å¡"); |
| | | } |
| | | |
| | | if (status.getStatus() == TaskStatus.Status.RUNNING) { |
| | | // æ è®°ä»»å¡ä¸ºå·²åæ¶ |
| | | status.setCancelled(true); |
| | | status.setStatus(TaskStatus.Status.CANCELLED); |
| | | } |
| | | } |
| | | |
| | | private long getCurrentTime() { |
| | | double offsetDays = rtsConfig.getOffsetDays(); |
| | | long millis = (long) (offsetDays * MILLIS_OF_ONE_DAY); |
| | | return System.currentTimeMillis() - millis; |
| | | } |
| | | |
| | | private String executeSimulateTask(Simu simu, List<DeviceInfo> deviceInfos, File serviceNameDir, |
| | | long currentTime, String serviceName, boolean firstTime) throws IOException { |
| | | SimuData simuData = mapper.readValue(simu.getData(), SimuData.class); |
| | | simuData.setOutPath(serviceName); |
| | | simuData.setInPath(serviceName); |
| | | List<RainGauge> gauges = simuData.getGauges(); //é¨éè®¡ä¿¡æ¯ |
| | | if (firstTime) { |
| | | resolveService.initArgs(simu, simuData); |
| | | } |
| | | //æ ¹æ®é¨é计读åä½éæ°æ® |
| | | File newDatFile = generateNewRainfallFile(gauges, deviceInfos, serviceNameDir, currentTime); |
| | | //çæä¸ä¸ªæ°ççæzarrçé
ç½®æä»¶ |
| | | ConfigVo configVo; |
| | | if (firstTime) { |
| | | configVo = firstTimeZarrConfigFile(serviceNameDir, currentTime, newDatFile); |
| | | } else { |
| | | configVo = generateNewZarrConfigFile(serviceNameDir, serviceName, currentTime, newDatFile); |
| | | } |
| | | File newConfigFile = new File(serviceNameDir, serviceName + JSON_EXT); |
| | | mapper.writeValue(newConfigFile, configVo); |
| | | //æ§è¡æ±è§£å¨è¿ç® |
| | | String cmd = String.format("%s \"%s\"", config.getUwSolverBat(), newConfigFile); |
| | | callBat(cmd); |
| | | |
| | | File newZarr2TifJson; |
| | | if (firstTime) { |
| | | newZarr2TifJson = generateNewZarr2TifJson(serviceNameDir, currentTime, Collections.emptyList()); |
| | | } else { |
| | | //çæä¸ä¸ªæ°çzarr转tifçjsonæä»¶ |
| | | ResultVo result = configVo.getResult(); |
| | | Integer fromFrame = result.getLastFrames(); |
| | | Integer toFrame = result.getSave_frames() - 1; |
| | | newZarr2TifJson = generateNewZarr2TifJson(serviceNameDir, currentTime, Arrays.asList(fromFrame, toFrame)); |
| | | } |
| | | //æ§è¡zarr转tif |
| | | String zarr2TifCmd = String.format("%s \"%s\"", config.getZarr2tifBat(), newZarr2TifJson); |
| | | callBat(zarr2TifCmd); |
| | | //è¿åæ°çlayer.jsonåç§° |
| | | if (firstTime) { |
| | | return generateLayerJsonAndPng(serviceName, serviceNameDir, -1); |
| | | } else { |
| | | return generateLayerJsonAndPng(serviceName, serviceNameDir, currentTime); |
| | | } |
| | | } |
| | | |
| | | private String generateLayerJsonAndPng(String serviceName, File serviceNameDir, |
| | | long currentTime) throws IOException { |
| | | ResultDto resultDto = new ResultDto(); |
| | | resultDto.setServiceName(serviceName); |
| | | File temp = Paths.get(config.getOutPath(), serviceName, "temp").toFile(); |
| | | resultDto.setTemp(temp.getAbsolutePath()); |
| | | resultDto.setOutPath(Paths.get(config.getOutPath(), serviceName).toString()); |
| | | File dem = new File(serviceNameDir, DEM_TIF); |
| | | resultDto.setTerrainFile(dem.getAbsolutePath()); |
| | | File newDepthDir; |
| | | if (currentTime < 0) { |
| | | newDepthDir = new File(serviceNameDir + File.separator + "depth"); |
| | | } else { |
| | | newDepthDir = new File(serviceNameDir + File.separator + "depth_" + currentTime); |
| | | } |
| | | resultDto.setWaterPath(newDepthDir.getAbsolutePath()); |
| | | LayerDto layerDto = new LayerDto(config.getVer(), config.getEpsg(), config.getSizes()); |
| | | String newLayerJsonName; |
| | | if (currentTime < 0) { |
| | | newLayerJsonName = "layer.json"; |
| | | } else { |
| | | newLayerJsonName = "layer_" + currentTime + JSON_EXT; |
| | | } |
| | | layerDto.setName(newLayerJsonName); |
| | | testService.processRealTime(resultDto, layerDto); |
| | | log.info("宿¶æ¨¡æå®æ"); |
| | | return newLayerJsonName; |
| | | } |
| | | |
| | | private File generateNewZarr2TifJson(File serviceNameDir, long currentTime, List<Object> range) throws IOException { |
| | | Zarr2Tif zarr2Tif; |
| | | File newZarr2TifJson; |
| | | String newZarrPath; |
| | | String geotiffDir; |
| | | if (range.isEmpty()) { |
| | | zarr2Tif = new Zarr2Tif(); |
| | | newZarrPath = serviceNameDir + File.separator + RESULT_ZARR; |
| | | geotiffDir = serviceNameDir + File.separator + "depth"; |
| | | zarr2Tif.setTerrain_file(serviceNameDir + File.separator + DEM_TIF); |
| | | newZarr2TifJson = new File(serviceNameDir, "zarr2tif.json"); |
| | | } else { |
| | | File srcZarr2TifJson = new File(serviceNameDir, "zarr2tif.json"); |
| | | zarr2Tif = mapper.readValue(srcZarr2TifJson, Zarr2Tif.class); |
| | | //ä¿®æ¹zarr2tif对象ä¸çåæ®µ |
| | | newZarrPath = serviceNameDir + File.separator + RESULT_ZARR; |
| | | geotiffDir = serviceNameDir + File.separator + "depth_" + currentTime; |
| | | newZarr2TifJson = new File(serviceNameDir, "zarr2tif_" + currentTime + JSON_EXT); |
| | | } |
| | | zarr2Tif.setGeotiff_dir(geotiffDir); |
| | | zarr2Tif.setZarr_file(newZarrPath); |
| | | zarr2Tif.setRange(range); |
| | | mapper.writeValue(newZarr2TifJson, zarr2Tif); |
| | | return newZarr2TifJson; |
| | | } |
| | | |
| | | private ConfigVo firstTimeZarrConfigFile(File serviceNameDir, long currentTime, File newDatFile) { |
| | | ConfigVo configVo = new ConfigVo(); |
| | | String serviceNameDirPath = serviceNameDir.getAbsolutePath(); |
| | | configVo.setTerrain(serviceNameDirPath + File.separator + DEM_TIF); |
| | | configVo.setLanduse(serviceNameDirPath + File.separator + "Landuse.tif"); |
| | | File stationFile = new File(serviceNameDir, "Station.tif"); |
| | | if (stationFile.exists()) { |
| | | configVo.setStation(stationFile.getAbsolutePath()); |
| | | } |
| | | int realTimeSimulateTime = 300; //æ¨¡ææ¶é´ï¼é»è®¤ä¸º5minï¼å³300s |
| | | int realTimeInterval = rtsConfig.getRealTimeInterval(); //æ¯å¸§çé´éæ¶é´ |
| | | List<String> rainGauge = new ArrayList<>(); |
| | | rainGauge.add(newDatFile.getAbsolutePath());//raingage file |
| | | rainGauge.add("mm/min"); |
| | | configVo.setRaingage(rainGauge); |
| | | String saveName = serviceNameDir + File.separator + RESULT_ZARR; |
| | | ResultVo result = new ResultVo(saveName, realTimeSimulateTime / realTimeInterval, |
| | | realTimeInterval, "continue", null); |
| | | result.setSave_interval(realTimeInterval); |
| | | result.setSave_timestamp0(TimeFormatUtil.formatTime(currentTime, YYYY_MM_DD_HH_MM_SS)); |
| | | configVo.setDuration(realTimeSimulateTime); |
| | | result.setSave_name(saveName); |
| | | result.setSave_filter(config.getSaveFilter()); |
| | | configVo.setResult(result); |
| | | return configVo; |
| | | } |
| | | |
| | | private ConfigVo generateNewZarrConfigFile(File serviceNameDir, String serviceName, long currentTime, File newDatFile) throws IOException { |
| | | File configFile = new File(serviceNameDir, serviceName + JSON_EXT); |
| | | ConfigVo configVo = mapper.readValue(configFile, ConfigVo.class); |
| | | File stationFile = new File(serviceNameDir, "Station.tif"); |
| | | if (stationFile.exists()) { |
| | | configVo.setStation(stationFile.getAbsolutePath()); |
| | | } |
| | | int realTimeSimulateTime = 300; //æ¨¡ææ¶é´ï¼é»è®¤ä¸º5minï¼å³300s |
| | | int realTimeInterval = rtsConfig.getRealTimeInterval(); //æ¯å¸§çé´éæ¶é´ |
| | | configVo.getRaingage().set(0, newDatFile.getAbsolutePath()); //raingage file |
| | | ResultVo result = configVo.getResult(); |
| | | Integer lastFrames = result.getLastFrames(); |
| | | if (lastFrames == null) { |
| | | lastFrames = 0; |
| | | } |
| | | Integer saveStart = result.getSave_start(); |
| | | Integer saveInterval = result.getSave_interval(); |
| | | Integer saveFrames = result.getSave_frames(); |
| | | int newStartPoint = saveStart + (saveFrames - lastFrames) * saveInterval; |
| | | int newSaveFrames = saveFrames + (realTimeSimulateTime / realTimeInterval); |
| | | result.setSave_start(newStartPoint); //èµ·å§æ¶é´è¦å¨ä¸æ¬¡æ¶é´çåºç¡ä¸å¼å§ |
| | | result.setLastFrames(saveFrames); |
| | | result.setSave_frames(newSaveFrames); //ä¿ç5帧ï¼å¨åæ¥çåºç¡ä¸å¢å 5帧 |
| | | result.setSave_timestamp0(TimeFormatUtil.formatTime(currentTime, YYYY_MM_DD_HH_MM_SS)); |
| | | configVo.setDuration(newStartPoint + realTimeSimulateTime); |
| | | return configVo; |
| | | } |
| | | |
| | | private File generateNewRainfallFile(List<RainGauge> gauges, List<DeviceInfo> deviceInfos, |
| | | File serviceNameDir, long currentTime) throws IOException { |
| | | String title = config.getRainfallTitle(); |
| | | List<String> newLines = new ArrayList<>(); |
| | | newLines.add(title); |
| | | Map<String, Integer> deviceInfoMap = deviceInfos.stream().collect(Collectors.toMap(DeviceInfo::getId, DeviceInfo::getMappingId)); |
| | | List<RainRecord> rainRecords = new ArrayList<>(); |
| | | for (RainGauge gauge : gauges) { |
| | | String id = gauge.getId(); |
| | | Integer mappingId = deviceInfoMap.getOrDefault(id, 0); |
| | | RainRecord rr = getRainGaugeResult(gauge, mappingId, currentTime); |
| | | rainRecords.add(rr); |
| | | } |
| | | fillEmptyValue(rainRecords); //å¡«å
没æå¼çé¨é计 |
| | | for (RainRecord rr : rainRecords) { |
| | | newLines.add(rr.toString()); |
| | | } |
| | | File newDatFile = new File(serviceNameDir, "rainfall_" + currentTime + ".dat"); |
| | | if (!newDatFile.exists()) newDatFile.createNewFile(); |
| | | Files.write(newDatFile.toPath(), newLines, StandardOpenOption.TRUNCATE_EXISTING); |
| | | return newDatFile; |
| | | } |
| | | |
| | | //å°é¨é计ä¸ç©ºå¼ï¼intensity为-1ï¼çé¨åå¡«å
å¼ |
| | | private void fillEmptyValue(List<RainRecord> rainRecords) { |
| | | double[] rainValues = rainRecords.stream().mapToDouble(r -> r.getIntensity()).toArray(); |
| | | double[] forwardValues = forwardFill(rainValues); |
| | | double[] backwordValues = backwordFill(rainValues); |
| | | for (int i = 0; i < rainRecords.size(); i++) { |
| | | RainRecord rr = rainRecords.get(i); |
| | | double filledValue = forwardValues[i] != -1 ? forwardValues[i] : backwordValues[i]; |
| | | rr.setIntensity(filledValue); |
| | | } |
| | | //妿齿¯-1ï¼å设置为0 |
| | | for (RainRecord rr : rainRecords) { |
| | | double intensity = rr.getIntensity(); |
| | | if (intensity == -1) { |
| | | rr.setIntensity(0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private double[] forwardFill(double[] rainValues) { |
| | | double[] result = Arrays.copyOf(rainValues, rainValues.length); |
| | | double lastValid = -1D; |
| | | for (int i = 0; i < result.length; i++) { |
| | | if (result[i] != -1) { |
| | | lastValid = result[i]; |
| | | } else if (lastValid != -1) { |
| | | result[i] = lastValid; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private double[] backwordFill(double[] rainValues) { |
| | | double[] result = Arrays.copyOf(rainValues, rainValues.length); |
| | | double lastValid = -1D; |
| | | for (int i = result.length - 1; i >= 0; i--) { |
| | | if (result[i] != -1) { |
| | | lastValid = result[i]; |
| | | } else if (lastValid != -1) { |
| | | result[i] = lastValid; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private RainRecord getRainGaugeResult(RainGauge gauge, int stationId, long currentTime) throws JsonProcessingException { |
| | | double lon = gauge.getX(); |
| | | double lat = gauge.getY(); |
| | | LocalDateTime dateTime = TimeFormatUtil.toDate(currentTime); |
| | | int year = dateTime.getYear(); |
| | | int month = dateTime.getMonthValue(); |
| | | int day = dateTime.getDayOfMonth(); |
| | | int hour = dateTime.getHour(); |
| | | int minute = dateTime.getMinute(); |
| | | String id = gauge.getId(); |
| | | long someMinutesAgo = currentTime - TimeUnit.MINUTES.toMillis(rtsConfig.getRequestOffsetMinutes()); |
| | | String startTime = TimeFormatUtil.formatTime(someMinutesAgo, YYYY_MM_DD_HH_MM_SS); |
| | | String endTime = TimeFormatUtil.formatTime(currentTime, YYYY_MM_DD_HH_MM_SS); |
| | | double intensity = getIntensityByDeviceId(id, startTime, endTime); //ä¿çæå®ä½æ°å°æ° |
| | | // return String.format("%s %s %s %s %s %s %s %s %s", |
| | | // stationId, lon, lat, year, month, day, hour, minute, String.format("%.6f", intensity)); |
| | | return new RainRecord(stationId, lon, lat, year, month, day, hour, minute, intensity); |
| | | } |
| | | |
| | | //æ ¹æ®é¨é计æ è¯æ¥è¯¢é¨éæ°æ® |
| | | private double getIntensityByDeviceId(String deviceId, String startTime, String endTime) throws JsonProcessingException { |
| | | RemoteGaugeInput input = new RemoteGaugeInput(); |
| | | input.setCurrentPage(1); |
| | | input.setPageSize(2); |
| | | RemoteGaugeInput.FilterObject filterObject = new RemoteGaugeInput.FilterObject(); |
| | | filterObject.setDeviceCode(deviceId); |
| | | filterObject.setSendTimeList(Arrays.asList(startTime, endTime)); |
| | | input.setFilterObject(filterObject); |
| | | String url = rtsConfig.getUrl(); |
| | | String token = rtsConfig.getToken(); |
| | | ResponseEntity<String> post = HttpRequestUtil.post(url, input, String.class, token); |
| | | String body = post.getBody(); |
| | | JsonNode jsonNode = mapper.readTree(body); |
| | | JsonNode pageData = jsonNode.get("data").get("pageData"); |
| | | if (!pageData.isEmpty()) { |
| | | return pageData.get(0).get("value").asDouble(); |
| | | } |
| | | return -1D; |
| | | } |
| | | |
| | | private String callBat(String cmd) { |
| | | try { |
| | | ProcessBuilder pb = new ProcessBuilder("cmd", "/c", cmd); |
| | | pb.redirectErrorStream(true); // åå¹¶é误æµå°æ åè¾åº |
| | | Process process = pb.start(); |
| | | process.getOutputStream().close(); |
| | | try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))) { |
| | | String line; |
| | | while ((line = reader.readLine()) != null) { |
| | | log.info(line); |
| | | } |
| | | } |
| | | int exitCode = process.waitFor(); |
| | | return "" + exitCode; // sb.toString(); |
| | | } catch (Exception ex) { |
| | | log.error(ex.getMessage(), ex); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | static class RainRecord { |
| | | private int stationId; |
| | | private double lon; |
| | | private double lat; |
| | | private int year; |
| | | private int month; |
| | | private int day; |
| | | private int hour; |
| | | private int minute; |
| | | private double intensity; //-1ä»£è¡¨æ²¡ææ°å¼ |
| | | |
| | | public RainRecord() { |
| | | } |
| | | |
| | | public RainRecord(int stationId, double lon, double lat, int year, int month, |
| | | int day, int hour, int minute, double intensity) { |
| | | this.stationId = stationId; |
| | | this.lon = lon; |
| | | this.lat = lat; |
| | | this.year = year; |
| | | this.month = month; |
| | | this.day = day; |
| | | this.hour = hour; |
| | | this.minute = minute; |
| | | this.intensity = intensity; |
| | | } |
| | | |
| | | public int getStationId() { |
| | | return stationId; |
| | | } |
| | | |
| | | public void setStationId(int stationId) { |
| | | this.stationId = stationId; |
| | | } |
| | | |
| | | public double getLon() { |
| | | return lon; |
| | | } |
| | | |
| | | public void setLon(double lon) { |
| | | this.lon = lon; |
| | | } |
| | | |
| | | public double getLat() { |
| | | return lat; |
| | | } |
| | | |
| | | public void setLat(double lat) { |
| | | this.lat = lat; |
| | | } |
| | | |
| | | public int getYear() { |
| | | return year; |
| | | } |
| | | |
| | | public void setYear(int year) { |
| | | this.year = year; |
| | | } |
| | | |
| | | public int getMonth() { |
| | | return month; |
| | | } |
| | | |
| | | public void setMonth(int month) { |
| | | this.month = month; |
| | | } |
| | | |
| | | public int getDay() { |
| | | return day; |
| | | } |
| | | |
| | | public void setDay(int day) { |
| | | this.day = day; |
| | | } |
| | | |
| | | public int getHour() { |
| | | return hour; |
| | | } |
| | | |
| | | public void setHour(int hour) { |
| | | this.hour = hour; |
| | | } |
| | | |
| | | public int getMinute() { |
| | | return minute; |
| | | } |
| | | |
| | | public void setMinute(int minute) { |
| | | this.minute = minute; |
| | | } |
| | | |
| | | public double getIntensity() { |
| | | return intensity; |
| | | } |
| | | |
| | | public void setIntensity(double intensity) { |
| | | this.intensity = intensity; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "" + stationId + " " + lon + " " + lat + |
| | | " " + year + " " + month + " " + day + |
| | | " " + hour + " " + minute + " " + String.format("%.6f", intensity); |
| | | } |
| | | } |
| | | |
| | | // ä»»å¡ç¶æå
é¨ç±» |
| | | static class TaskStatus { |
| | | public enum Status { |
| | | RUNNING, COMPLETED, FAILED, CANCELLED |
| | | } |
| | | |
| | | private int taskId; |
| | | private Status status; |
| | | private boolean cancelled; |
| | | private String errorMessage; |
| | | |
| | | public int getTaskId() { |
| | | return taskId; |
| | | } |
| | | |
| | | public void setTaskId(int taskId) { |
| | | this.taskId = taskId; |
| | | } |
| | | |
| | | public Status getStatus() { |
| | | return status; |
| | | } |
| | | |
| | | public void setStatus(Status status) { |
| | | this.status = status; |
| | | } |
| | | |
| | | public boolean isCancelled() { |
| | | return cancelled; |
| | | } |
| | | |
| | | public void setCancelled(boolean cancelled) { |
| | | this.cancelled = cancelled; |
| | | } |
| | | |
| | | public String getErrorMessage() { |
| | | return errorMessage; |
| | | } |
| | | |
| | | public void setErrorMessage(String errorMessage) { |
| | | this.errorMessage = errorMessage; |
| | | } |
| | | } |
| | | |
| | | } |