From 45a773850057dd90c4292d30715b4f9dfdc86740 Mon Sep 17 00:00:00 2001 From: 13693261870 <252740454@qq.com> Date: 星期一, 04 十二月 2023 13:42:20 +0800 Subject: [PATCH] 屏蔽NoData --- src/main/java/com/moon/server/service/data/RasterAnalysisService.java | 735 ++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 498 insertions(+), 237 deletions(-) diff --git a/src/main/java/com/moon/server/service/data/RasterAnalysisService.java b/src/main/java/com/moon/server/service/data/RasterAnalysisService.java index dad196e..14d2d17 100644 --- a/src/main/java/com/moon/server/service/data/RasterAnalysisService.java +++ b/src/main/java/com/moon/server/service/data/RasterAnalysisService.java @@ -1,25 +1,518 @@ package com.moon.server.service.data; +import com.alibaba.fastjson.JSONObject; +import com.moon.server.entity.all.StaticData; +import com.moon.server.entity.data.AnalysisResultEntity; +import com.moon.server.entity.data.MetaEntity; +import com.moon.server.entity.data.PublishEntity; +import com.moon.server.helper.GeoHelper; +import com.moon.server.helper.PathHelper; +import com.moon.server.helper.StringHelper; +import com.moon.server.helper.WebHelper; +import com.moon.server.service.all.WebSocketService; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; 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.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.List; -import java.util.Vector; +import javax.annotation.Resource; +import java.awt.geom.Point2D; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.*; /** * 鏍呮牸鍒嗘瀽鏈嶅姟 * @author LJW - * @date 2023-9-1 6:16 + * @date 2023-09-01 6:16 */ @Service public class RasterAnalysisService { - public static Dataset clipRaster(Dataset dataset, Geometry geometry) { + @Value("${sys.gdal_path}") + String gdalPath; + + @Resource + PathHelper pathHelper; + + @Resource + PublishService publishService; + + private final static Log log = LogFactory.getLog(RasterAnalysisService.class); + + /** + * 娴嬭瘯 + * <p> + * POINT (26.72 -48.58) + * LINESTRING(18.44 -46.69,20.14 -45.93) + * POLYGON ((5.11 -41.64,7.68 -43.59,4.73 -43.3,5.11 -41.64)) + * POLYGON ((42.6 -40.3,49.1 -40.4,49.1 -65.7,46.3 -65.6,42.6 -40.3)) + */ + public List<AnalysisResultEntity> test(Geometry geo, Integer size) { + List<AnalysisResultEntity> rs = new ArrayList<>(); + AnalysisResultEntity entity = new AnalysisResultEntity(); + entity.setLayerName("Test"); + + openRaster(entity, "D:\\Moon\\data\\DOM\\Lunar_LRO_LOLA_ClrShade_Global_128ppd_v04_2.tif", geo, size); + rs.add(entity); + + return rs; + } + + /** + * 浣跨敤WKT鏌ヨ鍒嗘瀽锛岀粨鏋滀互娑堟伅鎺ㄩ�� + */ + public void analysisForPost(Geometry geo, Integer size, String token) { + List<PublishEntity> pubs = publishService.selectRaster(); + if (null == pubs || pubs.isEmpty()) { + return; + } + + //for (PublishEntity pub : pubs) { + pubs.parallelStream().forEach(pub -> { + try { + AnalysisResultEntity entity = new AnalysisResultEntity(token); + entity.setLayerName(pub.getName()); + entity.setUnit(pub.getUnit()); + + List<MetaEntity> metas = publishService.selectMetasByPubid(pub.getId()); + if (null == metas || metas.isEmpty()) { + setError(entity, "鎵句笉鍒板彂甯冩暟鎹�"); + postInfo(entity); + return; + } + + String filePath = getFilePath(metas); + File file = new File(filePath); + if (!file.exists() || file.isDirectory()) { + setError(entity, "婧愭暟鎹笉瀛樺湪"); + postInfo(entity); + return; + } + + openRaster(entity, filePath, geo, size); + postInfo(entity); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + } + }); + } + + /** + * 鑾峰彇鏂囦欢璺緞 + */ + private String getFilePath(List<MetaEntity> metas) throws IOException { + String basePath = pathHelper.getConfig().getUploadPath() + File.separator; + if (metas.size() == 1) { + return basePath + metas.get(0).getPath(); + } + + String tempPath = pathHelper.getTempPath() + File.separator, guid = StringHelper.getGuid(); + String fileList = tempPath + guid + ".txt"; + FileWriter fw = new FileWriter(fileList); + for (int i = 0, c = metas.size(); i < c; i++) { + String str = (i > 0 ? "\r\n" : "") + basePath + metas.get(i).getPath(); + fw.write(str.toCharArray()); + } + fw.close(); + + String vrt = tempPath + guid + ".vrt"; + String cmd = String.format("\"%s\\gdalbuildvrt.exe\" -input_file_list \"%s\" \"%s\"", gdalPath, fileList, vrt); + WebHelper.exec(cmd); + + return vrt; + } + + /** + * 鎺ㄩ�佹秷鎭� + */ + private void postInfo(AnalysisResultEntity entity) throws IOException { + JSONObject map = new JSONObject(); + map.put("analysisForPost", entity); + + String json = JSONObject.toJSONString(map); + //System.out.println(json) + + WebSocketService.broadCastInfo(json); + } + + /** + * 鍒嗘瀽鏂规硶 + */ + public List<AnalysisResultEntity> analysis(Geometry geo, Integer size) { + List<AnalysisResultEntity> rs = new ArrayList<>(); + + List<PublishEntity> pubs = publishService.selectRaster(); + if (null == pubs || pubs.isEmpty()) { + return rs; + } + + for (PublishEntity pub : pubs) { + try { + AnalysisResultEntity entity = new AnalysisResultEntity(); + entity.setLayerName(pub.getName()); + entity.setUnit(pub.getUnit()); + + List<MetaEntity> metas = publishService.selectMetasByPubid(pub.getId()); + if (null == metas || metas.isEmpty()) { + setError(entity, "鎵句笉鍒板彂甯冩暟鎹�"); + continue; + } + + String filePath = getFilePath(metas); + File file = new File(filePath); + if (!file.exists() || file.isDirectory()) { + setError(entity, "婧愭暟鎹笉瀛樺湪"); + continue; + } + + openRaster(entity, filePath, geo, size); + rs.add(entity); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + } + } + return rs; + } + + /** + * 鎵撳紑鏍呮牸鏁版嵁 + */ + private void openRaster(AnalysisResultEntity entity, String filePath, Geometry geo, int size) { + Dataset ds = null; + try { + // filePath = "D:\\Moon\\data\\DOM\\test.tif" + ds = gdal.Open(filePath); + if (null == ds) { + throw new Exception("鎵撳紑鏍呮牸鏁版嵁澶辫触"); + } + + switch (geo.GetGeometryType()) { + case ogr.wkbPoint: + analysisPoint(entity, ds, geo, size); + break; + case ogr.wkbLineString: + analysisPolyline(entity, ds, geo, size); + break; + default: + analysisPolygon(entity, ds, geo); + } + } catch (Exception ex) { + setError(entity, ex.getMessage()); + log.error(ex.getMessage(), ex); + } finally { + // gdal.GDALDestroyDriverManager() + if (null != ds) { + ds.delete(); + } + } + } + + /** + * 鍒嗘瀽鐐� + */ + public void analysisPoint(AnalysisResultEntity entity, Dataset ds, Geometry geo, int size) { + double[] transform = ds.GetGeoTransform(); + double pixelWidth = transform[1], pixelHeight = Math.abs(transform[5]); + + double buffer = Math.max(pixelWidth, pixelHeight) * size; + geo = geo.Buffer(buffer); + + analysisPolygon(entity, ds, geo); + } + + /** + * 鍒嗘瀽绾� + */ + public void analysisPolyline(AnalysisResultEntity entity, Dataset ds, Geometry geo, int size) { + double[] transform = ds.GetGeoTransform(); + int xSize = ds.getRasterXSize(), ySize = ds.getRasterYSize(); + double minX = transform[0], pixelWidth = transform[1], maxY = transform[3], pixelHeight = transform[5]; + + double len = 0; + int bandCount = ds.getRasterCount(); + double lineDis = getPolylineDistance(geo); + double distance = lineDis / Math.max(geo.GetPointCount(), size); + + List<double[]> points = getPointsByDistance(geo, distance); + for (int i = 0, c = points.size(); i < c; i++) { + double[] xy = points.get(i); + if (i > 0) { + double[] p = points.get(i - 1); + len += GeoHelper.getDistance(p[0], p[1], xy[0], xy[1]); + } + + int xPixel = (int) Math.floor((xy[0] - minX) / pixelWidth); + int yPixel = (int) Math.floor((maxY - xy[1]) / Math.abs(pixelHeight)); + if (xPixel < 1 || xPixel > xSize || yPixel < 1 || yPixel > ySize) { + continue; + } + + List<Double> vals = new ArrayList<>(); + for (int j = 1; j <= bandCount; j++) { + double[] pixelValues = new double[1]; + ds.GetRasterBand(j).ReadRaster(xPixel, yPixel, 1, 1, pixelValues); + if (!Double.isNaN(pixelValues[0])) { + vals.add(WebHelper.round(pixelValues[0], 3)); + } + } + if (vals.size() > 0) { + entity.addPoint(xy[0], xy[1], len, vals); + } + } + } + + /** + * 鍒嗘瀽闈� + */ + public void analysisPolygon(AnalysisResultEntity entity, Dataset ds, Geometry geo) { + double[] transform = ds.GetGeoTransform(); + int xSize = ds.getRasterXSize(), ySize = ds.getRasterYSize(); + double minX = transform[0], pixelWidth = transform[1], maxY = transform[3], pixelHeight = Math.abs(transform[5]), rotationX = transform[2], rotationY = transform[4]; + double[] env = new double[4]; + geo.GetEnvelope(env); + entity.addPoint(geo.Centroid().GetX(), geo.Centroid().GetY(), 0, null); + + int xMinPixel = Math.max((int) Math.floor((env[0] - minX) / pixelWidth), 1); + int yMinPixel = Math.max((int) Math.floor((maxY - env[3]) / pixelHeight), 1); + int xMaxPixel = Math.min((int) Math.floor((env[1] - minX) / pixelWidth), xSize); + int yMaxPixel = Math.min((int) Math.floor((maxY - env[2]) / pixelHeight), ySize); + if (xMaxPixel < 1 || yMaxPixel < 1 || xMaxPixel - xMinPixel < 0 || yMaxPixel - yMinPixel < 0) { + setError(entity, "鏌ヨ鑼冨洿鏃犳晥"); + return; + } + + int bandCount = ds.getRasterCount(); + int width = xMaxPixel - xMinPixel; + int height = yMaxPixel - yMinPixel; + if (width * height > StaticData.I64 * StaticData.I64) { + readRasterForBlocks(entity, ds, bandCount, xMinPixel, yMinPixel, width, height); + return; + } + + for (int i = 1; i <= bandCount; i++) { + double[] pixelValues = new double[width * height]; + ds.GetRasterBand(i).ReadRaster(xMinPixel, yMinPixel, width, height, pixelValues); + setBandVals(entity, pixelValues); + } + } + + /** + * 鎸夌収鍧楄鍙栨爡鏍兼暟鎹� + */ + private void readRasterForBlocks(AnalysisResultEntity entity, Dataset ds, int bandCount, int xMinPixel, int yMinPixel, int width, int height) { + List<Integer> xList = getSamples(xMinPixel, width - 1); + List<Integer> yList = getSamples(yMinPixel, height - 1); + + double[] pixelValues = new double[1]; + for (int i = 1; i <= bandCount; i++) { + List<Double> list = new ArrayList<>(); + for (Integer x : xList) { + for (Integer y : yList) { + ds.GetRasterBand(i).ReadRaster(x, y, 1, 1, pixelValues); + if (!Double.isNaN(pixelValues[0])) { + list.add(pixelValues[0]); + } + } + } + setBandVals(entity, list); + } + } + + /** + * 鑾峰彇鎶芥牱鍒楄〃 + */ + private List<Integer> getSamples(int start, int strip) { + List<Integer> list = new ArrayList<>(); + + double avg = 1.0 * strip / (StaticData.I64 - 1); + for (int i = 0; i < StaticData.I64; i++) { + list.add(start + (int) Math.ceil(avg * i)); + } + + return list; + } + + /** + * 璁剧疆閿欒 + */ + private void setError(AnalysisResultEntity entity, String info) { + entity.setCode(StaticData.I500); + entity.setInfo(info); + } + + /** + * 璁剧疆Band鍊� + */ + private void setBandVals(AnalysisResultEntity entity, double[] pixelValues) { + if (null == pixelValues || pixelValues.length == 0) { + return; + } + + List<Double> list = new ArrayList<>(); + for (double val : pixelValues) { + if (!Double.isNaN(val) && val > Integer.MIN_VALUE) { + list.add(val); + } + } + setBandVals(entity, list); + } + + /** + * 璁剧疆Band鍊� + */ + private void setBandVals(AnalysisResultEntity entity, List<Double> list) { + if (null == list || list.isEmpty()) { + return; + } + + double min = Collections.min(list); + double max = Collections.max(list); + double avg = list.stream().mapToDouble(Double::valueOf).average().getAsDouble(); + entity.addBandVals(min, avg, max); + } + + /** + * 鑾峰彇鎶樼嚎璺濈 + */ + private double getPolylineDistance(Geometry geo) { + double dis = 0; + for (int i = 0, c = geo.GetPointCount() - 1; i < c; i++) { + double[] xy1 = geo.GetPoint(i); + double[] xy2 = geo.GetPoint(i + 1); + + dis += GeoHelper.getDistance(xy1[0], xy1[1], xy2[0], xy2[1]); + } + + return dis; + } + + /** + * 鏍规嵁璺濈鑾峰彇鑺傜偣 + */ + private List<double[]> getPointsByDistance(Geometry geo, double distance) { + List<double[]> list = new ArrayList<>(); + + int c = geo.GetPointCount() - 1; + for (int i = 0; i < c; i++) { + double[] xy1 = geo.GetPoint(i); + double[] xy2 = geo.GetPoint(i + 1); + list.add(xy1); + + double lineDis = GeoHelper.getDistance(xy1[0], xy1[1], xy2[0], xy2[1]); + if (lineDis < distance) { + continue; + } + + double d = distance; + double angle = GeoHelper.getAngle(xy1[0], xy1[1], xy2[0], xy2[1]); + while (d + distance * StaticData.D05 < lineDis) { + Point2D point = GeoHelper.getPointByDistanceAndAngle(xy1[0], xy1[1], angle, d); + list.add(new double[]{point.getX(), point.getY()}); + d += distance; + } + } + list.add(geo.GetPoint(c)); + + return list; + } + + /** + * 鍒嗘瀽鐐� 2 + */ + public void analysisPoint2(AnalysisResultEntity entity, Dataset ds, Geometry geo, int size) { + double x = geo.GetX(), y = geo.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)); + + 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); + } + } + + /** + * 鍒嗘瀽绾� 2 + */ + public void analysisPolyline2(AnalysisResultEntity entity, Dataset ds, Geometry geo, int size) { + double[] transform = ds.GetGeoTransform(); + // double rotationX = transform[2]; double rotationY = transform[4] + double minX = transform[0], pixelWidth = transform[1], maxY = transform[3], pixelHeight = Math.abs(transform[5]); + + double buffer = Math.max(pixelWidth, pixelHeight) * size; + double[] env = new double[4]; + geo = geo.Buffer(buffer); + geo.GetEnvelope(env); + + int xMinPixel = (int) Math.floor((env[0] - minX) / pixelWidth); + int yMinPixel = (int) Math.floor((maxY - env[3]) / pixelHeight); + int xMaxPixel = (int) Math.floor((env[1] - minX) / pixelWidth); + int yMaxPixel = (int) Math.floor((maxY - env[2]) / pixelHeight); + + int bandCount = ds.getRasterCount(); + int xMin = Math.min(xMinPixel, xMaxPixel); + int xMax = Math.max(xMinPixel, xMaxPixel); + int yMin = Math.min(yMinPixel, yMaxPixel); + int yMax = Math.max(yMinPixel, yMaxPixel); + + List<Double> list = new ArrayList<>(); + for (int y = yMin; y <= yMax; y++) { + for (int x = xMin; x <= xMax; x++) { + Geometry point = new Geometry(ogr.wkbPoint); + point.AddPoint(minX + pixelWidth * x, maxY - pixelHeight * y); + if (geo.Intersects(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) + } + + private void 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); + } + } + + private Dataset clipRaster(Dataset dataset, Geometry geometry) { Vector<String> warpOptions = new Vector<>(); warpOptions.add("-crop_to_cutline"); warpOptions.add("-cutline"); @@ -27,237 +520,5 @@ 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) { - // 鎵撳紑鏍呮牸鍥惧儚鏁版嵁闆� - 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) { - // 鎵撳紑鏍呮牸鍥惧儚鏁版嵁闆� - 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