Hua 2 maanden geleden
bovenliggende
commit
4c3640ec92

+ 2 - 2
ruoyi-ui/.env.development

@@ -10,8 +10,8 @@ VITE_APP_BASE_Title = '/sh'
 # 若依管理系统/生产环境
 VITE_APP_BASE_API = '/sh-api'
 
-# VITE_DEV_PATH = 'http://localhost:8082'
-VITE_DEV_PATH = 'http://192.168.2.104:8082'
+VITE_DEV_PATH = 'http://localhost:8082'
+# VITE_DEV_PATH = 'http://192.168.2.104:8082'
 
 # 是否在打包时开启压缩,支持 gzip 和 brotli
 VITE_BUILD_COMPRESS = gzip

+ 7 - 0
ruoyi-ui/src/api/standardization/bizDataShowConfig.js

@@ -50,3 +50,10 @@ export function getBizDataByConfig(config) {
     })
 }
 
+export function getForecastlist(query) {
+    return request({
+        url: '/forecast/plan/list',
+        method: 'get',
+        params: query
+    })
+}

+ 247 - 11
ruoyi-ui/src/views/map/components/map.vue

@@ -1,5 +1,21 @@
 <template>
   <div class="map-index">
+    <div ref="scrollContainer" v-if="route.params.id=='28'" style="background-color: white;position: absolute;z-index: 9999;top: 1%;left: 1%;width: 10vw;height: 50vh;overflow:auto;">
+      <el-timeline style="padding-top: 5%;padding-left: 5%;">
+        <el-timeline-item
+          v-for="(activity, index) in activities"
+          :key="index"
+          :icon="activity.icon"
+          :type="activity.type"
+          :color="activity.color"
+          :size="activity.size"
+          :hollow="activity.hollow"
+          :timestamp="activity.timestamp"
+        >
+          {{ activity.content }}
+        </el-timeline-item>
+      </el-timeline>
+    </div>
     <div id="mapChart"></div>
   </div>
 </template>
@@ -12,7 +28,7 @@ import TileLayer from "ol/layer/Tile";
 import VectorLayer from "ol/layer/Vector";
 import Overlay from 'ol/Overlay';
 import {XYZ} from 'ol/source';
-
+import Point from 'ol/geom/Point';
 import {createDynamicStyle} from "@/views/map/utils/styleParser.js";
 import {loadSource} from "../hooks/dataSourceManager.js";
 import bus from "@/utils/bus.js";
@@ -24,29 +40,94 @@ import 'ol/ol.css';
 import VectorSource from 'ol/source/Vector';
 import OSM from 'ol/source/OSM';
 import Feature from 'ol/Feature';
-import { Style, Fill, Stroke, Text, Circle } from 'ol/style';
+import { Style, Fill, Stroke, Text, Circle,Icon,RegularShape } from 'ol/style';
 import { fromLonLat } from 'ol/proj';
 import GeoJSON from 'ol/format/GeoJSON';
 import jsonDatak5 from "./kaixuan5.json";
 import jsonDatal3 from "./laixuan3.json";
 import jsonDatakw from "./wanhang.json";
 import jsonDatakw3 from "./wanhang3.json";
+import suzhouJson from "./suzhou.json";
+import {useRoute} from "vue-router";
+import suzhouPoint from "./suzhouPoints.json";
+import { ref } from 'vue';
+
+const scrollContainer = ref(null);
+const scrollAmount = 50; 
+const route = useRoute();
 const props = defineProps({
   config: Object,
 });
-
 const mapChart = ref(null);
 // 存储弹窗的引用
 const popupOverlays = ref([]);
-
+const activities =ref( [
+])
 onMounted(async () => {
   await initMap();
   // 初始化完成后执行配置渲染
+  if(route.params.id==='25'){
+    polygonLayer.value = createPolygonLayer(jsonDatak5)
+    mapChart.value.addLayer(polygonLayer.value);
+  }
+  if(route.params.id==='28'){
+    const keys = Object.keys(suzhouJson.data.outPutQUZ)
+    keys.forEach(item=>{
+      var par = {
+        content: '',
+        timestamp: item,
+        size: 'large',
+        type: 'primary',
+      }
+      activities.value.push(par)
+    })
+    suzhouJson.data.inputParam = JSON.parse(suzhouJson.data.inputParam)
+    console.log(suzhouJson.data)
+    setInterval(changeMap, 2000)
+    pointLayer.value = createPointlayer(suzhouPoint)
+    mapChart.value.addLayer(pointLayer.value);
+    
+  }
   if (props.config) {
     // toCenter(props.config.center, props.config.zoom);
     await loadLayers(props.config.layers);
   }
 });
