月球大数据地理空间分析展示平台-【后端】-月球后台服务
13693261870
2023-09-11 64208929b109627e5563ddceecca17551998c4d3
修改栅格分析的点、线分析功能
已修改2个文件
254 ■■■■ 文件已修改
src/main/java/com/moon/server/entity/data/AnalysisResultEntity.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/moon/server/service/data/RasterAnalysisService.java 253 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/moon/server/entity/data/AnalysisResultEntity.java
@@ -11,6 +11,7 @@
    private static final long serialVersionUID = -1237623414044281355L;
    public AnalysisResultEntity() {
        code = 200;
    }
    private String layerName;
src/main/java/com/moon/server/service/data/RasterAnalysisService.java
@@ -17,9 +17,7 @@
import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.*;
/**
 * 栅格分析服务
@@ -102,21 +100,20 @@
            // double rotationX = transform[2]; double rotationY = transform[4]
            double minX = transform[0], pixelWidth = transform[1], maxY = transform[3], pixelHeight = transform[5];
            int bandCount = ds.getRasterCount();
            int xPixel = (int) Math.floor((x - minX) / pixelWidth);
            int yPixel = (int) Math.floor((maxY - y) / Math.abs(pixelHeight));
            int bandCount = ds.getRasterCount();
            List<double[]> sum = new ArrayList<>();
            for (int bandIndex = 1; bandIndex <= bandCount; bandIndex++) {
            List<double[]> list = new ArrayList<>();
            for (int i = 1; i <= bandCount; i++) {
                double[] pixelValues = new double[size * size];
                Band band = ds.GetRasterBand(bandIndex);
                Band band = ds.GetRasterBand(i);
                band.ReadRaster(xPixel, yPixel, size, size, pixelValues);
                sum.add(pixelValues);
                list.add(pixelValues);
            }
            //return average(calculateAverage(sum));
            processResult(entity, list);
        } catch (Exception ex) {
            setError(entity, ex.getMessage());
            log.error(ex.getMessage(), ex);
@@ -129,13 +126,130 @@
    }
    /**
     * 处理结果
     */
    private void processResult(AnalysisResultEntity entity, List<double[]> list) {
        if (null == list || list.isEmpty()) {
            return;
        }
        List<Double> rs = new ArrayList<>();
        for (double[] ds : list) {
            if (null != ds && ds.length > 0) {
                for (double d : ds) {
                    rs.add(d);
                }
            }
        }
        processResult(rs, entity);
    }
    /**
     * 处理结果
     */
    private void processResult(List<Double> rs, AnalysisResultEntity entity) {
        double min = Collections.min(rs);
        double max = Collections.max(rs);
        double avg = rs.stream().mapToDouble(Double::valueOf).average().getAsDouble();
        entity.setMin(min);
        entity.setMax(max);
        entity.setAvg(avg);
    }
    /**
     * 分析线
     */
    public List<AnalysisResultEntity> analysisPolyline(Geometry polyline) {
        List<AnalysisResultEntity> rs = new ArrayList<>();
        //
        List<PublishEntity> pubs = publishService.selectRaster();
        if (null == pubs || pubs.isEmpty()) {
            return rs;
        }
        for (PublishEntity pub : pubs) {
            AnalysisResultEntity entity = new AnalysisResultEntity();
            entity.setLayerName(pub.getName());
            processPolyline(entity, pub, polyline);
            rs.add(entity);
        }
        return rs;
    }
    /**
     * 处理线
     */
    private void processPolyline(AnalysisResultEntity entity, PublishEntity pub, Geometry polyline) {
        List<MetaEntity> metas = publishService.selectMetasByPubid(pub.getId());
        if (null == metas || metas.isEmpty()) {
            setError(entity, "找不到发布数据");
            return;
        }
        String filePath = pathHelper.getConfig().getUploadPath() + File.separator + metas.get(0).getPath();
        File file = new File(filePath);
        if (!file.exists() || file.isDirectory()) {
            setError(entity, "源数据不存在");
            return;
        }
        processPolyline(entity, filePath, polyline);
    }
    /**
     * 处理线
     */
    public void processPolyline(AnalysisResultEntity entity, String filePath, Geometry polyline) {
        Dataset ds = null;
        try {
            ds = gdal.Open(filePath);
            if (null == ds) {
                throw new Exception("打开栅格数据失败");
            }
            double[] transform = ds.GetGeoTransform();
            // double rotationX = transform[2]; double rotationY = transform[4]
            double minX = transform[0], pixelWidth = transform[1], maxY = transform[3], pixelHeight = transform[5];
            double[] bounds = new double[6];
            polyline.GetEnvelope(bounds);
            double startX = bounds[0], endX = bounds[1], startY = bounds[2], endY = bounds[3];
            int bandCount = ds.getRasterCount();
            int xStartPixel = (int) Math.floor((startX - minX) / pixelWidth);
            int yStartPixel = (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> list = new ArrayList<>();
            for (int y = Math.min(yStartPixel, yEndPixel); y <= Math.max(yStartPixel, 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 (polyline.Contains(point)) {
                        for (int i = 1; i <= bandCount; i++) {
                            double[] values = new double[1];
                            ds.GetRasterBand(i).ReadRaster(x, y, 1, 1, values);
                            list.add(values[0]);
                        }
                    }
                }
            }
            processResult(list, entity);
        } catch (Exception ex) {
            setError(entity, ex.getMessage());
            log.error(ex.getMessage(), ex);
        } finally {
            //  gdal.GDALDestroyDriverManager()
            if (null != ds) {
                ds.delete();
            }
        }
    }
    /**
@@ -146,52 +260,6 @@
        //
        return rs;
    }
    public List<Double> processLine(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[] 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) {
@@ -236,20 +304,10 @@
            sum.add(pixelValues);
        }
        return average(calculateAverage(sum));
        return 0;
    }
    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) {
    public void processClippedDataByLine(String imagePath, String geometryString) {
        // 注册GDAL驱动
        gdal.AllRegister();
        // 打开栅格图像数据集
@@ -275,11 +333,19 @@
            sum.add(pixelValues);
        }
        return calculateAverage(sum);
    }
    public double processClippedDataByPolygon(String imagePath, String geometryString) {
    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 void processClippedDataByPolygon(String imagePath, String geometryString) {
        // 注册GDAL驱动
        gdal.AllRegister();
        // 打开栅格图像数据集
@@ -304,50 +370,7 @@
            band.ReadRaster(0, 0, width, height, pixelValues);
            // 多波段归一化处理
            bandSum[bandIndex - 1] = average(pixelValues);
        }
        return average(bandSum);
    }
    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);
    }
}