package com.se.nsl.service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.bc.zarr.ZarrArray; import com.bc.zarr.ZarrGroup; import com.se.nsl.config.PropertiesConfig; import com.se.nsl.domain.po.Simu; import com.se.nsl.domain.vo.SimuResult; import com.se.nsl.domain.vo.SimuVo; import com.se.nsl.helper.StringHelper; import com.se.nsl.mapper.SimuMapper; import com.se.nsl.utils.CoordinateTransformer; import com.se.nsl.utils.SolverTifUtil; import com.se.nsl.utils.TimeFormatUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import ucar.ma2.InvalidRangeException; import javax.annotation.Resource; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @Slf4j @Service @SuppressWarnings("ALL") public class SimuService { public static final String TIF_EXTSION = ".tif"; public static final String YYYY_MM_DD_HH_MM_SS = "yyyyMMddHHmmss"; @Resource SimuMapper simuMapper; @Resource PropertiesConfig config; /** * 分页查询推演模拟 * * @param pageNum 页码 * @param pageSize 每页数量 * @return 分页后的推演模拟 */ public IPage selectPage(SimuVo vo, int pageNum, int pageSize) { QueryWrapper wrapper = getPageWrapper(vo, pageNum, pageSize); Page page = new Page<>(pageNum, pageSize); page.addOrder(OrderItem.desc("id")); return simuMapper.selectPage(page, wrapper); } private QueryWrapper getPageWrapper(SimuVo vo, int pageNum, int pageSize) { QueryWrapper wrapper = new QueryWrapper<>(); if (null != vo.getId()) { wrapper.eq("id", vo.getId()); } if (!StringHelper.isEmpty(vo.getName())) { wrapper.like("lower(name)", vo.getName().trim().toLowerCase()); } if (!StringHelper.isEmpty(vo.getServiceName())) { wrapper.like("service_name", vo.getServiceName().trim()); } if (null != vo.getType()) { wrapper.eq("type", vo.getType()); } if (null != vo.getAreaType()) { wrapper.eq("area_type", vo.getAreaType()); } if (null != vo.getStatus()) { wrapper.eq("status", vo.getStatus()); } return wrapper; } /** * 根据ID批量删除推演模拟 * * @param ids 要删除的区域ID列表 * @return 删除成功的记录数 */ public int deleteByIds(List ids) { return simuMapper.deleteBatchIds(ids); } /** * 新增推演模拟 * * @param Simu 推演模拟对象 * @return 新增成功的记录数 */ public int insert(Simu simu) { return simuMapper.insert(simu); } public int inserts(List list) { return simuMapper.inserts(list); } /** * 根据ID查询 * * @param id ID * @return Simu */ public Simu selectById(Integer id) { return simuMapper.selectById(id); } /** * 修改推演模拟 * * @param Simu 推演模拟对象 * @return 修改成功的记录数 */ public int updateById(Simu simu) { return simuMapper.updates(Arrays.asList(simu)); } public SimuResult queryByPosition(double lon, double lat, long time, String serviceName) { //transform coordiante from 4326 to 4548 double[] xy = CoordinateTransformer.transform(4326, 4548, lon, lat); // System.out.println(String.format("转换前的坐标:x:%s,y:%s", lon, lat)); // System.out.println(String.format("转换后的坐标:x:%s,y:%s", xy[0], xy[1])); //read from zarr // return queryByZarr(xy, time, serviceName); //read from tif file return queryByTif(xy, time, serviceName); } public List queryByPosition(double lon, double lat, String serviceName) { //transform coordiante from 4326 to 4548 double[] xy = CoordinateTransformer.transform(4326, config.getEpsg(), lon, lat); // System.out.println(String.format("转换前的坐标:x:%s,y:%s", lon, lat)); // System.out.println(String.format("转换后的坐标:x:%s,y:%s", xy[0], xy[1])); //read from zarr // return queryByZarr(xy, time, serviceName); //read from tif file return queryByTif(xy, serviceName); } private SimuResult queryByZarr(double[] xy, long time, String serviceName) { double x = xy[0]; double y = xy[1]; String prefix = formatTime(time); File inPath = new File(config.getInPath()); // File tifDir = new File(inPath, serviceName + File.separator + "depth"); // int index = 0; // File[] files = tifDir.listFiles(); // for (File file : files) { // String name = file.getName(); // if (!name.endsWith(TIF_EXTSION)) continue; // if (name.equals(prefix + TIF_EXTSION)) { // break; // } // index++; // } File dem = new File(inPath, serviceName + File.separator + "DEM.tif"); //TODO File zarr = new File(inPath, serviceName + File.separator + "result.zarr"); try { ZarrGroup group = ZarrGroup.open(zarr.toPath()); ZarrArray depthArray = group.openArray("depth"); int[] shape = new int[] {60, 637, 351}; // int[] offset = new int[]{210, 384}; float[] depth = (float[]) depthArray.read(shape); System.out.println("depth:" + depth.length); } catch (IOException | InvalidRangeException e) { throw new RuntimeException(e); } return null; } private SimuResult queryByTif(double[] xy, long time, String serviceName) { File inPath = new File(config.getInPath()); String prefix = formatTime(time); String child = serviceName + File.separator + "depth" + File.separator + prefix + TIF_EXTSION; File tifFile = new File(inPath, child); if (!tifFile.exists()) { return null; } return SolverTifUtil.getSimuResult(tifFile, xy); } private List queryByTif(double[] xy, String serviceName) { List res = new ArrayList<>(); File inPath = new File(config.getInPath()); Path depthPath = Paths.get(inPath.getAbsolutePath(), serviceName, "depth"); File depthDir = depthPath.toFile(); File[] files = depthDir.listFiles(); for (File tifFile : files) { String name = tifFile.getName(); if (!name.endsWith(TIF_EXTSION)) continue; SimuResult result = SolverTifUtil.getSimuResult(tifFile, xy); if (result == null) continue; res.add(result); } return res; } private String formatTime(long time) { return TimeFormatUtil.formatTime(time, YYYY_MM_DD_HH_MM_SS); } }