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.FileHelper; 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.servlet.http.HttpServletResponse; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * 栅格分析服务 * @author WWW * @date 2023-11-16 */ @Service public class SlopeAnalysisService { @Value("${sys.path.slopFile}") private String filePath; private String xlsTemplate; private final static Log log = LogFactory.getLog(SlopeAnalysisService.class); /** * 获取Excel模板 */ private String getXlsTemplate() { if (null == xlsTemplate) { xlsTemplate = FileHelper.getClassPath() + File.separator + "config" + File.separator + "slop.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 list = analysisPolygon(polygon, ds); if (null == list || list.isEmpty()) { throw new Exception("分析结果为空(查询范围无效)"); } // } finally { if (null != ds) { ds.delete(); } } } /** * 分析多边形 */ public List 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 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.GetY(), point.GetX(), values[0])); } } } return list; } }