月球大数据地理空间分析展示平台-【后端】-月球后台服务
13693261870
2023-09-11 e6a222fea235eb4ebb3fc47d95c61a07a2db5e15
修改栅格分析的面方法
已修改2个文件
339 ■■■■■ 文件已修改
src/main/java/com/moon/server/controller/data/RasterAnalysisController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/moon/server/service/data/RasterAnalysisService.java 333 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/moon/server/controller/data/RasterAnalysisController.java
@@ -53,7 +53,7 @@
                return fail("像点值只能为:" + StringHelper.join(PIXELS, ", "));
            }
            List<?> rs = rasterService.analysisPoint(geo, pixel);
            List<?> rs = rasterService.analysis(geo, pixel);
            return success(rs.size(), rs);
        } catch (Exception ex) {
@@ -77,7 +77,7 @@
                return fail("WKT字符串不正确");
            }
            List<?> rs = rasterService.analysisPolyline(geo);
            List<?> rs = rasterService.analysis(geo, 0);
            return success(rs.size(), rs);
        } catch (Exception ex) {
@@ -101,7 +101,7 @@
                return fail("WKT字符串不正确");
            }
            List<?> rs = rasterService.analysisPolygon(geo);
            List<?> rs = rasterService.analysis(geo, 0);
            return success(rs.size(), rs);
        } catch (Exception ex) {
src/main/java/com/moon/server/service/data/RasterAnalysisService.java
@@ -35,9 +35,9 @@
    private final static Log log = LogFactory.getLog(RasterAnalysisService.class);
    /**
     * 分析点
     * 分析方法
     */
    public List<AnalysisResultEntity> analysisPoint(Geometry point, int size) {
    public List<AnalysisResultEntity> analysis(Geometry geo, Integer size) {
        List<AnalysisResultEntity> rs = new ArrayList<>();
        List<PublishEntity> pubs = publishService.selectRaster();
@@ -49,7 +49,20 @@
            AnalysisResultEntity entity = new AnalysisResultEntity();
            entity.setLayerName(pub.getName());
            processPoint(entity, pub, point, size);
            List<MetaEntity> metas = publishService.selectMetasByPubid(pub.getId());
            if (null == metas || metas.isEmpty()) {
                setError(entity, "找不到发布数据");
                continue;
            }
            String filePath = pathHelper.getConfig().getUploadPath() + File.separator + metas.get(0).getPath();
            File file = new File(filePath);
            if (!file.exists() || file.isDirectory()) {
                setError(entity, "源数据不存在");
                continue;
            }
            openRaster(entity, filePath, geo, size);
            rs.add(entity);
        }
@@ -57,37 +70,9 @@
    }
    /**
     * 设置错误
     * 打开栅格数据
     */
    private void setError(AnalysisResultEntity entity, String info) {
        entity.setCode(StaticData.I500);
        entity.setInfo(info);
    }
    /**
     * 处理点
     */
    private void processPoint(AnalysisResultEntity entity, PublishEntity pub, Geometry point, int size) {
        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;
        }
        processPoint(entity, filePath, point, size);
    }
    /**
     * 处理点
     */
    public void processPoint(AnalysisResultEntity entity, String filePath, Geometry point, int size) {
    private void openRaster(AnalysisResultEntity entity, String filePath, Geometry geo, int size) {
        Dataset ds = null;
        try {
            ds = gdal.Open(filePath);
@@ -95,25 +80,16 @@
                throw new Exception("打开栅格数据失败");
            }
            double x = point.GetX(), y = point.GetY();
            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];
            int bandCount = ds.getRasterCount();
            int xPixel = (int) Math.floor((x - minX) / pixelWidth);
            int yPixel = (int) Math.floor((maxY - y) / Math.abs(pixelHeight));
            List<double[]> list = new ArrayList<>();
            for (int i = 1; i <= bandCount; i++) {
                double[] pixelValues = new double[size * size];
                Band band = ds.GetRasterBand(i);
                band.ReadRaster(xPixel, yPixel, size, size, pixelValues);
                list.add(pixelValues);
            switch (geo.GetGeometryType()) {
                case ogr.wkbPoint:
                    analysisPoint(entity, ds, geo, size);
                    break;
                case ogr.wkbLineString:
                    analysisPolyline(entity, ds, geo);
                    break;
                default:
                    analysisPolygon(entity, ds, geo);
            }
            processResult(entity, list);
        } catch (Exception ex) {
            setError(entity, ex.getMessage());
            log.error(ex.getMessage(), ex);
@@ -123,6 +99,106 @@
                ds.delete();
            }
        }
    }
    /**
     * 分析点
     */
    public void analysisPoint(AnalysisResultEntity entity, Dataset ds, Geometry point, int size) {
        double x = point.GetX(), y = point.GetY();
        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];
        int bandCount = ds.getRasterCount();
        int xPixel = (int) Math.floor((x - minX) / pixelWidth);
        int yPixel = (int) Math.floor((maxY - y) / Math.abs(pixelHeight));
        List<double[]> list = new ArrayList<>();
        for (int i = 1; i <= bandCount; i++) {
            double[] pixelValues = new double[size * size];
            Band band = ds.GetRasterBand(i);
            band.ReadRaster(xPixel, yPixel, size, size, pixelValues);
            list.add(pixelValues);
        }
        processResult(entity, list);
    }
    /**
     * 分析线
     */
    public void analysisPolyline(AnalysisResultEntity entity, Dataset ds, Geometry polyline) {
        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);
    }
    /**
     * 分析面
     */
    public void analysisPolygon(AnalysisResultEntity entity, Dataset ds, Geometry polygon) {
        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[] env = new double[6];
        polygon.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.floor((env[1] - minX) / pixelWidth);
        int yMaxPixel = (int) Math.floor((maxY - env[2]) / Math.abs(pixelHeight));
        int bandCount = ds.getRasterCount();
        int geoWidth = Math.abs(xMaxPixel - xMinPixel);
        int geoHeight = Math.abs(yMaxPixel - yMinPixel);
        List<double[]> list = new ArrayList<>();
        for (int i = 1; i <= bandCount; i++) {
            Band band = ds.GetRasterBand(i);
            double[] pixelValues = new double[geoWidth * geoHeight];
            band.ReadRaster(xMinPixel, yMinPixel, geoWidth, geoHeight, pixelValues);
            list.add(pixelValues);
        }
        processResult(entity, list);
    }
    /**
     * 设置错误
     */
    private void setError(AnalysisResultEntity entity, String info) {
        entity.setCode(StaticData.I500);
        entity.setInfo(info);
    }
    /**
@@ -149,162 +225,11 @@
     * 处理结果
     */
    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.setMin(Collections.min(rs));
        entity.setMax(Collections.max(rs));
        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();
            }
        }
    }
    /**
     * 分析面
     */
    public List<AnalysisResultEntity> analysisPolygon(Geometry polygon) {
        List<AnalysisResultEntity> rs = new ArrayList<>();
        //
        return rs;
    }
    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 0;
    }
    public void processClippedDataByLine(String imagePath, String geometryString) {