+const count = ref(0)
+function changeMap(){
+  
+  const keys1 = Object.keys(suzhouJson.data.outPutQUZ)
+  console.log(count.value,keys1.length)
+  if(count.value >= keys1.length){
+    console.log(count.value,keys1.length)
+    count.value = 0
+    scrollContainer.value.scrollTo({
+      top: 0, // 滚动到顶部
+      behavior: 'smooth' // 启用平滑滚动效果
+    });
+  }
+  activities.value.forEach(item=>{
+    item.content = ''
+    item.color = ''
+  })
+  activities.value[count.value].content = '当前展示时间'
+  activities.value[count.value].color = '#0bbd87',
+  mapChart.value.removeLayer(pointLayer.value)
+  const keys = Object.keys(suzhouJson.data.outPutQUZ)
+  for(var i = 0;i<suzhouPoint.length;i++){
+    for(var i1 = 0;i1<suzhouJson.data.outPutQUZ[keys[count.value]].length;i1++){
+      if(suzhouPoint[i].STATIONNAME===suzhouJson.data.outPutQUZ[keys[count.value]][i1].name){
+        suzhouPoint[i].ZZ = suzhouJson.data.outPutQUZ[keys[count.value]][i1].z
+      }
+    }
+  }
+  pointLayer.value = createPointlayer(suzhouPoint)
+  mapChart.value.addLayer(pointLayer.value);
+  if(count.value >=10){
+    scrollContainer.value.scrollTop += scrollAmount;
+  }
+  count.value++
+}
 function createPolygonLayer(jsonData){
   var parData = []
   if(Array.isArray(jsonData)){
@@ -62,7 +143,7 @@ function createPolygonLayer(jsonData){
       "type": "FeatureCollection",
       "features": parData
     };
-
+    console.log(parData)
     // 创建矢量数据源并加载GeoJSON多边形数据[3,4](@ref)
     const vectorSource = new VectorSource({
       features: new GeoJSON().readFeatures(polygonGeoJSON, {
@@ -70,7 +151,6 @@ function createPolygonLayer(jsonData){
         featureProjection: 'EPSG:4326'
       })
     });
-
     // 创建多边形要素样式[6,7](@ref)
     const polygonStyle = new Style({
       fill: new Fill({
@@ -81,19 +161,175 @@ function createPolygonLayer(jsonData){
         width: 2           // 边框宽度
       })
     });
+    const styleFunction = function(feature) {
+      const properties = feature.getProperties();
+      if (properties.DEPTH2D >= 1) {
+        return new Style({
+          fill: new Fill({
+            color: 'rgba(255, 0, 0, 0.5)'
+          }),
+          stroke: new Stroke({
+            color: '#ff0000',
+            width: 3
+          })
+        });
+      }
+      else if (properties.DEPTH2D < 1&&properties.DEPTH2D>=0.5) {
+        return new Style({
+          fill: new Fill({
+            color: 'rgb(238, 190, 119)' 
+          }),
+          stroke: new Stroke({
+            color: '#ff0000',
+            width: 3
+          })
+        });
+      }
+      else if (properties.DEPTH2D < 0.5&&properties.DEPTH2D>=0.3) {
+        return new Style({
+          fill: new Fill({
+            color: 'rgb(238, 190, 119)' 
+          }),
+          stroke: new Stroke({
+            color: '#ff0000',
+            width: 3
+          })
+        });
+      }
+      else if (properties.DEPTH2D < 0.3&&properties.DEPTH2D>=0.25) {
+        return new Style({
+          fill: new Fill({
+            color: 'rgb(238, 190, 119)' 
+          }),
+          stroke: new Stroke({
+            color: '#ff0000',
+            width: 3
+          })
+        });
+      }
+      else if (properties.DEPTH2D < 0.25&&properties.DEPTH2D>=0.2) {
+        return new Style({
+          fill: new Fill({
+            color: 'rgb(121, 187, 255)' 
+          }),
+          stroke: new Stroke({
+            color: '#ff0000',
+            width: 3
+          })
+        });
+      }
+      else if (properties.DEPTH2D < 0.2&&properties.DEPTH2D>=0.15) {
+        return new Style({
+          fill: new Fill({
+            color: 'rgb(198, 226, 255)' 
+          }),
+          stroke: new Stroke({
+            color: '#ff0000',
+            width: 3
+          })
+        });
+      }
+      // 默认样式
+      return new Style({
+        fill: new Fill({
+          color: 'rgb(51, 126, 204)'  // 半透明蓝色填充
+        }),
+        stroke: new Stroke({
+          color: '#0066ff',  // 蓝色边框
+          width: 2           // 边框宽度
+        })
+      });
+    };
 
     // 创建矢量图层[1,2](@ref)
     return new VectorLayer({
       source: vectorSource,
-      style: polygonStyle
+      style: styleFunction
     });
   }
 }
-
+function createStationStyle(station) {
+  // 根据水位值设置颜色[7](@ref)
+  let color = '#3399CC'; // 默认蓝色
+  if (station.ZZ > 5.0) {
+    color = '#FF6B6B'; // 高水位用红色
+  } else if (station.ZZ < 4.5) {
+    color = '#4ECDC4'; // 低水位用绿色
+  }
+  
+  return new Style({
+    image: new RegularShape({
+      points: 3, // 三角形
+      radius: 8, // 大小
+      fill: new Fill({
+        color: '#FF5722' // 红色填充
+      }),
+      stroke: new Stroke({
+        color: '#fff', // 白色边框
+        width: 2
+      }),
+      angle: Math.PI // 旋转180度,使三角形倒置[1,4](@ref)
+    }),
+    text: new Text({
+      text: station.STATIONNAME + '\n水位: ' + station.ZZ + 'm',
+      offsetY: 20,
+      font: '12px Microsoft YaHei, sans-serif',
+      fill: new Fill({
+        color: '#333'
+      }),
+      stroke: new Stroke({
+        color: '#fff',
+        width: 1
+      }),
+      backgroundFill: new Fill({
+        color: 'transparent'
+      }),
+      padding: [2, 4, 2, 4]
+    })
+  });
+} 
+function createPointlayer(dataJson){
+  const vectorSource = new VectorSource();
+  
+  // 为每个水文站创建要素[2,3](@ref)
+  dataJson.forEach(station => {
+    // 使用经纬度坐标创建点要素[5](@ref)
+    const feature = new Feature({
+      geometry: new Point([station.XX2000, station.YY2000]),
+      name: station.STATIONNAME,
+      waterLevel: station.ZZ,
+      area: station.QUYU,
+      river: station.HELIU,
+      type: station.TYPE,
+      stationId: station.STATIONID
+    });
+    
+    // 设置样式(根据水位值动态设置颜色)
+    const style = createStationStyle(station);
+    feature.setStyle(style);
+    vectorSource.addFeature(feature);
+  });
+  
+  // 创建矢量图层[1,4](@ref)
+  const vectorLayer = new VectorLayer({
+    source: vectorSource,
+    // 可以设置图层属性便于后续管理
+    properties: {
+      name: 'hydrologicalStations',
+      type: 'vector'
+    }
+  });
+  
+  // 将图层添加到地图
+  
+  
+  return vectorLayer;
+}
   // 创建多边形图层
+const pointLayer = ref(null)
 const polygonLayer = ref(null)
 const initMap = () => {
-  polygonLayer.value = createPolygonLayer(jsonDatak5)
+  
   let vecLayer = new TileLayer({
     source: new XYZ({
       url: "http://t0.tianditu.gov.cn/vec_w/wmts?" +
@@ -120,7 +356,7 @@ const initMap = () => {
       maxZoom: 16,
       projection: 'EPSG:4326',
     }),
-    layers: [vecLayer, cvaLayer,polygonLayer.value],
+    layers: [vecLayer, cvaLayer],
     controls: defaultControls({
       zoom: false,//不显示放大放小按钮
       rotate: false,//不显示指北针控件
@@ -385,7 +621,7 @@ watch(() => props.config, async (config) => {
   if (config) {
     // 渲染配置
     // 1. 跳转中心点
-    toCenter(config.center, config.zoom);
+    // toCenter(config.center, config.zoom);
     // 渲染图层
     await loadLayers(config.layers);
   }

File diff suppressed because it is too large
+ 0 - 0
ruoyi-ui/src/views/map/components/suzhou.json


+ 126 - 0
ruoyi-ui/src/views/map/components/suzhouPoints.json

@@ -0,0 +1,126 @@
+[
+    {
+        "Column0": 0,
+        "XX": 1879.0959375,
+        "YY": 840.2012500000001,
+        "ZZ": 6.2,
+        "YY2000": 31.2431,
+        "QUYU": "黄浦区",
+        "STATIONID": "SW63401500",
+        "SQTYPE": "因特网;中心城区;苏州河;上海市;防汛代表站;中心城区防汛代表站",
+        "XX2000": 121.4867,
+        "HELIU": "黄浦江",
+        "SLP": "中心城区",
+        "STATIONNAME": "黄浦公园",
+        "DATASOURCE": "市水文总站",
+        "TYPE": "实时水位"
+    },
+    {
+        "Column0": 2,
+        "XX": -22031.2975,
+        "YY": -30029.475000000002,
+        "ZZ": 4.2,
+        "YY2000": 30.9644,
+        "QUYU": "松江区",
+        "STATIONID": "SW63401100",
+        "SQTYPE": "因特网;上海市;防汛代表站",
+        "XX2000": 121.2365,
+        "HELIU": "黄浦江",
+        "SLP": "青松片",
+        "STATIONNAME": "米市渡",
+        "DATASOURCE": "市水文总站",
+        "TYPE": "实时水位"
+    },
+    {
+        "Column0": 156,
+        "XX": -7405.0293,
+        "YY": -27400.9061,
+        "YY2000": 30.9885,
+        "QUYU": "奉贤区",
+        "STATIONID": "SW63404400",
+        "SQTYPE": "防汛代表站;因特网;上海市",
+        "XX2000": 121.3902,
+        "HELIU": "黄浦江",
+        "SLP": "浦东片",
+        "STATIONNAME": "沙港(二)",
+        "DATASOURCE": "市水文总站",
+        "TYPE": "实时水位;风速风向"
+    },
+    {
+        "Column0": 284,
+        "XX": -15423.5095,
+        "YY": -29490.0059,
+        "YY2000": 30.9695,
+        "QUYU": "松江区",
+        "STATIONID": "SW63401120",
+        "SQTYPE": "上海市",
+        "XX2000": 121.3063,
+        "HELIU": "黄浦江",
+        "SLP": "浦南东片",
+        "STATIONNAME": "松浦大桥",
+        "DATASOURCE": "市水文总站",
+        "TYPE": "实时水位;土壤墒情;流量监测"
+    },
+    {
+        "Column0": 287,
+        "XX": -45307.3132,
+        "YY": -16856.2149,
+        "YY2000": 31.0827,
+        "QUYU": "青浦区",
+        "STATIONID": "SW63402950",
+        "SQTYPE": "上海市",
+        "XX2000": 120.9929,
+        "HELIU": "拦路港",
+        "SLP": "青松片",
+        "STATIONNAME": "河祝",
+        "DATASOURCE": "市水文总站",
+        "TYPE": "实时水位;土壤墒情"
+    },
+    {
+        "Column0": 287,
+        "XX": -45307.3132,
+        "YY": -16856.2149,
+        "YY2000": 31.0827,
+        "QUYU": "青浦区",
+        "STATIONID": "SW63402950",
+        "SQTYPE": "上海市",
+        "XX2000": 120.9929,
+        "HELIU": "拦路港",
+        "SLP": "青松片",
+        "STATIONNAME": "河祝",
+        "DATASOURCE": "市水文总站",
+        "TYPE": "实时水位;土壤墒情"
+    },
+    {
+        "Column0": 257,
+        "XX": -40186.2201,
+        "YY": -20297.0102,
+        "YY2000": 31.0519,
+        "QUYU": "青浦区",
+        "STATIONID": "SW63403100",
+        "OUTWATER": 2.71,
+        "SQTYPE": "因特网;上海市;防汛代表站",
+        "XX2000": 121.0467,
+        "HELIU": "拦路港",
+        "SLP": "太北片",
+        "STATIONNAME": "泖甸",
+        "DATASOURCE": "市水文总站",
+        "TYPE": "实时水位"
+    },
+    {
+        "Column0": 286,
+        "XX": -29975.9195,
+        "YY": -29147.8266,
+        "YY2000": 30.9723,
+        "QUYU": "松江区",
+        "STATIONID": "SW63402700",
+        "OUTWATER": 2.37,
+        "SQTYPE": "上海市",
+        "XX2000": 121.1539,
+        "HELIU": "斜塘",
+        "SLP": "太南片",
+        "STATIONNAME": "夏字圩",
+        "DATASOURCE": "市水文总站",
+        "TYPE": "实时水位;土壤墒情"
+    }
+]

+ 57 - 30
ruoyi-ui/src/views/standardization/bizDataShowConfig/show/GwTableTwo.vue

@@ -1,10 +1,23 @@
 <template>
   <div class="descriptions-container">
-    <el-descriptions :column="columnNumber" border>
+    <!-- <el-descriptions :column="columnNumber" border>
       <el-descriptions-item v-for="(item, index) in data" :key="index" :label="item.name">
         {{ item.value ? item.value : '-' }}
       </el-descriptions-item>
-    </el-descriptions>
+    </el-descriptions> -->
+    <el-table
+        :data="data"
+        height="14vh"
+        :cell-style="{ padding: '5px' }"
+        :row-style="{ fontSize: '1rem', textAlign:'center' }"
+        border>
+      <el-table-column align="center" width="" prop="planName" label="方案名称"></el-table-column>
+      <el-table-column align="center" width="" prop="updateTime" label="更新时间">
+        <template #default="scope">
+
+        </template>
+      </el-table-column>
+    </el-table>
   </div>
   <!--  <table class="gw-descriptions-table">-->
   <!--    <tbody>-->
@@ -29,37 +42,51 @@
   <!--    </tr>-->
   <!--    </tbody>-->
   <!--  </table>-->
+    
 </template>
 <script setup>
+import {
+  getForecastlist
+} from "@/api/standardization/bizDataShowConfig.js";
+import {useRoute} from "vue-router";
+const data = ref()
+const route = useRoute();
+function getYu(){
+  getForecastlist({appId: route.params.id}).then(res=>{
+    data.value = res.rows
+  })
+}
+onMounted(() => {
+  getYu();
+});
+// const props = defineProps({
+//   data: {
+//     type: Array,
+//     default: [],
+//   },
+//   columnNumber: {
+//     type: Number,
+//     default: 3,
+//   },
+// })
 
-const props = defineProps({
-  data: {
-    type: Array,
-    default: [],
-  },
-  columnNumber: {
-    type: Number,
-    default: 3,
-  },
-})
+// const row = computed(() => {
+//   return (num) => {
+//     let start = (num - 1) * props.columnNumber;
+//     let end = num * props.columnNumber;
+//     // if (end >= props.data.length && props.data.length > 1) {
+//     //   end = -1;
+//     // }
+//     return props.data.slice(start, end);
+//   }
+// })
 
-const row = computed(() => {
-  return (num) => {
-    let start = (num - 1) * props.columnNumber;
-    let end = num * props.columnNumber;
-    // if (end >= props.data.length && props.data.length > 1) {
-    //   end = -1;
-    // }
-    return props.data.slice(start, end);
-  }
-})
-
-const rowNumber = computed(() => {
-  if (props.data) {
-    return Math.ceil(props.data.length / props.columnNumber);
-  }
-  return 0;
-})
+// const rowNumber = computed(() => {
+//   if (props.data) {
+//     return Math.ceil(props.data.length / props.columnNumber);
+//   }
+//   return 0;
+// })
 </script>
 <style lang="scss" scoped>
 .descriptions-container {
@@ -129,4 +156,4 @@ const rowNumber = computed(() => {
   }
 
 }
-</style>
+</style>

Some files were not shown because too many files changed in this diff