e040d561d798536f666fffbe33f9b43ecbed5bba..7b2459ba1c1f14c06f17914f3d53ebcd6e2641a3
2025-05-16 wuww
解决土地利用裁剪后使用异常
7b2459 对比 | 目录
2025-05-16 wuww
添加裁剪DEM、土地利用功能
cfdc56 对比 | 目录
已修改6个文件
157 ■■■■ 文件已修改
src/main/java/com/se/nsl/config/PropertiesConfig.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/controller/TestController.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/domain/vo/ConfigVo.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/helper/ComHelper.java 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/service/ResolveService.java 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-prod.yml 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/config/PropertiesConfig.java
@@ -78,6 +78,12 @@
    private String flowPath;
    private String sourceDem;
    private String sourceLanduse;
    private String landuseFile;
    private boolean copyTif;
    private String tifPath;
@@ -413,4 +419,28 @@
    public void setEpsg(Integer epsg) {
        this.epsg = epsg;
    }
    public String getSourceDem() {
        return sourceDem;
    }
    public void setSourceDem(String sourceDem) {
        this.sourceDem = sourceDem;
    }
    public String getSourceLanduse() {
        return sourceLanduse;
    }
    public void setSourceLanduse(String sourceLanduse) {
        this.sourceLanduse = sourceLanduse;
    }
    public String getLanduseFile() {
        return landuseFile;
    }
    public void setLanduseFile(String landuseFile) {
        this.landuseFile = landuseFile;
    }
}
src/main/java/com/se/nsl/controller/TestController.java
@@ -336,12 +336,16 @@
        resolveService.createRainfallFile(simu, data);
        resolveService.callUwSolver(data);*/
        SimuData data = new SimuData();
        /*SimuData data = new SimuData();
        data.setStartTime(new Date(1748747454000L));
        data.setInPath("20250515143948");
        data.setOutPath(data.getInPath());
        data.setEpsg(4548);
        testService.test(data);
        testService.test(data);*/
        Simu simu = simuService.selectById(17);
        SimuData data = JSON.parseObject(simu.getData(), SimuData.class);
        resolveService.initArgs(simu, data);
        return (Object) System.currentTimeMillis();
    }
