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];
|
}
|
|
}
|