package com.moon.server.service.data;
|
|
import com.moon.server.entity.all.StaticData;
|
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;
|
}
|
}
|