src/main/java/com/se/nsl/domain/vo/ConfigVo.java
@@ -50,9 +50,9 @@
    public ConfigVo(String terrain, String landuse, String station, String raingage, String saveName, int duration, int frames) {
        this();
        //this.terrain.set(0, terrain.replace("\\", "/")); // 地形高程数据
        //this.landuse.set(0, landuse.replace("\\", "/")); // 土地利用类型
        //this.station.set(0, station.replace("\\", "/")); // 雨量站索引
        this.terrain.set(0, terrain.replace("\\", "/")); // 地形高程数据
        this.landuse.set(0, landuse.replace("\\", "/")); // 土地利用类型
        this.station.set(0, station.replace("\\", "/")); // 雨量站索引
        this.raingage = raingage.replace("\\", "/");
        this.duration = duration;
src/main/java/com/se/nsl/helper/ComHelper.java
@@ -2,10 +2,7 @@
import com.se.nsl.domain.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.WarpOptions;
import org.gdal.gdal.gdal;
import org.gdal.gdal.*;
import org.gdal.gdalconst.gdalconst;
import org.gdal.ogr.Geometry;
import org.gdal.ogr.ogr;
@@ -70,6 +67,37 @@
        destDs.delete();
    }
    public static void Resample(Dataset ds, Integer targetEpsg, String dest, Double destNoData, String wkt, Integer width, Integer height) {
        Vector<String> vector = new Vector<>();
        if (targetEpsg != null) {
            //vector.add("-s_srs");
            //vector.add("EPSG:" + 4548);
            vector.add("-t_srs");
            vector.add("EPSG:" + targetEpsg);
        }
        //if (destNoData != null) {
        //    vector.add("-dstnodata");
        //    vector.add("" + destNoData);
        //}
        if (wkt != null) {
            vector.add("-cutline");
            vector.add(wkt);
            vector.add("-crop_to_cutline");
        }
        if (width != null && height != null) {
            vector.add("-ts");
            vector.add("" + width);
            vector.add("" + height);
        }
        vector.add("-r");
        vector.add("bilinear"); // 双线性插值
        vector.add("-of");
        vector.add("GTiff");
        Dataset destDs = gdal.Warp(dest, new Dataset[]{ds}, new WarpOptions(vector));
        if (null != destDs) destDs.delete();
    }
    public static void Resample2(Dataset ds, String dest, int width, int height, LayerDto layer) {
        Vector<String> vector = new Vector<>();
        vector.add("-s_srs");
src/main/java/com/se/nsl/service/ResolveService.java
@@ -11,12 +11,19 @@
import com.se.nsl.domain.po.SimuData;
import com.se.nsl.domain.vo.ConfigVo;
import com.se.nsl.helper.ComHelper;
import com.se.nsl.helper.GdalHelper;
import com.se.nsl.helper.StringHelper;
import com.se.nsl.helper.WebHelper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;
import org.gdal.ogr.Geometry;
import org.gdal.ogr.ogr;
import org.gdal.osr.CoordinateTransformation;
import org.gdal.osr.SpatialReference;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@@ -108,7 +115,7 @@
            SimuData data = JSONUtil.toBean(simu.getData(), SimuData.class);
            update(simu, 1, "初始化参数");
            initArgs(data);
            initArgs(simu, data);
            createRainfallFile(simu, data);
            update(simu, 2, "调用求解器");
@@ -138,18 +145,60 @@
    /**
     * 初始化参数
     */
    public void initArgs(SimuData data) throws IOException {
    public void initArgs(Simu simu, SimuData data) throws IOException {
        String inPath = config.getInPath() + File.separator + data.getInPath();
        createDir(inPath);
        createDir(inPath + File.separator + "depth");
        createDir(inPath + File.separator + "velocity");
        createDir(config.getOutPath() + File.separator + data.getOutPath());
        // 临时复制高程tif,以后需要自行切割
        File uwBat = new File(config.getUwSolverBat());
        String sourceTif = uwBat.getParent() + File.separator + "case1" + File.separator + "LiuLiMiaoZhen_5m_f32.tif";
        String targetTif = inPath + File.separator + config.getDemFile();
        Files.copy(Paths.get(sourceTif), Paths.get(targetTif), StandardCopyOption.REPLACE_EXISTING);
        Geometry geom = Geometry.CreateFromWkt(simu.getGeom());
        if (geom.GetGeometryType() == ogr.wkbMultiPolygon) geom = geom.GetGeometryRef(0);
        SpatialReference dstSR = GdalHelper.createSpatialReference(config.getEpsg());
        CoordinateTransformation ct = CoordinateTransformation.CreateCoordinateTransformation(GdalHelper.SR4326, dstSR);
        geom.Transform(ct);
        String wkt = geom.ExportToWkt();
        String terrainFile = inPath + File.separator + config.getTerrainFile();
        Dataset dsDem = gdal.Open(config.getSourceDem(), gdalconstConstants.GA_ReadOnly);
        ComHelper.Resample(dsDem, null, terrainFile, null, wkt, null, null);
        dsDem.delete();
        String landuseFile = inPath + File.separator + config.getLanduseFile();
        Dataset dsLanduse = gdal.Open(config.getSourceLanduse(), gdalconstConstants.GA_ReadOnly);
        ComHelper.Resample(dsLanduse, null, landuseFile, null, wkt, null, null);
        dsLanduse.delete();
    }
    public void updateTif(Simu simu, SimuData data2) throws IOException {
        Dataset ds = gdal.Open(config.getSourceLanduse(), gdalconstConstants.GA_Update); // 以读写模式打开TIFF文件
        Band band = ds.GetRasterBand(1);
        if (band.GetRasterDataType() != gdalconstConstants.GDT_Byte) {
            System.err.println("错误:非Byte类型数据");
            ds.delete();
            return;
        }
        int width = band.getXSize();
        int height = band.getYSize();
        // 读取Byte类型数据
        byte[] data = new byte[width * height];
        band.ReadRaster(0, 0, width, height, data);
        // 替换0值为8(注意Java的byte是有符号的,需处理0-255范围)
        for (int i = 0; i < data.length; i++) {
            if ((data[i] & 0xFF) == 0) {  // 无符号比较
                data[i] = (byte) 8;
            }
        }
        band.WriteRaster(0, 0, width, height, data); // 写回数据并保存
        band.SetNoDataValue(8.0);  // 设置新Nodata值
        band.FlushCache(); // 强制写入更改
        ds.delete();
    }
    private void createDir(String path) {
@@ -228,10 +277,11 @@
        }
        String inPath = config.getInPath() + File.separator + data.getInPath();
        String terrainFile = (inPath + File.separator + config.getDemFile());
        String terrainFile = inPath + File.separator + config.getTerrainFile();
        String landuseFile = inPath + File.separator + config.getLanduseFile();
        String rainfallFile = (inPath + File.separator + "rainfall.dat");
        String saveName = inPath + File.separator + "result.zarr";
        ConfigVo vo = new ConfigVo(terrainFile, terrainFile, terrainFile, rainfallFile, saveName, duration, config.getSaveFrames());
        ConfigVo vo = new ConfigVo(terrainFile, landuseFile, terrainFile, rainfallFile, saveName, duration, config.getSaveFrames());
        String configFile = config.getInPath() + File.separator + data.getInPath() + File.separator + data.getInPath() + ".json";
        ComHelper.writeJson(configFile, JSON.toJSONString(vo));
@@ -248,7 +298,7 @@
        String inPath = config.getInPath() + File.separator + data.getInPath();
        String zarrFile = inPath + File.separator + "result.zarr";
        String geotiffDir = inPath + File.separator + "depth";
        String terrainFile = inPath + File.separator + config.getDemFile();
        String terrainFile = inPath + File.separator + config.getTerrainFile();
        String jsonPath = inPath + File.separator + "zarr2tif.json";
        Zarr2Tif zarr2Tif = new Zarr2Tif(zarrFile, geotiffDir, terrainFile, data.getStartTime());
@@ -289,7 +339,7 @@
        File uwBat = new File(config.getUwSolverBat());
        String zarrFile = uwBat.getParent() + File.separator + "result.zarr";
        String inPath = config.getInPath() + File.separator + data.getInPath();
        String terrainFile = inPath + File.separator + config.getDemFile();
        String terrainFile = inPath + File.separator + config.getTerrainFile();
        String waterPath = inPath + File.separator + "depth";
        String cmd = String.format("%s \"%s\" \"%s\" \"%s\" \"%s\"", config.getZarr2tifBat(), "depth", zarrFile, terrainFile, waterPath);
src/main/resources/application-prod.yml
@@ -150,7 +150,7 @@
  rainfallTitle: Station Longitude Latitude Year Month Day Hour Minute Intensity
  rainfallSite: beijing
  epsg: 4548
  saveFrames: 6
  saveFrames: 3
  # 土地利用:1-Cropland,2-Forest,3-Shrub,4-Grassland,5-Water,6-Snow/Ice,7-Barren,8-Impervious,9-Wetland
  landuse: 2
  #sizes: 64,128,256,512,1024,2048,4096
@@ -162,5 +162,8 @@
  buildingKey: KJSFBM
  waterPath: depth
  flowPath: velocity
  landuseFile: Landuse.tif
  sourceDem: D:\other\simu\CudaUWSolver-2.0\Beijing-Data-10m\Beijing-4548-ASTERDEMV3-10m.tif
  sourceLanduse: D:\other\simu\CudaUWSolver-2.0\Beijing-Data-10m\Beijing-4548-Landuse-10m-Nonodata.tif
  copyTif: false
  tifPath: D:\other\simu\uwsolver\5ca43c87cd8e48c5a9c5399a5da46dbc\tongzhou_raster_4548_1m_clip_river_fill.tif