月球大数据地理空间分析展示平台-【后端】-月球后台服务
13693261870
2023-09-10 1052cd1f5ea5d3e9fad2c332e5bd8fba4af6710c
合并刘浩然的代码~
已添加2个文件
已修改1个文件
380 ■■■■■ 文件已修改
src/main/java/com/moon/server/controller/data/RasterAnalysisController.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/moon/server/entity/data/ImageEntity.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/moon/server/service/data/RasterAnalysisService.java 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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) {
        // è¾“入的几何Geometry: 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({
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;
    }
}
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);
    }
}