From 1052cd1f5ea5d3e9fad2c332e5bd8fba4af6710c Mon Sep 17 00:00:00 2001
From: 13693261870 <252740454@qq.com>
Date: 星期日, 10 九月 2023 20:38:43 +0800
Subject: [PATCH] 合并刘浩然的代码~

---
 src/main/java/com/moon/server/service/data/RasterAnalysisService.java       |  267 ++++++++++++++++++++++++++++++++++++++
 src/main/java/com/moon/server/controller/data/RasterAnalysisController.java |   34 ++++
 src/main/java/com/moon/server/entity/data/ImageEntity.java                  |   79 +++++++++++
 3 files changed, 377 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/moon/server/controller/data/RasterAnalysisController.java b/src/main/java/com/moon/server/controller/data/RasterAnalysisController.java
index 18b9d62..58536b7 100644
--- a/src/main/java/com/moon/server/controller/data/RasterAnalysisController.java
+++ b/src/main/java/com/moon/server/controller/data/RasterAnalysisController.java
@@ -3,15 +3,18 @@
 import com.moon.server.annotation.SysLog;
 import com.moon.server.controller.all.BaseController;
 import com.moon.server.entity.all.ResponseMsg;
+import com.moon.server.entity.data.ImageEntity;
 import com.moon.server.helper.WebHelper;
