dcb
2025-07-09 e53252b99e7b49b435b7a6ee3eab21ae1bd7a055
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package com.se.nsl.utils;
 
import com.se.nsl.domain.vo.SimuResult;
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 java.io.File;
 
//求解器产生的tif文件处理工具
@Slf4j
public class SolverTifUtil {
 
    private SolverTifUtil() {}
 
    private static final String YYYY_MM_DD_HH_MM_SS = "yyyyMMddHHmmss";
 
    private static class ColumnRow {
        public final Dataset dataset;
        public final int col;
        public final int row;
 
        public ColumnRow(Dataset dataset, int col, int row) {
            this.dataset = dataset;
            this.col = col;
            this.row = row;
        }
    }
 
    public static SimuResult getSimuResult(File tifFile, double[] position) {
        double x = position[0];
        double y = position[1];
        ColumnRow cr = getColumnRow(tifFile, x, y);
        if (cr == null) return null;
        float depth = readPixelValue(cr.dataset, cr.col, cr.row, 1);
        float velocity = calcVelocity(cr.dataset, cr.col, cr.row);
        SimuResult result = new SimuResult();
        result.setDepth(depth);
        result.setVelocity(velocity);
        String time = tifFile.getName().replace(".tif", "");
        result.setTime(TimeFormatUtil.toMillis(time, YYYY_MM_DD_HH_MM_SS));
        return result;
    }
 
    public static float getDepth(File tifFile, double[] position) {
        double x = position[0];
        double y = position[1];
        ColumnRow cr = getColumnRow(tifFile, x, y);
        if (cr == null) return 0;
        return readPixelValue(cr.dataset, cr.col, cr.row, 1);
    }
 
    public static float getValue(File tifFile, double[] position, int band) {
        double x = position[0];
        double y = position[1];
        ColumnRow cr = getColumnRow(tifFile, x, y);
        if (cr == null) return 0;
        return readPixelValue(cr.dataset, cr.col, cr.row, band);
    }
 
    public static ColumnRow getColumnRow(File tifFile, double x, double y) {
        Dataset dataset = gdal.Open(tifFile.getAbsolutePath(), gdalconstConstants.GA_ReadOnly);
        // 获取地理变换参数(6元素数组)
        // [0]: 左上角X坐标, [1]: 像元宽度, [2]: X方向旋转,
        // [3]: 左上角Y坐标, [4]: Y方向旋转, [5]: 像元高度(负值表示Y轴向下)
        double[] geoTransform = dataset.GetGeoTransform();
        //计算栅格行列号
        int col = (int) ((x - geoTransform[0]) / geoTransform[1]);
        int row = (int) ((geoTransform[3] - y) / Math.abs(geoTransform[5]));
        int width = dataset.getRasterXSize();
        int height = dataset.getRasterYSize();
        if (col < 0 || col > width || row < 0 || row > height) {
            log.warn("行列号不在tif范围内");
            return null;
        }
        return new ColumnRow(dataset, col, row);
    }
 
    private static float calcVelocity(Dataset dataset, int col, int row) {
        float x = readPixelValue(dataset, col, row, 2);
        float y = readPixelValue(dataset, col, row, 3);
        float velocity;
        if (Float.isNaN(x) && Float.isNaN(y)) {
            velocity = 0f;
        } else if (Float.isNaN(x)) {
            velocity = y;
        } else if (Float.isNaN(y)) {
            velocity = x;
        } else {
            velocity = (float) Math.sqrt(x * x + y * y);
        }
        return velocity;
    }
 
    private static float readPixelValue(Dataset dataset, int col, int row, int bandNum) {
        Band band = dataset.GetRasterBand(bandNum);
        float[] values = new float[1];
        band.ReadRaster(col, row, 1, 1, values);
        return values[0];
    }
 
}