package com.se.nsl.utils; import com.se.nsl.domain.vo.SimuResult; import lombok.extern.slf4j.Slf4j; import org.gdal.gdal.Band; import org.gdal.gdal.Dataset; import org.gdal.gdal.gdal; import org.gdal.gdalconst.gdalconstConstants; import java.io.File; //求解器产生的tif文件处理工具 @Slf4j public class SolverTifUtil { private SolverTifUtil() {} private static final String YYYY_MM_DD_HH_MM_SS = "yyyyMMddHHmmss"; private static class ColumnRow { public final Dataset dataset; public final int col; public final int row; public ColumnRow(Dataset dataset, int col, int row) { this.dataset = dataset; this.col = col; this.row = row; } } public static SimuResult getSimuResult(File tifFile, double[] position) { double x = position[0]; double y = position[1]; ColumnRow cr = getColumnRow(tifFile, x, y); if (cr == null) return null; float depth = readPixelValue(cr.dataset, cr.col, cr.row, 1); float velocity = calcVelocity(cr.dataset, cr.col, cr.row); SimuResult result = new SimuResult(); result.setDepth(depth); result.setVelocity(velocity); String time = tifFile.getName().replace(".tif", ""); result.setTime(TimeFormatUtil.toMillis(time, YYYY_MM_DD_HH_MM_SS)); return result; } public static float getDepth(File tifFile, double[] position) { double x = position[0]; double y = position[1]; ColumnRow cr = getColumnRow(tifFile, x, y); if (cr == null) return 0; return readPixelValue(cr.dataset, cr.col, cr.row, 1); } public static float getValue(File tifFile, double[] position, int band) { double x = position[0]; double y = position[1]; ColumnRow cr = getColumnRow(tifFile, x, y); if (cr == null) return 0; return readPixelValue(cr.dataset, cr.col, cr.row, band); } public static ColumnRow getColumnRow(File tifFile, double x, double y) { Dataset dataset = gdal.Open(tifFile.getAbsolutePath(), gdalconstConstants.GA_ReadOnly); // 获取地理变换参数(6元素数组) // [0]: 左上角X坐标, [1]: 像元宽度, [2]: X方向旋转, // [3]: 左上角Y坐标, [4]: Y方向旋转, [5]: 像元高度(负值表示Y轴向下) double[] geoTransform = dataset.GetGeoTransform(); //计算栅格行列号 int col = (int) ((x - geoTransform[0]) / geoTransform[1]); int row = (int) ((geoTransform[3] - y) / Math.abs(geoTransform[5])); int width = dataset.getRasterXSize(); int height = dataset.getRasterYSize(); if (col < 0 || col > width || row < 0 || row > height) { log.warn("行列号不在tif范围内"); return null; } return new ColumnRow(dataset, col, row); } private static float calcVelocity(Dataset dataset, int col, int row) { float x = readPixelValue(dataset, col, row, 2); float y = readPixelValue(dataset, col, row, 3); float velocity; if (Float.isNaN(x) && Float.isNaN(y)) { velocity = 0f; } else if (Float.isNaN(x)) { velocity = y; } else if (Float.isNaN(y)) { velocity = x; } else { velocity = (float) Math.sqrt(x * x + y * y); } return velocity; } private static float readPixelValue(Dataset dataset, int col, int row, int bandNum) { Band band = dataset.GetRasterBand(bandNum); float[] values = new float[1]; band.ReadRaster(col, row, 1, 1, values); return values[0]; } }