From 51d12c4cca7c9d4911a0037673bbd2dc210836d0 Mon Sep 17 00:00:00 2001
From: dcb <xgybdcb@163.com>
Date: 星期五, 20 六月 2025 10:17:12 +0800
Subject: [PATCH] 根据位置查询Bug修复

---
 src/main/java/com/se/nsl/service/SimuService.java |  299 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 299 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/se/nsl/service/SimuService.java b/src/main/java/com/se/nsl/service/SimuService.java
new file mode 100644
index 0000000..ccc2b3d
--- /dev/null
+++ b/src/main/java/com/se/nsl/service/SimuService.java
@@ -0,0 +1,299 @@
+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.TimeFormatUtil;
+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 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_HHMMSS = "yyyyMMddHHmmss";
+    @Resource
+    SimuMapper simuMapper;
+
+    @Resource
+    PropertiesConfig config;
+
+    /**
+     * 鍒嗛〉鏌ヨ鎺ㄦ紨妯℃嫙
+     *
+     * @param pageNum  椤电爜
+     * @param pageSize 姣忛〉鏁伴噺
+     * @return 鍒嗛〉鍚庣殑鎺ㄦ紨妯℃嫙
+     */
+    public IPage<Simu> selectPage(SimuVo vo, int pageNum, int pageSize) {
+        QueryWrapper<Simu> wrapper = getPageWrapper(vo, pageNum, pageSize);
+
+        Page<Simu> page = new Page<>(pageNum, pageSize);
+        page.addOrder(OrderItem.desc("id"));
+
+        IPage<Simu> paged = simuMapper.selectPage(page, wrapper);
+
+        return paged;
+    }
+
+    private QueryWrapper<Simu> getPageWrapper(SimuVo vo, int pageNum, int pageSize) {
+        QueryWrapper<Simu> 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<Integer> ids) {
+        return simuMapper.deleteBatchIds(ids);
+    }
+
+    /**
+     * 鏂板鎺ㄦ紨妯℃嫙
+     *
+     * @param Simu 鎺ㄦ紨妯℃嫙瀵硅薄
+     * @return 鏂板鎴愬姛鐨勮褰曟暟
+     */
+    public int insert(Simu simu) {
+        return simuMapper.insert(simu);
+    }
+
+    public int inserts(List<Simu> 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("杞崲鍓嶇殑鍧愭爣锛歺:%s,y:%s", lon, lat));
+//        System.out.println(String.format("杞崲鍚庣殑鍧愭爣锛歺:%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<SimuResult> queryByPosition(double lon, double lat, String serviceName) {
+        //transform coordiante from 4326 to 4548
+        double[] xy = CoordinateTransformer.transform(4326, 4548, lon, lat);
+//        System.out.println(String.format("杞崲鍓嶇殑鍧愭爣锛歺:%s,y:%s", lon, lat));
+//        System.out.println(String.format("杞崲鍚庣殑鍧愭爣锛歺:%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");
+        ColumnRow cr = getColumnRow(dem.getAbsoluteFile(), x, y);
+        if (cr == null) return null;
+
+        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) {
+        double x = xy[0];
+        double y = xy[1];
+        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;
+        }
+
+        ColumnRow cr = getColumnRow(tifFile, x, y);
+        if (cr == null) return null;
+//        System.out.println("col:" + cr.col + " ,row:" + cr.row);
+        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);
+        result.setTime(time);
+        return  result;
+    }
+
+    private List<SimuResult> queryByTif(double[] xy, String serviceName) {
+        double x = xy[0];
+        double y = xy[1];
+        List<SimuResult> 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;
+            ColumnRow cr = getColumnRow(tifFile, x, y);
+            if (cr == null) continue;
+            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_HHMMSS));
+            res.add(result);
+        }
+        return  res;
+    }
+
+    private static ColumnRow getColumnRow(File tifFile, double x, double y) {
+        Dataset dataset = gdal.Open(tifFile.getAbsolutePath(), gdalconstConstants.GA_ReadOnly);
+        // 鑾峰彇鍦扮悊鍙樻崲鍙傛暟锛�6鍏冪礌鏁扮粍锛�
+        // [0]: 宸︿笂瑙扻鍧愭爣, [1]: 鍍忓厓瀹藉害, [2]: X鏂瑰悜鏃嬭浆,
+        // [3]: 宸︿笂瑙扽鍧愭爣, [4]: Y鏂瑰悜鏃嬭浆, [5]: 鍍忓厓楂樺害锛堣礋鍊艰〃绀篩杞村悜涓嬶級
+        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("琛屽垪鍙蜂笉鍦╰if鑼冨洿鍐�");
+            return null;
+        }
+        return new ColumnRow(dataset, col, row);
+    }
+
+    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;
+        }
+    }
+
+    private float calcVelocity(Dataset dataset, int col, int row) {
+        float x = readPixelValue(dataset, col, row, 2);
+        float y = readPixelValue(dataset, col, row, 3);
+        float velocity = 0f;
+        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 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];
+    }
+
+    private String formatTime(long time) {
+        return TimeFormatUtil.formatTime(time, YYYY_MM_DD_HHMMSS);
+    }
+
+}

--
Gitblit v1.9.3