+import com.moon.server.service.data.RasterAnalysisService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.gdal.ogr.Geometry;
+import org.gdal.ogr.ogr;
+import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.util.ArrayList;
@@ -28,6 +31,31 @@
 @RestController
 @RequestMapping("/rasterAnalysis")
 public class RasterAnalysisController extends BaseController {
+    @Resource
+    RasterAnalysisService rasterService;
+
+    @SysLog()
+    @ApiOperation(value = "鏍规嵁geometry鑾峰彇瀵瑰簲鑼冨洿鐨勭伆搴﹀��")
+    @PostMapping
+    public ResponseMsg<Object> rasterAnalysis(@RequestBody List<ImageEntity> images) {
+        // 杈撳叆鐨勫嚑浣旼eometry: POINT (75.772 2.498)
+        String geometryString = images.get(0).getGeometryString();
+        Geometry geometry = Geometry.CreateFromWkt(geometryString);
+
+        for (ImageEntity i : images) {
+            String path = i.getPath();
+            if (geometry.GetGeometryType() == ogr.wkbPoint) {
+                i.setResult(rasterService.processPoint(path, geometryString, i.getPointSize()));
+            } else if (geometry.GetGeometryType() == ogr.wkbLineString) {
+                i.setResult(rasterService.processLine(path, geometryString));
+            } else if (geometry.GetGeometryType() == ogr.wkbPolygon) {
+                i.setResult(rasterService.processPolygon(path, geometryString));
+            }
+        }
+
+        return success(images);
+    }
+
     @SysLog()
     @ApiOperation(value = "鏌ヨ鐐瑰垎鏋�")
     @ApiImplicitParams({
diff --git a/src/main/java/com/moon/server/entity/data/ImageEntity.java b/src/main/java/com/moon/server/entity/data/ImageEntity.java
new file mode 100644
index 0000000..1acae62
--- /dev/null
+++ b/src/main/java/com/moon/server/entity/data/ImageEntity.java
@@ -0,0 +1,79 @@
+package com.moon.server.entity.data;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import java.io.Serializable;
+
+/**
+ * @author LJW
+ * @date 2023-09-07 20:08
+ */
+public class ImageEntity implements Serializable {
+    private static final long serialVersionUID = -3501191218555394360L;
+
+    private String id;
+
+    private String name;
+
+    @JsonIgnore
+    private String path;
+
+    @JsonIgnore
+    private String geometryString;
+
+    @JsonIgnore
+    private int pointSize = 1;
+
+    private Object result;
+
+    public ImageEntity() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getGeometryString() {
+        return geometryString;
+    }
+
+    public void setGeometryString(String geometryString) {
+        this.geometryString = geometryString;
+    }
+
+    public int getPointSize() {
+        return pointSize;
+    }
+
+    public void setPointSize(int pointSize) {
+        this.pointSize = pointSize;
+    }
+
+    public Object getResult() {
+        return result;
+    }
+
+    public void setResult(Object result) {
+        this.result = result;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/moon/server/service/data/RasterAnalysisService.java b/src/main/java/com/moon/server/service/data/RasterAnalysisService.java
new file mode 100644
index 0000000..a84e1ae
--- /dev/null
+++ b/src/main/java/com/moon/server/service/data/RasterAnalysisService.java
@@ -0,0 +1,267 @@
+package com.moon.server.service.data;
+
+import org.gdal.gdal.Band;
+import org.gdal.gdal.Dataset;
+import org.gdal.gdal.WarpOptions;
+import org.gdal.gdal.gdal;
+import org.gdal.ogr.Geometry;
+import org.gdal.ogr.ogr;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * 鏍呮牸鍒嗘瀽鏈嶅姟
+ * @author LJW
+ * @date 2023-9-1 6:16
+ */
+@Service
+public class RasterAnalysisService {
+    public static Dataset clipRaster(Dataset dataset, Geometry geometry) {
+        Vector<String> warpOptions = new Vector<>();
+        warpOptions.add("-crop_to_cutline");
+        warpOptions.add("-cutline");
+        warpOptions.add(geometry.ExportToWkt());
+        warpOptions.add("-dstalpha");
+
+        return gdal.Warp("", new Dataset[]{dataset}, new WarpOptions(warpOptions));
+    }
+
+    public double[] processClippedDataByLine(String imagePath, String geometryString) {
+        // 娉ㄥ唽GDAL椹卞姩
+        gdal.AllRegister();
+        // 鎵撳紑鏍呮牸鍥惧儚鏁版嵁闆�
+        Dataset dataset = gdal.Open(imagePath);
+        if (dataset == null) {
+            throw new RuntimeException("Failed to open raster dataset.");
+        }
+
+        Geometry geometry = Geometry.CreateFromWkt(geometryString);
+
+        Dataset clippedDataset = clipRaster(dataset, geometry);
+
+        int width = clippedDataset.GetRasterXSize();
+        int height = clippedDataset.GetRasterYSize();
+        int bandCount = clippedDataset.getRasterCount();
+
+        List<double[]> sum = new ArrayList<>();
+        for (int bandIndex = 1; bandIndex <= bandCount; bandIndex++) {
+            Band band = clippedDataset.GetRasterBand(bandIndex);
+
+            double[] pixelValues = new double[width * height];
+            band.ReadRaster(0, 0, width, height, pixelValues);
+
+            sum.add(pixelValues);
+        }
+
+        return calculateAverage(sum);
+    }
+
+    public double processClippedDataByPolygon(String imagePath, String geometryString) {
+        // 娉ㄥ唽GDAL椹卞姩
+        gdal.AllRegister();
+        // 鎵撳紑鏍呮牸鍥惧儚鏁版嵁闆�
+        Dataset dataset = gdal.Open(imagePath);
+        if (dataset == null) {
+            throw new RuntimeException("Failed to open raster dataset.");
+        }
+
+        Geometry geometry = Geometry.CreateFromWkt(geometryString);
+
+        Dataset clippedDataset = clipRaster(dataset, geometry);
+
+        int width = clippedDataset.GetRasterXSize();
+        int height = clippedDataset.GetRasterYSize();
+        int bandCount = clippedDataset.getRasterCount();
+
+        double[] bandSum = new double[bandCount];
+        for (int bandIndex = 1; bandIndex <= bandCount; bandIndex++) {
+            Band band = clippedDataset.GetRasterBand(bandIndex);
+
+            double[] pixelValues = new double[width * height];
+            band.ReadRaster(0, 0, width, height, pixelValues);
+
+            // 澶氭尝娈靛綊涓�鍖栧鐞�
+            bandSum[bandIndex - 1] = average(pixelValues);
+        }
+        return average(bandSum);
+    }
+
+    public double processPoint(String imagePath, String geometryString, int size) {
+        // 娉ㄥ唽GDAL椹卞姩
+        gdal.AllRegister();
+        // 鎵撳紑鏍呮牸鍥惧儚鏁版嵁闆�
+        Dataset dataset = gdal.Open(imagePath);
+        if (dataset == null) {
+            throw new RuntimeException("Failed to open raster dataset.");
+        }
+
+        Geometry geometry = Geometry.CreateFromWkt(geometryString);
+
+        double[] geoTransform = dataset.GetGeoTransform();
+        double minX = geoTransform[0];
+        double pixelWidth = geoTransform[1];
+        double rotationX = geoTransform[2];
+        double maxY = geoTransform[3];
+        double rotationY = geoTransform[4];
+        double pixelHeight = geoTransform[5];
+
+        double x = geometry.GetX();
+        double y = geometry.GetY();
+
+        int xPixel = (int) Math.floor((x - minX) / pixelWidth);
+        int yPixel = (int) Math.floor((maxY - y) / Math.abs(pixelHeight));
+
+        int bandCount = dataset.getRasterCount();
+
+        List<double[]> sum = new ArrayList<>();
+        for (int bandIndex = 1; bandIndex <= bandCount; bandIndex++) {
+            double[] pixelValues = new double[size * size];
+            Band band = dataset.GetRasterBand(bandIndex);
+            band.ReadRaster(xPixel, yPixel, size, size, pixelValues);
+
+            sum.add(pixelValues);
+        }
+
+        // 閲婃斁璧勬簮
+        gdal.GDALDestroyDriverManager();
+
+        return average(calculateAverage(sum));
+    }
+
+    public List<Double> processLine(String imagePath, String geometryString) {
+        // 娉ㄥ唽GDAL椹卞姩
+        gdal.AllRegister();
+        // 鎵撳紑鏍呮牸鍥惧儚鏁版嵁闆�
+        Dataset dataset = gdal.Open(imagePath);
+        if (dataset == null) {
+            throw new RuntimeException("Failed to open raster dataset.");
+        }
+
+        Geometry geometry = Geometry.CreateFromWkt(geometryString);
+
+        // 鏍呮牸鍍忕礌鑼冨洿
+        double[] geoTransform = dataset.GetGeoTransform();
+        double minX = geoTransform[0];
+        double pixelWidth = geoTransform[1];
+        double rotationX = geoTransform[2];
+        double maxY = geoTransform[3];
+        double rotationY = geoTransform[4];
+        double pixelHeight = geoTransform[5];
+
+        // geometry鍍忕礌鑼冨洿
+        double[] bounds = new double[6];
+        geometry.GetEnvelope(bounds);
+        double startX = bounds[0];
+        double endX = bounds[1];
+        double startY = bounds[2];
+        double endY = bounds[3];
+
+        int xStartPixel = (int) Math.floor((startX - minX) / pixelWidth);
+        int ySstartPixel = (int) Math.floor((maxY - startY) / Math.abs(pixelHeight));
+        int xEndPixel = (int) Math.floor((endX - minX) / pixelWidth);
+        int yEndPixel = (int) Math.floor((maxY - endY) / Math.abs(pixelHeight));
+
+        List<Double> values = new ArrayList<>();
+        for (int y = Math.min(ySstartPixel, yEndPixel); y <= Math.max(ySstartPixel, yEndPixel); y++) {
+            for (int x = Math.min(xStartPixel, xEndPixel); x <= Math.max(xStartPixel, xEndPixel); x++) {
+                Geometry point = new Geometry(ogr.wkbPoint);
+                point.AddPoint(minX + pixelWidth * x, maxY - pixelHeight * y);
+                if (geometry.Contains(point)) {
+                    values.add(bandValueHandle(dataset, x, y));
+                }
+            }
+        }
+
+        return values;
+    }
+
+    public double processPolygon(String imagePath, String geometryString) {
+        // 鎵撳紑鏍呮牸鍥惧儚鏁版嵁闆�
+        Dataset dataset = gdal.Open(imagePath);
+
+        if (dataset == null) {
+            throw new RuntimeException("Failed to open raster dataset.");
+        }
+
+        Geometry geometry = Geometry.CreateFromWkt(geometryString);
+
+        // 鏍呮牸鍍忕礌鑼冨洿
+        double[] geoTransform = dataset.GetGeoTransform();
+        double minX = geoTransform[0];
+        double pixelWidth = geoTransform[1];
+        double rotationX = geoTransform[2];
+        double maxY = geoTransform[3];
+        double rotationY = geoTransform[4];
+        double pixelHeight = geoTransform[5];
+
+        // geometry鍍忕礌鑼冨洿
+        double[] env = new double[6];
+        geometry.GetEnvelope(env);
+        int xMinPixel = (int) Math.floor((env[0] - minX) / pixelWidth);
+        int yMinPixel = (int) Math.floor((maxY - env[3]) / Math.abs(pixelHeight));
+        int xMaxPixel = (int) Math.ceil((env[1] - minX) / pixelWidth);
+        int yMaxPixel = (int) Math.ceil((maxY - env[2]) / Math.abs(pixelHeight));
+
+        int bandCount = dataset.getRasterCount();
+        int geometryWidth = Math.abs(xMaxPixel - xMinPixel);
+        int geometryHeight = Math.abs(yMaxPixel - yMinPixel);
+
+        List<double[]> sum = new ArrayList<>();
+        for (int bandIndex = 1; bandIndex <= bandCount; bandIndex++) {
+            Band band = dataset.GetRasterBand(bandIndex);
+
+            double[] pixelValues = new double[geometryWidth * geometryHeight];
+            band.ReadRaster(xMinPixel, yMinPixel, geometryWidth, geometryHeight, pixelValues);
+
+            // 澶氭尝娈靛綊涓�鍖栧鐞�
+            sum.add(pixelValues);
+        }
+
+        return average(calculateAverage(sum));
+    }
+
+    public static double average(double[] values) {
+        double sum = 0;
+        for (double value : values) {
+            sum += value;
+        }
+        return sum / values.length;
+    }
+
+    public static double[] calculateAverage(List<double[]> list) {
+        if (list == null || list.isEmpty()) {
+            return new double[0];
+        }
+
+        int arrayLength = list.get(0).length;
+        double[] outArray = new double[arrayLength];
+
+        for (int i = 0; i < arrayLength; i++) {
+            double sum = 0;
+
+            for (double[] array : list) {
+                sum += array[i];
+            }
+
+            outArray[i] = sum / list.size();
+        }
+
+        return outArray;
+    }
+
+    public static double bandValueHandle(Dataset dataset, int x, int y) {
+        double[] bandSum = new double[dataset.getRasterCount()];
+        for (int bandIndex = 1; bandIndex <= dataset.getRasterCount(); bandIndex++) {
+            double[] pixelValues = new double[1];
+            Band band = dataset.GetRasterBand(bandIndex);
+            band.ReadRaster(x, y, 1, 1, pixelValues);
+
+            bandSum[bandIndex - 1] = pixelValues[0];
+        }
+
+        return average(bandSum);
+    }
+}

--
Gitblit v1.9.3