月球大数据地理空间分析展示平台-【后端】-月球后台服务
13693261870
2023-11-16 906e2586e2e6e95830f93b50f8c5233189007715
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
package com.moon.server.service.data;
 
import com.moon.server.entity.all.StaticData;
import com.moon.server.entity.ctrl.CountEntity;
import com.moon.server.entity.data.PointEntity;
import com.moon.server.helper.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.gdal;
import org.gdal.ogr.Geometry;
import org.gdal.ogr.ogr;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;
 
/**
 * 栅格分析服务
 * @author WWW
 * @date 2023-11-16
 */
@Service
public class SlopeAnalysisService {
    @Value("${sys.path.slopFile}")
    private String filePath;
 
    @Resource
    protected PathHelper pathHelper;
 
    private String xlsTemplate;
 
    private final static Log log = LogFactory.getLog(SlopeAnalysisService.class);
 
    /**
     * 获取Excel模板
     */
    private String getXlsTemplate() {
        if (null == xlsTemplate) {
            xlsTemplate = FileHelper.getClassPath() + "config/slope.xlsx";
        }
 
        return xlsTemplate;
    }
 
    /**
     * 下载坡度分析Excel
     */
    public void downloadSlopXls(Geometry polygon, HttpServletResponse res) throws Exception {
        Dataset ds = null;
        try {
            ds = gdal.Open(filePath);
            if (null == ds) {
                throw new Exception("打开栅格数据失败");
            }
 
            List<PointEntity> list = analysisPolygon(polygon, ds);
            if (null == list || list.isEmpty()) {
                throw new Exception("分析结果为空(查询范围无效)");
            }
 
            String xlsFile = createXls(list, getXlsTemplate());
            if (null == xlsFile || !new File(xlsFile).exists()) {
                throw new Exception("创建坡度分析Excel失败");
            }
 
            String fileName = FileHelper.getFileName(xlsFile);
            WebHelper.download(xlsFile, fileName, res);
        } finally {
            if (null != ds) {
                ds.delete();
            }
        }
    }
 
    /**
     * 分析多边形
     */
    public List<PointEntity> analysisPolygon(Geometry geo, Dataset ds) {
        double[] transform = ds.GetGeoTransform();
        int xSize = ds.getRasterXSize(), ySize = ds.getRasterYSize();
        double minX = transform[0], pixelWidth = transform[1], maxY = transform[3], pixelHeight = Math.abs(transform[5]);
        double[] env = new double[4];
        geo.GetEnvelope(env);
 
        int xMinPixel = Math.max((int) Math.floor((env[0] - minX) / pixelWidth), 1);
        int yMinPixel = Math.max((int) Math.floor((maxY - env[3]) / pixelHeight), 1);
        int xMaxPixel = Math.min((int) Math.floor((env[1] - minX) / pixelWidth), xSize);
        int yMaxPixel = Math.min((int) Math.floor((maxY - env[2]) / pixelHeight), ySize);
        if (xMaxPixel < 1 || yMaxPixel < 1 || xMaxPixel - xMinPixel < 0 || yMaxPixel - yMinPixel < 0) {
            return null;
        }
 
        double[] values = new double[1];
        List<PointEntity> list = new ArrayList<>();
        for (int y = yMinPixel; y <= yMaxPixel; y++) {
            for (int x = xMinPixel; x <= xMaxPixel; x++) {
                Geometry point = new Geometry(ogr.wkbPoint);
                point.AddPoint(minX + pixelWidth * x, maxY - pixelHeight * y);
                if (!geo.Intersects(point)) {
                    continue;
                }
 
                ds.GetRasterBand(StaticData.I1).ReadRaster(x, y, 1, 1, values);
                if (!Double.isNaN(values[0])) {
                    list.add(new PointEntity(point.GetX(), point.GetY(), values[0]));
                }
            }
        }
 
        return list;
    }
 
    /**
     * 创建Excel
     */
    public String createXls(List<PointEntity> list, String template) {
        String target = pathHelper.getTempPath() + File.separator + "slope_" + StringHelper.YMD2_FORMAT.format(new Date()) + ".xlsx";
 
        Map<String, List<PointEntity>> map = new HashMap<>(1);
        map.put("data", list);
 
        ExcelHelper.writeToTemplate(template, target, map);
 
        return target;
    }
}