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