wangyifei
2024-10-31 794f620632fca78834677d6b0890bfa0fe78eb02
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package com.se.simu.service;
 
import com.se.simu.config.PropertiesConfig;
import com.se.simu.domain.vo.*;
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.osr.SpatialReference;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
/**
 * 内涝服务类
 *
 * @author WWW
 * @date   2024-07-16
 */
@Slf4j
@Service
public class WaterService {
    @Resource
    PropertiesConfig config;
 
    /**
     * 获取元数据信息
     */
    public byte[] getLayerJson(String serviceName) {
        try {
            String filePath = config.getOutPath() + File.separator + serviceName + File.separator + "layer.json";
 
            File dat = new File(filePath);
            if (!dat.exists()) {
                return null;
            }
 
            byte[] bytes = new byte[(int) dat.length()];
 
            FileInputStream fs = new FileInputStream(filePath);
            fs.read(bytes);
            fs.close();
 
            return bytes;
        } catch (Exception ex) {
            return null;
        }
    }
 
    /**
     * 获取地形高度图
     */
    public String getTerraMap(String serviceName, Integer width, Integer height) {
        return config.getOutPath() + File.separator + serviceName + File.separator + "terrain" + File.separator + width + "_" + height + ".png";
    }
 
    /**
     * 获取水面高度图
     */
    public String getWaterMap(String serviceName, Integer width, Integer height, Long timestamp) {
        return config.getOutPath() + File.separator + serviceName + File.separator + "waters" + File.separator + timestamp + File.separator + width + "_" + height + ".png";
    }
 
    /**
     * 获取水流向流速图
     */
    public String getFlowMap(String serviceName, Integer width, Integer height, Long timestamp) {
        return config.getOutPath() + File.separator + serviceName + File.separator + "flows" + File.separator + timestamp + File.separator + width + "_" + height + ".png";
    }
 
    /**
     * 获取图层 *
     */
    public Layer getLayer(String serviceName) {
        Layer layer = new Layer();
        layer.setVersion(config.getVer());
        layer.setDuration(new Duration(1719812810225L, 1719812810225L));
        layer.setExtension(new Extension(2.11062743358, 0.53812160220, 2.11070827834, 0.53819799453, 1.151, 38.83));
 
        List<Integer[]> sizes = new ArrayList<>();
        sizes.add(new Integer[]{64, 64});
        sizes.add(new Integer[]{128, 128});
        sizes.add(new Integer[]{256, 256});
        sizes.add(new Integer[]{512, 512});
        sizes.add(new Integer[]{1024, 1024});
        sizes.add(new Integer[]{2048, 2048});
        layer.setTerrain(new Terrain(sizes));
 
        List<Long> data = new ArrayList<>(Arrays.asList(1719812812225L, 1719812812225L, 1719812812225L, 1719812812225L, 1719812812225L, 1719812812225L));
        layer.setWaters(new Water(data));
 
        return layer;
    }
 
    /**
     * 获取降水曲线文件曲线图
     */
    public byte[] getRainfall(String serviceName) {
        try {
            String filePath = config.getOutPath() + File.separator + serviceName + File.separator + "rainfall.json";
 
            File rainfall = new File(filePath);
            if (!rainfall.exists()) {
                return null;
            }
 
            byte[] bytes = new byte[(int) rainfall.length()];
 
            FileInputStream fs = new FileInputStream(filePath);
            fs.read(bytes);
            fs.close();
 
            return bytes;
        } catch (Exception ex) {
            return null;
        }
    }
 
    /**
     * 根据坐标查询积水深度
     */
    public Double getWaterHeight(String serviceName, Double x, Double y, Long timestamp) {
        String filePath = config.getOutPath() + File.separator + serviceName + File.separator + "waters"
                + File.separator + timestamp + File.separator + "water.tif";
 
        // 首先是所有gdal程序都需要的注册语句
        gdal.AllRegister();
        // 读取影像
        Dataset hDataset = gdal.Open(filePath, gdalconstConstants.GA_Update);
 
        // 设置数据集的投影
        SpatialReference srs = new SpatialReference();
        srs.ImportFromEPSG(4548);
        hDataset.SetProjection(srs.ExportToWkt());
 
        //获取栅格数量
        int numBands=hDataset.GetRasterCount();
        System.out.println("RasterCount: " + numBands);
        //构造仿射变换参数数组,并获取数据
        double[] gt = new double[6];
        hDataset.GetGeoTransform(gt);
        System.out.println("仿射变换参数"+ Arrays.toString(gt));
 
        //经纬度转换为栅格像素坐标
        int[] ColRow=Coordinates2ColRow(gt,x,y);
 
        //判断是否坐标超出范围
        if(ColRow[0]<0||ColRow[1]<0||ColRow[0]>hDataset.getRasterXSize()||ColRow[1]>hDataset.getRasterYSize()){
            System.out.println(Arrays.toString(ColRow)+"坐标值超出栅格范围!");
            return null;
        }
 
        //获取该点对应的波段的值
        Band band = hDataset.GetRasterBand(1);
        double[] values = new double[1];
        band.ReadRaster(ColRow[0], ColRow[1], 1, 1, values);
        double value = values[0];
 
        //释放资源
        hDataset.delete();
        return value;
    }
 
    /**
     * 将地图坐标转换为栅格像素坐标
     * @param gt 仿射变换参数
     * @param X 横坐标
     * @param Y 纵坐标
     * @return
     */
    public int[] Coordinates2ColRow(double[] gt, double X, double Y){
        int[] ints = new int[2];
        //向下取整,如果向上取整会导致计算结果偏大,从而在后面读取到邻近像元的数据
        double  Yline = Math.floor(((Y - gt[3])*gt[1] - (X-gt[0])*gt[4]) / (gt[5]*gt[1]-gt[2]*gt[4]));
        double  Xpixel = Math.floor((X-gt[0] - Yline*gt[2])/gt[1]);
        ints[0] = new Double(Xpixel).intValue();
        ints[1] = new Double(Yline).intValue();
        return ints;
    }
}