wuww
2025-05-08 22f80ba79735ab9897530b79e34889d2082cedbc
开发根据参数生成降雨文件接口
已修改8个文件
166 ■■■■■ 文件已修改
src/main/java/com/se/nsl/config/PropertiesConfig.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/controller/SimuController.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/domain/po/SimuData.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/mapper/SimuMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/service/ResolveService.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/service/SimuService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/SimuMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/config/PropertiesConfig.java
@@ -88,6 +88,8 @@
    private Integer landuse;
    private Integer epsg;
    public String getVer() {
        return ver;
    }
@@ -403,4 +405,12 @@
    public void setCreateRainfall(String createRainfall) {
        this.createRainfall = createRainfall;
    }
    public Integer getEpsg() {
        return epsg;
    }
    public void setEpsg(Integer epsg) {
        this.epsg = epsg;
    }
}
src/main/java/com/se/nsl/controller/SimuController.java
@@ -11,6 +11,8 @@
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.gdal.ogr.Geometry;
import org.gdal.ogr.ogr;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
@@ -85,8 +87,17 @@
            SimuData data = JSON.parseObject(simu.getData(), SimuData.class);
            if (null == data) return fail("data数据格式(JSON)不正确");
            if (StringUtils.isEmpty(simu.getGeom())) return fail("geom字符串不是WKT格式");
            Geometry geom = Geometry.CreateFromWkt(simu.getGeom());
            if (!(geom.GetGeometryType() == ogr.wkbMultiPolygon || geom.GetGeometryType() == ogr.wkbPolygon))
                return fail("geom对象不是多边形");
            int rows = simuService.insert(simu);
            if (rows > 0 && (null == data.getRainfalls() || data.getRainfalls().size() < 2)) {
                resolveService.createRainfall(simu);
                simuService.updateById(simu);
            }
            return success(rows);
        } catch (Exception ex) {
@@ -128,6 +139,18 @@
    @PutMapping(value = "/updateById", produces = "application/json; charset=UTF-8")
    public R<Object> updateById(@RequestBody Simu simu) {
        try {
            if (StringUtils.isEmpty(simu.getData())) return fail("data为空");
            SimuData data = JSON.parseObject(simu.getData(), SimuData.class);
            if (null == data) return fail("data数据格式(JSON)不正确");
            if (StringUtils.isEmpty(simu.getGeom())) return fail("geom字符串不是WKT格式");
            Geometry geom = Geometry.CreateFromWkt(simu.getGeom());
            if (!(geom.GetGeometryType() == ogr.wkbMultiPolygon || geom.GetGeometryType() == ogr.wkbPolygon))
                return fail("geom对象不是多边形");
            if (null == data.getRainfalls() || data.getRainfalls().size() < 2) resolveService.createRainfall(simu);
            return success(simuService.updateById(simu));
        } catch (Exception ex) {
            return fail(ex, null);
src/main/java/com/se/nsl/domain/po/SimuData.java
@@ -102,6 +102,7 @@
        return minx + "," + miny + "," + maxx + "," + maxy;
    }
    @JSONField(serialize = false)
    public SpatialReference getSpatialReference() {
        return GdalHelper.createSpatialReference(this.getEpsg());
    }
src/main/java/com/se/nsl/mapper/SimuMapper.java
@@ -13,6 +13,8 @@
@Repository
@SuppressWarnings("ALL")
public interface SimuMapper extends BaseMapper<Simu> {
    int insert(Simu simu);
    int inserts(@Param("list") List<Simu> list);
    int updates(@Param("list") List<Simu> list);
src/main/java/com/se/nsl/service/ResolveService.java
@@ -22,6 +22,8 @@
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
@@ -31,6 +33,7 @@
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
@Slf4j
@Service
@@ -52,6 +55,8 @@
    SimpleDateFormat YYYYMDHM = new SimpleDateFormat("yyyy M d H m ");
    List<String> MODES = new ArrayList<>(Arrays.asList("正态分布", "平均分布", "波动平均分布", "持续上升"));
    public int start(Simu simu) {
        Date now = new Date();
        String date = StringHelper.YMDHMS2_FORMAT.format(now);
@@ -67,8 +72,8 @@
        SimuData data = JSON.parseObject(simu.getData(), SimuData.class);
        data.setInPath(date);
        data.setOutPath(date);
        data.setEpsg(4548);
        data.setEnvelope(envelope);
        data.setEpsg(config.getEpsg());
        simu.setData(JSON.toJSONString(data));
        simu.setServiceName(date);
@@ -101,7 +106,7 @@
            update(simu, 1, "初始化参数");
            initArgs(data);
            createRainfallFile(data);
            createRainfallFile(simu, data);
            update(simu, 2, "调用求解器");
            callUwSolver(data);
@@ -152,9 +157,16 @@
        f.mkdirs();
    }
    private void createRainfallFile(SimuData data) throws Exception {
    private void createRainfallFile(Simu simu, SimuData data) throws Exception {
        List<Rainfall> rainfalls = data.getRainfalls();
        if (null == rainfalls || rainfalls.size() < 2) return; // CollUtil.isEmpty
        if (null == rainfalls || rainfalls.size() < 2) createRainfall(simu);
        String dat = config.getInPath() + File.separator + "Rainfalls" + File.separator + simu.getId() + ".dat";
        String rainfallFile = config.getInPath() + File.separator + data.getInPath() + File.separator + "rainfall.dat";
        if (new File(dat).exists()) {
            Files.copy(Paths.get(dat), Paths.get(rainfallFile), StandardCopyOption.REPLACE_EXISTING);
            return;
        }
        List<String> list = new ArrayList<>();
        list.add(config.getRainfallTitle());
@@ -174,7 +186,6 @@
        //list.add(prefix + YYYYMDHM.format(rainfalls.get(c).getTime()) + getMinVal(rainfalls.get(c).getIntensity() / unit, DIGIT));
        list.add(String.format("%s%s%f", prefix, YYYYMDHM.format(rainfalls.get(c).getTime()), getMinVal(rainfalls.get(c).getIntensity() / unit, DIGIT)));
        String rainfallFile = config.getInPath() + File.separator + data.getInPath() + File.separator + "rainfall.dat";
        Files.write(Paths.get(rainfallFile), list, StandardCharsets.UTF_8);
    }
@@ -294,10 +305,79 @@
        }
    }
    public String createRainfallCsv(String csvPath, String type, double total, double intensity, int hours) {
    public String createRainfallCsv(String csvPath, String mode, double total, double intensity, int hours) {
        // python 脚本名.py <参数1-csv文件名> <参数2-降雨模式:正态分布|平均分布|波动平均分布|持续上升> <参数3-降雨总量> <参数4-最大雨强> <参数5-降雨时间(分钟)>
        String cmd = String.format("%s \"%s\" \"%s\" %f %f %d", config.getCreateRainfall(), csvPath, type, total, intensity, hours * 60);
        String cmd = String.format("%s \"%s\" \"%s\" %f %f %d", config.getCreateRainfall(), csvPath, mode, total, intensity, hours * 60);
        return callBat(cmd);
    }
    public void createRainfall(Simu simu) throws Exception {
        SimuData data = JSON.parseObject(simu.getData(), SimuData.class);
        if (null == data.getMode() || MODES.contains(data.getMode())) data.setMode(MODES.get(0));
        if (StringUtils.isEmpty(data.getIntensityUnit())) data.setIntensityUnit("mm/h");
        Geometry geom = Geometry.CreateFromWkt(simu.getGeom());
        if (geom.GetGeometryType() == ogr.wkbMultiPolygon) geom = geom.GetGeometryRef(0);
        double[] envelope = new double[4];
        geom.GetEnvelope(envelope);
        data.setEnvelope(envelope);
        data.setEpsg(config.getEpsg());
        String basePath = config.getInPath() + File.separator + "Rainfalls";
        if (!new File(basePath).exists()) new File(basePath).mkdirs();
        if (null == simu.getCreateTime()) simu.setCreateTime(new Timestamp(new Date().getTime()));
        String csvPath = basePath + File.separator + simu.getId() + ".csv";
        int unit = StringUtils.isEmpty(data.getIntensityUnit()) || "mm/h".equals(data.getIntensityUnit()) ? 60 : 5;
        createRainfallCsv(csvPath, data.getMode(), data.getTotal(), data.getIntensity() / unit, data.getDuration());
        List<Double> list = getValues(csvPath);
        if (!CollUtil.isEmpty(list)) {
            data.setRainfalls(new ArrayList<>());
            setRainfalls(simu, data, list);
        }
        simu.setData(JSON.toJSONString(data));
    }
    private List<Double> getValues(String csvPath) throws Exception {
        if (!new File(csvPath).exists()) return null;
        List<String> list = Files.readAllLines(Paths.get(csvPath));
        list.remove(0);
        //list.remove(list.size() - 1);
        return list.stream()
                .map(s -> new BigDecimal(s).setScale(6, RoundingMode.HALF_DOWN).doubleValue())
                .collect(Collectors.toList());
    }
    private void setRainfalls(Simu simu, SimuData data, List<Double> vals) throws Exception {
        String basePath = config.getInPath() + File.separator + "Rainfalls";
        String dat = basePath + File.separator + simu.getId() + ".dat";
        Calendar cal = Calendar.getInstance();
        cal.setTime(data.getStartTime());
        List<String> list = new ArrayList<>();
        list.add(config.getRainfallTitle());
        double centerX = ComHelper.getMinVal((data.getMinx() + data.getMaxx()) / 2, DIGIT);
        double centerY = ComHelper.getMinVal((data.getMiny() + data.getMaxy()) / 2, DIGIT);
        String prefix = config.getRainfallSite() + " " + centerX + " " + centerY + " ";
        Double total = 0.0;
        for (int i = 0, c = vals.size(); i < c; i++) {
            total += vals.get(i);
            if (i % 15 == 0) {
                data.getRainfalls().add(new Rainfall(cal.getTime(), vals.get(i), total));
            }
            list.add(String.format("%s%s%f", prefix, YYYYMDHM.format(cal.getTime()), vals.get(i)));
            cal.add(Calendar.MINUTE, 1);
        }
        Files.write(Paths.get(dat), list, StandardCharsets.UTF_8);
    }
}
src/main/java/com/se/nsl/service/SimuService.java
@@ -82,7 +82,11 @@
     * @return 新增成功的记录数
     */
    public int insert(Simu simu) {
        return simuMapper.inserts(Collections.singletonList(simu));
        return simuMapper.insert(simu);
    }
    public int inserts(List<Simu> list) {
        return simuMapper.inserts(list);
    }
    /**
src/main/resources/application-dev.yml
@@ -147,6 +147,7 @@
  createRainfall: '"C:\Program Files\Python310\python.exe" D:\terrait\NslServer\data\CreatRainfall.py'
  rainfallTitle: Station Longitude Latitude Year Month Day Hour Minute Intensity
  rainfallSite: beijing
  epsg: 4548
  saveFrames: 10
  # 土地利用:1-Cropland,2-Forest,3-Shrub,4-Grassland,5-Water,6-Snow/Ice,7-Barren,8-Impervious,9-Wetland
  landuse: 2
src/main/resources/mapper/SimuMapper.xml
@@ -1,6 +1,35 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.se.nsl.mapper.SimuMapper">
    <insert id="insert" parameterType="com.se.nsl.domain.po.Simu">
        <selectKey resultType="java.lang.Long" order="AFTER" keyProperty="id">
            select currval('nsl.simu_id_seq'::regclass) as id
        </selectKey>
        insert into nsl.simu (
            name, service_name, type, area_type, data, status, result, create_time, create_user, bak, geom)
        values (
            #{name},
            #{serviceName},
            #{type},
            #{areaType},
            #{data},
            #{status},
            #{result},
            now(),
            #{createUser},
            #{bak},
            <choose>
                <when test="geom != null and geom != ''">
                    ST_GeomFromText('${geom}')
                </when>
                <otherwise>
                    null
                </otherwise>
            </choose>
        )
    </insert>
    <insert id="inserts" parameterType="com.se.nsl.domain.po.Simu">
        insert into nsl.simu (
            name, service_name, type, area_type, data, status, result, create_time, create_user, bak, geom)