13693261870
2024-10-30 495292b588949bcb2cb15eaa9657619aca7f5579
src/main/java/com/se/simu/service/ResultService.java
@@ -23,6 +23,10 @@
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
@@ -39,7 +43,7 @@
    @Resource
    PropertiesConfig config;
    public final static double MAX_X_OFFSET = 0.002;
    public final static double MAX_X_OFFSET = 0;
    public void process(DataPo data) throws Exception {
        String basePath = config.getInPath() + File.separator + data.getInPath() + File.separator;
@@ -61,6 +65,7 @@
            copeWater(dto, layer);
            copeFlow(dto, layer);
            copeLayerJson(dto, layer);
            copeRainFallJson(dto, layer);
        } finally {
            File dir = new File(dto.getTemp());
            if (dir.exists()) {
@@ -76,7 +81,7 @@
        Dataset ds = null;
        try {
            ds = gdal.Open(dto.getTerrainFile(), gdalconst.GA_ReadOnly);
            if (null == ds || 0 == ds.getRasterCount() || null == ds.GetSpatialRef()) return;
            if (null == ds || 0 == ds.getRasterCount()) return;
            setTerrainInfo(ds, layer);
            setWaterInfo(dto, layer);
@@ -124,20 +129,25 @@
        }
    }
    /**
     * 重采样
     */
    private static void Resample(Dataset ds, String dest, int width, int height, LayerDto layer) {
        Vector<String> vector = new Vector<>();
        vector.add("-t_srs");
        vector.add("EPSG:" + 4326);
        //vector.add("-s_srs");
        //vector.add("EPSG:" + 4548);
        //vector.add("-t_srs");
        //vector.add("EPSG:" + 4326);
        vector.add("-ts");
        vector.add("" + width);
        vector.add("" + height);
        vector.add("-te");
        vector.add("" + layer.getExtension().getMinx());
        vector.add("" + layer.getExtension().getMiny());
        vector.add("" + layer.getExtension().getMaxx());
        vector.add("" + layer.getExtension().getMaxy());
        vector.add("-te_srs");
        vector.add("EPSG:" + 4326);
        //vector.add("-te");
        //vector.add("" + layer.getExtension().getMinx());
        //vector.add("" + layer.getExtension().getMiny());
        //vector.add("" + layer.getExtension().getMaxx());
        //vector.add("" + layer.getExtension().getMaxy());
        //vector.add("-te_srs");
        //vector.add("EPSG:" + 4326);
        vector.add("-r");
        vector.add("bilinear");
        vector.add("-of");
@@ -292,10 +302,16 @@
        for (String file : files) {
            String fileName = getNameWithExt(file);
            int hour = Integer.parseInt(fileName.substring(0, 2));
            int minute = Integer.parseInt(fileName.substring(2, 4));
            int second = Integer.parseInt(fileName.substring(4, 6));
            int year = Integer.parseInt(fileName.substring(0, 4));
            int month = Integer.parseInt(fileName.substring(4, 6));
            int day = Integer.parseInt(fileName.substring(6, 8));
            int hour = Integer.parseInt(fileName.substring(8, 10));
            int minute = Integer.parseInt(fileName.substring(10, 12));
            int second = Integer.parseInt(fileName.substring(12, 14));
            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, month);
            calendar.set(Calendar.DAY_OF_MONTH, day);
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            calendar.set(Calendar.MINUTE, minute);
            calendar.set(Calendar.SECOND, second);
@@ -311,7 +327,7 @@
            Dataset ds = null;
            try {
                ds = gdal.Open(file, gdalconst.GA_ReadOnly);
                if (null == ds || 0 == ds.getRasterCount() || null == ds.GetSpatialRef()) return;
                if (null == ds || 0 == ds.getRasterCount()) return;
                double[] mm = new double[2];
                ds.GetRasterBand(1).ComputeRasterMinMax(mm, 0);
@@ -329,7 +345,7 @@
            Dataset ds = null;
            try {
                ds = gdal.Open(files.get(i), gdalconst.GA_ReadOnly);
                if (null == ds || 0 == ds.getRasterCount() || null == ds.GetSpatialRef()) return;
                if (null == ds || 0 == ds.getRasterCount()) return;
                createWaterPng(dto, ds, layer, layer.getWaters().getData().get(i));
            } finally {
@@ -366,9 +382,8 @@
            Band band = ds.GetRasterBand(1);
            float[] buffer = new float[width * height];
            //band.ReadRaster(0, 0, width, height, buffer, width, height, 0, 0);
            band.ReadRaster(0, 0, width, height, buffer);
            float[] building = dto.getBuildings().get(width + "_" + height);
            double[] transform = ds.GetGeoTransform();
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            double differ = layer.getExtension().getMaxHeight() - layer.getExtension().getMinHeight(), minHeight = layer.getExtension().getMinHeight();
@@ -376,7 +391,11 @@
                for (int y = 0; y < height; y++) {
                    int offset = x + y * width;
                    if (Float.isNaN(buffer[offset]) || buffer[offset] < -999 || buffer[offset] < minHeight) continue;
                    if (!Float.isNaN(building[offset]) && building[offset] > -999) continue;
                    double X = transform[0] + x * transform[1] + y * transform[2];
                    double Y = transform[3] + x * transform[4] + y * transform[5];
                    //BuildingDto building = intersects(dto, X, Y);
                    //if (null != building) continue;
                    int r = 0, g, b;
                    if (buffer[offset] - layer.getExtension().getMaxHeight() > 0) {
@@ -397,68 +416,64 @@
        }
    }
    /**
     * 是否相交
     * https://blog.csdn.net/flyingshineangel/article/details/135423025
     */
    private static BuildingDto intersects(ResultDto dto, double x, double y) {
        Geometry p = new Geometry(ogr.wkbPoint);
        p.AddPoint_2D(x, y);
        p.AssignSpatialReference(dto.getBuildingList().get(0).getGeom().GetSpatialReference());
        return dto.getBuildingList().parallelStream().filter(b -> b.getGeom().Intersects(p)).findFirst().orElse(null);
    }
    private void copeFlow(ResultDto dto, LayerDto layer) {
        List<String> vxFiles = new ArrayList<>();
        List<String> vyFiles = new ArrayList<>();
        List<String> files = getFiles(dto.getFlowPath(), ".tif");
        for (String file : files) {
            if (file.contains(File.separator + "vx")) vxFiles.add(file);
            if (file.contains(File.separator + "vy")) vyFiles.add(file);
        }
        if (null == vxFiles || null == vyFiles || vxFiles.size() != vyFiles.size() || vxFiles.size() != layer.getWaters().getData().size())
            return;
        if (null == files || files.size() != layer.getWaters().getData().size()) return;
        for (int i = 0, c = vxFiles.size(); i < c; i++) {
            Dataset vxDs = null, vyDs = null;
        for (int i = 0, c = files.size(); i < c; i++) {
            Dataset ds = null;
            try {
                vxDs = gdal.Open(vxFiles.get(i), gdalconst.GA_ReadOnly);
                vyDs = gdal.Open(vyFiles.get(i), gdalconst.GA_ReadOnly);
                if (null == vxDs || 0 == vxDs.getRasterCount() || null == vxDs.GetSpatialRef() || null == vyDs || 0 == vyDs.getRasterCount() || null == vyDs.GetSpatialRef())
                    return;
                ds = gdal.Open(files.get(i), gdalconst.GA_ReadOnly);
                if (null == ds || 0 == ds.getRasterCount()) return;
                createFlowPng(dto, vxDs, vyDs, layer, layer.getWaters().getData().get(i));
                createFlowPng(dto, ds, layer, layer.getWaters().getData().get(i));
            } finally {
                if (null != vxDs) vxDs.delete();
                if (null != vyDs) vyDs.delete();
                if (null != ds) ds.delete();
            }
        }
    }
    private static void createFlowPng(ResultDto dto, Dataset vxDs, Dataset vyDs, LayerDto layer, long ticks) {
    private static void createFlowPng(ResultDto dto, Dataset ds, LayerDto layer, long ticks) {
        String flowPath = dto.getOutPath() + File.separator + "flows" + File.separator + ticks;
        File dir = new File(flowPath);
        if (!dir.exists() || !dir.isDirectory()) dir.mkdirs();
        for (int[] sizes : layer.getTerrain().getSize()) {
            String vxName = getNameWithExt(vxDs.GetDescription()) + "_" + sizes[0] + "_" + sizes[1];
            String vxTif = dto.getTemp() + File.separator + vxName + ".tif";
            Resample(vxDs, vxTif, sizes[0], sizes[1], layer);
            String vyName = getNameWithExt(vyDs.GetDescription()) + "_" + sizes[0] + "_" + sizes[1];
            String vyTif = dto.getTemp() + File.separator + vyName + ".tif";
            Resample(vyDs, vyTif, sizes[0], sizes[1], layer);
            if (!new File(vxTif).exists() || !new File(vyTif).exists()) continue;
            String name = getNameWithExt(ds.GetDescription()) + "_" + sizes[0] + "_" + sizes[1];
            String tif = dto.getTemp() + File.separator + name + ".tif";
            Resample(ds, tif, sizes[0], sizes[1], layer);
            if (!new File(tif).exists()) continue;
            String png = flowPath + File.separator + sizes[0] + "_" + sizes[1] + ".png";
            vxyTif2Png(layer, vxTif, vyTif, png, sizes[0], sizes[1]);
            vxyTif2Png(layer, tif, png, sizes[0], sizes[1]);
        }
    }
    private static void vxyTif2Png(LayerDto layer, String vxTif, String vyTif, String png, int width, int height) {
        Dataset vxDs = null, vyDs = null;
    private static void vxyTif2Png(LayerDto layer, String tif, String png, int width, int height) {
        Dataset ds = null;
        try {
            vxDs = gdal.Open(vxTif, gdalconst.GA_ReadOnly);
            vyDs = gdal.Open(vyTif, gdalconst.GA_ReadOnly);
            if (null == vxDs || 0 == vxDs.getRasterCount() || null == vyDs || 0 == vyDs.getRasterCount()) return;
            ds = gdal.Open(tif, gdalconst.GA_ReadOnly);
            if (null == ds || 0 == ds.getRasterCount()) return;
            float[] vxBuffer = new float[width * height], vyBuffer = new float[width * height];
            vxDs.GetRasterBand(1).ReadRaster(0, 0, width, height, vxBuffer);
            vyDs.GetRasterBand(1).ReadRaster(0, 0, width, height, vyBuffer);
            ds.GetRasterBand(1).ReadRaster(0, 0, width, height, vxBuffer);
            ds.GetRasterBand(2).ReadRaster(0, 0, width, height, vyBuffer);
            createFlowPng(vxBuffer, vyBuffer, png, width, height);
        } finally {
            if (null != vxDs) vxDs.delete();
            if (null != vyDs) vyDs.delete();
            if (null != ds) ds.delete();
        }
    }
@@ -503,8 +518,10 @@
     */
    private void copeLayerJson(ResultDto dto, LayerDto layer) throws IOException {
        layer.getWaters().setFiles(null);
        //String json = JSONUtil.toJsonPrettyStr(layer);
        layer.getTerrain().setEpsg(null);
        String json = JSON.toJSONString(layer);
        //String json = JSONUtil.toJsonPrettyStr(layer);
        String filePath = dto.getOutPath() + File.separator + "layer.json";
        FileWriter fw = new FileWriter(filePath);
@@ -513,4 +530,37 @@
        bw.close();
        fw.close();
    }
    /**
     * 处理降水曲线文件曲线图
     */
    public void copeRainFallJson(ResultDto dto, LayerDto layer) throws IOException, ParseException {
        String rainGageFilePath = config.getInPath() + File.separator + dto.getServiceName() + File.separator + "RainGage.dat";
        String filePath = dto.getOutPath() + File.separator + "rainfall.json";
        String line;
        Map<String, Double> rainFallJsons = new LinkedHashMap<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        BufferedReader br = new BufferedReader(new FileReader(rainGageFilePath));
        // 处理第一行数据
        if ((line = br.readLine()) != null) {
            while ((line = br.readLine()) != null) {
                // 处理每一行数据
                String[] rainFall = line.split(" ");
                if (rainFall.length < 7) continue;
                String sdt = rainFall[1] + "-" + rainFall[2] + "-" + rainFall[3] + " " + rainFall[4] + ":" + rainFall[5];
                BigDecimal num = new BigDecimal(rainFall[6]);
                rainFallJsons.put("" + sdf.parse(sdt).getTime(), num.setScale(2, RoundingMode.HALF_UP).doubleValue());
            }
        }
        FileWriter fw = new FileWriter(filePath);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(JSON.toJSONString(rainFallJsons));
        bw.close();
        fw.close();
    }
}