From 6d817179edaf2a6c793595056f5d250eb4396ab0 Mon Sep 17 00:00:00 2001 From: dcb <xgybdcb@163.com> Date: 星期一, 26 五月 2025 09:54:02 +0800 Subject: [PATCH] 输出的png结果修改为可以通过设置间隔时间来输出 --- src/main/java/com/se/nsl/controller/SimuController.java | 27 +++ src/main/java/com/se/nsl/domain/po/SimuData.java | 2 src/main/java/com/se/nsl/service/ResolveService.java | 37 ++++ src/main/java/com/se/nsl/config/PropertiesConfig.java | 10 + src/main/java/com/se/nsl/service/TestService.java | 6 src/main/java/com/se/nsl/utils/ZarrReader.java | 112 ++++++++++++++++ src/main/resources/application-dev.yml | 13 + src/main/java/com/se/nsl/service/SimuService.java | 14 + src/main/java/com/se/nsl/domain/vo/SimuResult.java | 23 +++ src/main/java/com/se/nsl/utils/CoordinateTransformer.java | 120 +++++++++++++++++ 10 files changed, 350 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/se/nsl/config/PropertiesConfig.java b/src/main/java/com/se/nsl/config/PropertiesConfig.java index 6d19af8..e035421 100644 --- a/src/main/java/com/se/nsl/config/PropertiesConfig.java +++ b/src/main/java/com/se/nsl/config/PropertiesConfig.java @@ -66,6 +66,8 @@ private Integer saveFrames; + private Integer saveFrameInterval; + private List<Integer> sizes; private String terrainFile; @@ -288,6 +290,14 @@ this.saveFrames = saveFrames; } + public Integer getSaveFrameInterval() { + return saveFrameInterval; + } + + public void setSaveFrameInterval(Integer saveFrameInterval) { + this.saveFrameInterval = saveFrameInterval; + } + public boolean isCopyTif() { return copyTif; } diff --git a/src/main/java/com/se/nsl/controller/SimuController.java b/src/main/java/com/se/nsl/controller/SimuController.java index 0028a67..484f60f 100644 --- a/src/main/java/com/se/nsl/controller/SimuController.java +++ b/src/main/java/com/se/nsl/controller/SimuController.java @@ -1,6 +1,7 @@ package com.se.nsl.controller; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.metadata.IPage; import com.se.nsl.domain.po.Simu; import com.se.nsl.domain.po.SimuData; @@ -94,12 +95,15 @@ return fail("geom瀵硅薄涓嶆槸澶氳竟褰�"); int rows = simuService.insert(simu); + System.out.println(String.format("id:%s", simu.getId())); + if (rows > 0 && (null == data.getRainfalls() || data.getRainfalls().size() < 2)) { resolveService.createRainfall(simu); simuService.updateById(simu); } - - return success(rows); + JSONObject json = new JSONObject(); + json.put("id", simu.getId()); + return success(json); } catch (Exception ex) { return fail(ex, null); } @@ -156,4 +160,23 @@ return fail(ex, null); } } + + @ApiOperation(value = "position") + @GetMapping("/position") + public R<Object> queryByPosition(double lon, double lat, String time, String serviceName) { + if (lon > 180 || lon < -180) { + return fail("缁忓害鑼冨洿搴旇鍦�-180鍒�180"); + } + if (lat > 90 || lat < -90) { + return fail("绾害鑼冨洿搴旇鍦�-90鍒�90"); + } + if (time == null || time.trim().isEmpty()) { + return fail("鏃堕棿鎴充笉鑳戒负绌�"); + } + if (serviceName == null || serviceName.trim().isEmpty()) { + return fail("鏈嶅姟鍚嶄笉鑳戒负绌�"); + } + + return null; + } } diff --git a/src/main/java/com/se/nsl/domain/po/SimuData.java b/src/main/java/com/se/nsl/domain/po/SimuData.java index 1b5dfac..61c0fe9 100644 --- a/src/main/java/com/se/nsl/domain/po/SimuData.java +++ b/src/main/java/com/se/nsl/domain/po/SimuData.java @@ -68,7 +68,7 @@ @ApiModelProperty("闄嶉洦鍒楄〃") private List<Rainfall> rainfalls; - @ApiModelProperty("闆ㄥ己鍗曚綅锛歮m/h銆乵m/5min") + @ApiModelProperty("闆ㄥ己鍗曚綅锛歮m/h銆乵m/5min銆乵m/min") private String intensityUnit; public SimuData() { diff --git a/src/main/java/com/se/nsl/domain/vo/SimuResult.java b/src/main/java/com/se/nsl/domain/vo/SimuResult.java new file mode 100644 index 0000000..1046f80 --- /dev/null +++ b/src/main/java/com/se/nsl/domain/vo/SimuResult.java @@ -0,0 +1,23 @@ +package com.se.nsl.domain.vo; + +public class SimuResult { + + private double depth; + private double velocity; + + public double getDepth() { + return depth; + } + + public void setDepth(double depth) { + this.depth = depth; + } + + public double getVelocity() { + return velocity; + } + + public void setVelocity(double velocity) { + this.velocity = velocity; + } +} diff --git a/src/main/java/com/se/nsl/service/ResolveService.java b/src/main/java/com/se/nsl/service/ResolveService.java index cfe6efc..0ee73a6 100644 --- a/src/main/java/com/se/nsl/service/ResolveService.java +++ b/src/main/java/com/se/nsl/service/ResolveService.java @@ -210,6 +210,30 @@ } f.mkdirs(); } + + enum RainFallUnit { + MM_H("mm/h", 60), + MM_15MIN("mm/15min", 15), + MM_5MIN("mm/5min", 5), + MM_MIN("mm/min", 1); + private String unit; + private int c; //绯绘暟 + RainFallUnit(String unit, int c) { + this.unit = unit; + this.c = c; + } + + public static RainFallUnit of(String unit) { + RainFallUnit[] values = values(); + for (RainFallUnit v : values) { + if (v.unit.equals(unit)) { + return v; + } + } + return MM_H; //榛樿鎸夌収mm/h璁$畻 + } + + } public void createRainfallFile(Simu simu, SimuData data) throws Exception { List<Rainfall> rainfalls = data.getRainfalls(); @@ -228,8 +252,12 @@ double centerX = ComHelper.getMinVal((data.getMinx() + data.getMaxx()) / 2, DIGIT); double centerY = ComHelper.getMinVal((data.getMiny() + data.getMaxy()) / 2, DIGIT); String prefix = config.getRainfallSite() + " " + centerX + " " + centerY + " "; - int unit = StringUtils.isEmpty(data.getIntensityUnit()) || "mm/h".equals(data.getIntensityUnit()) ? 60 : 5; - + //濡傛灉娌℃湁鍗曚綅鎴栬�呭崟浣嶄负mm/h鍒欐寜鐓� mm/h璁$畻锛屽惁鍒欐寜鐓m/5min璁$畻 +// int unit = StringUtils.isEmpty(data.getIntensityUnit()) || "mm/h".equals(data.getIntensityUnit()) ? 60 : 5; + String iu = data.getIntensityUnit(); + RainFallUnit rfUnit = RainFallUnit.of(iu); + data.setIntensityUnit(rfUnit.unit); + int unit = rfUnit.c; int c = rainfalls.size() - 1; for (int i = 0; i < c; i++) { Rainfall r1 = rainfalls.get(i); @@ -290,7 +318,10 @@ String landuseFile = inPath + File.separator + config.getLanduseFile(); String rainfallFile = (inPath + File.separator + "rainfall.dat"); String saveName = inPath + File.separator + "result.zarr"; - ConfigVo vo = new ConfigVo(terrainFile, landuseFile, terrainFile, rainfallFile, saveName, duration, config.getSaveFrames()); +// ConfigVo vo = new ConfigVo(terrainFile, landuseFile, terrainFile, rainfallFile, saveName, duration, config.getSaveFrames()); + Integer saveFrameInterval = config.getSaveFrameInterval(); + int saveFrames = duration / 60 / saveFrameInterval; + ConfigVo vo = new ConfigVo(terrainFile, landuseFile, terrainFile, rainfallFile, saveName, duration, saveFrames); String configFile = config.getInPath() + File.separator + data.getInPath() + File.separator + data.getInPath() + ".json"; ComHelper.writeJson(configFile, JSON.toJSONString(vo)); diff --git a/src/main/java/com/se/nsl/service/SimuService.java b/src/main/java/com/se/nsl/service/SimuService.java index c218828..0a12469 100644 --- a/src/main/java/com/se/nsl/service/SimuService.java +++ b/src/main/java/com/se/nsl/service/SimuService.java @@ -5,15 +5,16 @@ import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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 lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Arrays; -import java.util.Collections; import java.util.List; @Slf4j @@ -108,4 +109,15 @@ public int updateById(Simu simu) { return simuMapper.updates(Arrays.asList(simu)); } + + public SimuResult queryByPosition(double lon, double lat, String 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 zarr data and compare the data with lon,lat,time + + return null; + } + } diff --git a/src/main/java/com/se/nsl/service/TestService.java b/src/main/java/com/se/nsl/service/TestService.java index fda8f1e..6408b5f 100644 --- a/src/main/java/com/se/nsl/service/TestService.java +++ b/src/main/java/com/se/nsl/service/TestService.java @@ -204,11 +204,9 @@ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); for (String file : files) { String fileName = ComHelper.getNameWithExt(file); - // 瑙f瀽涓� LocalDateTime锛堥粯璁ゅ熀浜庣郴缁熸椂鍖猴紝鍙兘闇�鎸囧畾鏃跺尯锛� LocalDateTime dateTime = LocalDateTime.parse(fileName, formatter); - // 杞崲涓� UTC 鏃堕棿鎴筹紙鎺ㄨ崘锛岄伩鍏嶆椂鍖烘涔夛級 - Instant utcInstant = dateTime.atZone(ZoneId.of("UTC")).toInstant(); - long timestamp = utcInstant.toEpochMilli(); + Instant instant = dateTime.atZone(ZoneId.systemDefault()).toInstant(); + long timestamp = instant.toEpochMilli(); layer.getWaters().getData().add(timestamp); } layer.getDuration().setStart(layer.getWaters().getData().get(0)); diff --git a/src/main/java/com/se/nsl/utils/CoordinateTransformer.java b/src/main/java/com/se/nsl/utils/CoordinateTransformer.java new file mode 100644 index 0000000..469c085 --- /dev/null +++ b/src/main/java/com/se/nsl/utils/CoordinateTransformer.java @@ -0,0 +1,120 @@ +package com.se.nsl.utils; + +import org.gdal.gdal.gdal; +import org.gdal.osr.CoordinateTransformation; +import org.gdal.osr.SpatialReference; +import org.gdal.osr.osr; + +public class CoordinateTransformer { + +// static { +// try { +// gdal.AllRegister(); +// } catch (Exception e) { +// System.err.println("GDAL椹卞姩娉ㄥ唽澶辫触: " + e.getMessage()); +// } +// } + + public static double[] transform(int sourceEPSG, int targetEPSG, + double x, double y, double z) { + SpatialReference sourceSRS = null; + SpatialReference targetSRS = null; + CoordinateTransformation ct = null; + + try { + // 鍒涘缓婧愬潗鏍囩郴 + sourceSRS = new SpatialReference(); + int sourceResult = sourceSRS.ImportFromEPSG(sourceEPSG); + if (sourceResult != 0) { + throw new IllegalArgumentException("鏃犳晥鐨勬簮EPSG浠g爜: " + sourceEPSG); + } + + // 鍒涘缓鐩爣鍧愭爣绯� + targetSRS = new SpatialReference(); + int targetResult = targetSRS.ImportFromEPSG(targetEPSG); + if (targetResult != 0) { + throw new IllegalArgumentException("鏃犳晥鐨勭洰鏍嘐PSG浠g爜: " + targetEPSG); + } + + sourceSRS.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER); + targetSRS.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER); + + // 鍒涘缓鍧愭爣杞崲瀵硅薄 + ct = new CoordinateTransformation(sourceSRS, targetSRS); + double[] result = ct.TransformPoint(x, y, z); + + if (result == null || Double.isNaN(result[0]) || Double.isNaN(result[1])) { + throw new IllegalArgumentException("鍧愭爣杞崲澶辫触锛屽彲鑳芥槸鍧愭爣绯讳笉鍏煎"); + } + + return result; + } finally { + // 纭繚璧勬簮琚噴鏀� + if (ct != null) ct.delete(); + if (targetSRS != null) targetSRS.delete(); + if (sourceSRS != null) sourceSRS.delete(); + } + } + + public static double[] transform(int sourceEPSG, int targetEPSG, double x, double y) { + return transform(sourceEPSG, targetEPSG, x, y, 0.0); + } + + public static double[] transform(String sourceWKT, String targetWKT, + double x, double y, double z) { + SpatialReference sourceSRS = null; + SpatialReference targetSRS = null; + CoordinateTransformation ct = null; + + try { + // 鍒涘缓婧愬潗鏍囩郴 + sourceSRS = new SpatialReference(); + int sourceResult = sourceSRS.ImportFromWkt(sourceWKT); + if (sourceResult != 0) { + throw new IllegalArgumentException("鏃犳晥鐨勬簮WKT瀹氫箟"); + } + + // 鍒涘缓鐩爣鍧愭爣绯� + targetSRS = new SpatialReference(); + int targetResult = targetSRS.ImportFromWkt(targetWKT); + if (targetResult != 0) { + throw new IllegalArgumentException("鏃犳晥鐨勭洰鏍嘩KT瀹氫箟"); + } + + // 鍒涘缓鍧愭爣杞崲瀵硅薄 + ct = new CoordinateTransformation(sourceSRS, targetSRS); + double[] result = ct.TransformPoint(x, y, z); + + if (result == null || Double.isNaN(result[0]) || Double.isNaN(result[1])) { + throw new IllegalArgumentException("鍧愭爣杞崲澶辫触锛屽彲鑳芥槸鍧愭爣绯讳笉鍏煎"); + } + + return result; + } finally { + // 纭繚璧勬簮琚噴鏀� + if (ct != null) ct.delete(); + if (targetSRS != null) targetSRS.delete(); + if (sourceSRS != null) sourceSRS.delete(); + } + } + + public static void main(String[] args) { + try { + double[] result1 = transform(4326, 32650, 116.4074, 39.9042); // 鍖椾含 + System.out.printf("WGS84 -> UTM 50N: (%.6f, %.6f, %.2f)%n", + result1[0], result1[1], result1[2]); + + double[] result2 = transform(4326, 3857, 116.4074, 39.9042); // 鍖椾含 + System.out.printf("WGS84 -> Web Mercator: (%.6f, %.6f, %.2f)%n", + result2[0], result2[1], result2[2]); + + // 浣跨敤閫傚悎NAD83 California zone 5鐨勫潗鏍� + double[] result3 = transform(4326, 26945, -122.4194, 37.7749); // 鏃ч噾灞� + System.out.printf("WGS84 -> NAD83 California zone 5: (%.6f, %.6f, %.2f)%n", + result3[0], result3[1], result3[2]); + + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/se/nsl/utils/ZarrReader.java b/src/main/java/com/se/nsl/utils/ZarrReader.java new file mode 100644 index 0000000..3d38e1f --- /dev/null +++ b/src/main/java/com/se/nsl/utils/ZarrReader.java @@ -0,0 +1,112 @@ +package com.se.nsl.utils; + +import org.gdal.gdal.Dataset; +import org.gdal.gdal.Driver; +import org.gdal.gdal.gdal; +import org.gdal.gdalconst.gdalconstConstants; + +public class ZarrReader { + + static { + // 娉ㄥ唽GDAL椹卞姩 + try { + gdal.AllRegister(); + } catch (Exception e) { + System.err.println("GDAL椹卞姩娉ㄥ唽澶辫触: " + e.getMessage()); + } + } + + /** + * 璇诲彇Zarr鏁版嵁闆嗗苟鎵撳嵃鍩烘湰淇℃伅 + * @param zarrPath Zarr鏁版嵁闆嗚矾寰勶紙鏈湴璺緞鎴朥RL锛� + */ + public static void readZarr(String zarrPath) { + // 鎵撳紑Zarr鏁版嵁闆� + Driver driver = gdal.GetDriverByName("Zarr"); + if (driver == null) { + System.out.println("zarr椹卞姩涓嶅彲鐢�"); + } + Dataset dataset = gdal.Open(zarrPath, gdalconstConstants.GA_ReadOnly); + + + if (dataset == null) { + System.err.println("鏃犳硶鎵撳紑Zarr鏁版嵁闆�: " + zarrPath); + System.err.println(gdal.GetLastErrorMsg()); + return; + } + + try { + // 鎵撳嵃鏁版嵁闆嗗熀鏈俊鎭� + System.out.println("鏁版嵁闆嗕俊鎭�:"); + System.out.println(" 椹卞姩: " + dataset.GetDriver().getShortName()); + System.out.println(" 瀹藉害: " + dataset.GetRasterXSize() + " 鍍忕礌"); + System.out.println(" 楂樺害: " + dataset.GetRasterYSize() + " 鍍忕礌"); + System.out.println(" 娉㈡鏁�: " + dataset.GetRasterCount()); + + // 鑾峰彇鍦扮悊鍙樻崲鍙傛暟 + double[] geoTransform = dataset.GetGeoTransform(); + if (geoTransform != null && geoTransform.length >= 6) { + System.out.println(" 鍦扮悊鍙樻崲鍙傛暟:"); + System.out.printf(" 宸︿笂瑙扻: %.6f%n", geoTransform[0]); + System.out.printf(" 宸︿笂瑙扽: %.6f%n", geoTransform[3]); + System.out.printf(" X鏂瑰悜鍒嗚鲸鐜�: %.6f%n", geoTransform[1]); + System.out.printf(" Y鏂瑰悜鍒嗚鲸鐜�: %.6f%n", geoTransform[5]); + } + + // 鑾峰彇鎶曞奖淇℃伅 + String projection = dataset.GetProjection(); + if (projection != null && !projection.isEmpty()) { + System.out.println(" 鎶曞奖淇℃伅: " + projection.substring(0, Math.min(100, projection.length())) + "..."); + } + + // 璇诲彇绗竴涓尝娈电殑鏁版嵁 + if (dataset.GetRasterCount() > 0) { + int width = dataset.GetRasterXSize(); + int height = dataset.GetRasterYSize(); + float[] buffer = new float[width * height]; + + // 璇诲彇娉㈡鏁版嵁 + dataset.GetRasterBand(1).ReadRaster(0, 0, width, height, buffer); + + // 缁熻鍩烘湰淇℃伅 + float min = Float.MAX_VALUE; + float max = Float.MIN_VALUE; + float sum = 0; + int validCount = 0; + + for (float value : buffer) { + if (!Float.isNaN(value) && !Float.isInfinite(value)) { + min = Math.min(min, value); + max = Math.max(max, value); + sum += value; + validCount++; + } + } + + if (validCount > 0) { + float mean = sum / validCount; + System.out.printf(" 绗竴涓尝娈电粺璁′俊鎭�: 鏈�灏忓��=%.2f, 鏈�澶у��=%.2f, 骞冲潎鍊�=%.2f%n", min, max, mean); + } + } + + } catch (Exception e) { + System.err.println("璇诲彇Zarr鏁版嵁鏃跺彂鐢熼敊璇�: " + e.getMessage()); + e.printStackTrace(); + } finally { + // 閲婃斁璧勬簮 + if (dataset != null) { + dataset.delete(); + } + } + } + + public static void main(String[] args) { + // 绀轰緥Zarr鏁版嵁闆嗚矾寰� - 璇锋浛鎹负瀹為檯璺緞 +// String zarrPath = "C:\\Users\\Deng\\Desktop\\just_test\\result.zarr"; + String zarrPath = "D:\\other\\simu\\uwsolver\\20250516174452\\result.zarr"; + + // 璇诲彇骞舵墦鍗癦arr淇℃伅 + readZarr(zarrPath); + + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index a65cbba..9196b5e 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -141,14 +141,18 @@ flowUnits: CMS solverBat: D:\other\simu\uwsolver\run_solver.bat sww2tifBat: D:\other\simu\uwsolver\sww2tif.bat - uwSolverBat: D:\other\simu\CudaUWSolver.Demo.NoVis.20250430\start.bat + uwSolverBat: D:\other\simu\CudaUWSolver-2.0\start.bat +# uwSolverBat: D:\other\simu\CudaUWSolver.Demo.NoVis.20250430\start.bat + zarr2tifBat: D:\other\simu\zarr2tif-2.1\start.bat # zarr2tifBat: D:\other\simu\zarr2tif1.0\start.bat - zarr2tifBat: D:\other\simu\zarr2tif-2.0-mkl\start.bat +# zarr2tifBat: D:\other\simu\zarr2tif-2.0-mkl\start.bat createRainfall: '"C:\Program Files\Python310\python.exe" D:\terrait\NslServer\data\CreatRainfall.py' rainfallTitle: Station Longitude Latitude Year Month Day Hour Minute Intensity rainfallSite: beijing epsg: 4548 - saveFrames: 10 + saveFrames: 3 + #鐢熸垚甯ф暟鐨勯棿闅旀椂闂达紝鍗曚綅鏄垎閽燂紝璁剧疆涓�5琛ㄧず姣忛殧5鍒嗛挓鐢熸垚涓�甯� + saveFrameInterval: 5 # 鍦熷湴鍒╃敤锛�1-Cropland,2-Forest,3-Shrub,4-Grassland,5-Water,6-Snow/Ice,7-Barren,8-Impervious,9-Wetland landuse: 2 #sizes: 64,128,256,512,1024,2048,4096 @@ -160,5 +164,8 @@ buildingKey: KJSFBM waterPath: depth flowPath: velocity + landuseFile: Landuse.tif + sourceDem: D:\other\simu\CudaUWSolver-2.0\Beijing-Data-10m\Beijing-4548-ASTERDEMV3-10m.tif + sourceLanduse: D:\other\simu\CudaUWSolver-2.0\Beijing-Data-10m\Beijing-4548-Landuse-10m-Nonodata.tif copyTif: false tifPath: D:\other\simu\uwsolver\5ca43c87cd8e48c5a9c5399a5da46dbc\tongzhou_raster_4548_1m_clip_river_fill.tif -- Gitblit v1.9.3