package com.se.simu.service;
|
|
import cn.hutool.json.JSONUtil;
|
import com.se.simu.config.PropertiesConfig;
|
import com.se.simu.domain.po.DataPo;
|
import com.se.simu.domain.po.SimuPo;
|
import com.se.simu.domain.vo.*;
|
import com.se.simu.helper.GdalHelper;
|
import lombok.extern.slf4j.Slf4j;
|
import org.gdal.gdal.Dataset;
|
import org.gdal.gdal.gdal;
|
import org.gdal.gdalconst.gdalconst;
|
import org.gdal.osr.SpatialReference;
|
import org.gdal.osr.osr;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.List;
|
|
/**
|
* 内涝服务类
|
*
|
* @author WWW
|
* @date 2024-07-16
|
*/
|
@Slf4j
|
@Service
|
@SuppressWarnings("ALL")
|
public class WaterService {
|
@Resource
|
PropertiesConfig config;
|
|
/**
|
* 获取元数据信息
|
*/
|
public byte[] getson(String serviceName, String json) {
|
try {
|
String filePath = config.getOutPath() + File.separator + serviceName + File.separator + json;
|
|
File dat = new File(filePath);
|
if (!dat.exists()) {
|
return null;
|
}
|
|
byte[] bytes = new byte[(int) dat.length()];
|
|
FileInputStream fs = new FileInputStream(filePath);
|
fs.read(bytes);
|
fs.close();
|
|
return bytes;
|
} catch (Exception ex) {
|
log.error(ex.getMessage(), ex);
|
return null;
|
}
|
}
|
|
/**
|
* 获取地形高度图
|
*/
|
public String getTerraMap(String serviceName, Integer width, Integer height) {
|
return config.getOutPath() + File.separator + serviceName + File.separator + "terrain" + File.separator + width + "_" + height + ".png";
|
}
|
|
/**
|
* 获取水面高度图
|
*/
|
public String getWaterMap(String serviceName, Integer width, Integer height, Long timestamp) {
|
return config.getOutPath() + File.separator + serviceName + File.separator + "waters" + File.separator + timestamp + File.separator + width + "_" + height + ".png";
|
}
|
|
/**
|
* 获取水流向流速图
|
*/
|
public String getFlowMap(String serviceName, Integer width, Integer height, Long timestamp) {
|
return config.getOutPath() + File.separator + serviceName + File.separator + "flows" + File.separator + timestamp + File.separator + width + "_" + height + ".png";
|
}
|
|
/**
|
* 获取图层 *
|
*/
|
public Layer getLayer(String serviceName) {
|
Layer layer = new Layer();
|
layer.setVersion(config.getVer());
|
layer.setDuration(new Duration(1719812810225L, 1719812810225L));
|
layer.setExtension(new Extension(2.11062743358, 0.53812160220, 2.11070827834, 0.53819799453, 1.151, 38.83));
|
|
List<Integer[]> sizes = new ArrayList<>();
|
sizes.add(new Integer[]{64, 64});
|
sizes.add(new Integer[]{128, 128});
|
sizes.add(new Integer[]{256, 256});
|
sizes.add(new Integer[]{512, 512});
|
sizes.add(new Integer[]{1024, 1024});
|
sizes.add(new Integer[]{2048, 2048});
|
layer.setTerrain(new Terrain(sizes));
|
|
List<Long> data = new ArrayList<>(Arrays.asList(1719812812225L, 1719812812225L, 1719812812225L, 1719812812225L, 1719812812225L, 1719812812225L));
|
layer.setWaters(new Water(data));
|
|
return layer;
|
}
|
|
/**
|
* 根据坐标查询积水深度:gdalconst.GA_Update
|
*/
|
public Double getWaterHeight(SimuPo simu, double x, double y, Long timestamp) {
|
String filePath = config.getOutPath() + File.separator + simu.getServiceName() + File.separator + "waters"
|
+ File.separator + timestamp + File.separator + "water.tif";
|
|
Dataset ds = null;
|
try {
|
ds = gdal.Open(filePath, gdalconst.GA_ReadOnly);
|
if (null == ds || ds.getRasterCount() < 1) {
|
return null;
|
}
|
if (null == ds.GetSpatialRef()) {
|
ds.SetSpatialRef(getSpatialRef(simu));
|
}
|
|
double[] gt = ds.GetGeoTransform();
|
double[] xy = GdalHelper.fromWgs84(ds.GetSpatialRef(), x, y);
|
int[] XY = coordinates2ColRow(gt, xy[0], xy[1]);
|
|
if (XY[0] < 0 || XY[1] < 0 || XY[0] > ds.getRasterXSize() || XY[1] > ds.getRasterYSize()) {
|
return null;
|
}
|
|
double[] vals = new double[1];
|
ds.GetRasterBand(1).ReadRaster(XY[0], XY[1], 1, 1, vals);
|
|
return isValid(vals[0]) ? vals[0] : null;
|
} catch (Exception ex) {
|
log.error(ex.getMessage(), ex);
|
return null;
|
} finally {
|
if (null != ds) ds.delete();
|
}
|
}
|
|
private SpatialReference getSpatialRef(SimuPo simu) {
|
DataPo data = JSONUtil.toBean(simu.getData(), DataPo.class);
|
|
SpatialReference sr = new SpatialReference();
|
sr.ImportFromEPSG(data.getEpsg());
|
sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
|
|
return sr;
|
}
|
|
/**
|
* 将地图坐标转换为栅格像素坐标
|
*
|
* @param gt 仿射变换参数
|
* @param x 横坐标
|
* @param y 纵坐标
|
* @return 像素坐标
|
*/
|
public int[] coordinates2ColRow(double[] gt, double x, double y) {
|
// 向下取整,如果向上取整会导致计算结果偏大,从而在后面读取到邻近像元的数据
|
//Double col = Math.floor(((y - gt[3]) * gt[1] - (x - gt[0]) * gt[4]) / (gt[5] * gt[1] - gt[2] * gt[4]));
|
Double col = Math.floor((y * gt[1] - x * gt[4] + gt[0] * gt[4] - gt[3] * gt[1]) / (gt[5] * gt[1] - gt[2] * gt[4]));
|
Double row = Math.floor((x - gt[0] - col * gt[2]) / gt[1]);
|
|
return new int[]{row.intValue(), col.intValue()};
|
}
|
|
public static boolean isValid(double val) {
|
return !Double.isNaN(val) && val > Integer.MIN_VALUE;
|
}
|
}
|