Procházet zdrojové kódy

feat(bd): 优化地图组件和室内定位功能

- 为地图组件添加 mapId 属性,支持自定义地图容器 ID
- 在地图加载时添加 3D Tiles 层,增强地图展示效果
- 优化围栏和事件相关的地图展示逻辑
- 重构室内定位功能,支持自定义图层样式
- 优化点融合算法,增加地点相同性判断
chen.cheng před 9 měsíci
rodič
revize
d6f479cba8

+ 5 - 3
bd-location/src/main/java/com/ruoyi/bd/service/engine/impl/PointFusionEngine.java

@@ -50,6 +50,7 @@ public class PointFusionEngine extends EvtFusionEngine {
     private PointWebSocketServer webSocketServer;
 
     private final List<LinkedBlockingQueue<JSONObject>> messageQueueList = new ArrayList<>(5);
+
     @PostConstruct
     public void init() {
         super.init();
@@ -61,9 +62,9 @@ public class PointFusionEngine extends EvtFusionEngine {
         long gap = newer.getSrcTimestamp() - older.getSrcTimestamp();
         // 将gap 转换为秒
         gap = gap / 1000;
-        return gap <= MAX_POINT_TIME_GAP;
+        boolean isSamePoint = Double.compare(older.getLatitude(), newer.getLatitude()) == 0 && Double.compare(older.getLongitude(), newer.getLongitude()) == 0;
+        return gap <= MAX_POINT_TIME_GAP && isSamePoint;
     }
-
     @Override
     public String getKey(LocationInfo msg) {
         return BDConst.REDIS_KEY.BD_POINT_KEY + msg.getMsg().getString("deviceId");
@@ -73,6 +74,7 @@ public class PointFusionEngine extends EvtFusionEngine {
     public List<LinkedBlockingQueue<JSONObject>> getQueue() {
         return messageQueueList;
     }
+
     @Override
     public void getBizId(LocationInfo msg) {
         long evtTimestamp = msg.getEvtTimestamp();
@@ -92,7 +94,7 @@ public class PointFusionEngine extends EvtFusionEngine {
         webSocketServer.sendInfo(msg.getMsg().getString("deviceId"), msg.getMsg().toJSONString());
     }
 
-    public void  pushDevcLocation(LocationInfo msg) {
+    public void pushDevcLocation(LocationInfo msg) {
         webSocketServer.sendInfo(msg.getMsg().getString("deviceId"), msg.getMsg().toJSONString());
     }
 }

+ 12 - 0
ruoyi-ui/src/views/bd/fence/index.vue

@@ -170,6 +170,12 @@ export default {
         const polygon = this.custDrawPoly({
           name: defenceName,
           coordinates: this.polygonToCoordinates(poly),
+          symbol: {
+            lineColor: 'rgba(241,0,23,0.49)',
+            lineWidth: 2,
+            polygonFill: 'rgba(241,0,23,0.49)',
+            polygonOpacity: 0.4,
+          },
           bizAttr: {
             id,
             name: defenceName,
@@ -228,6 +234,12 @@ export default {
           this.drawtool.clear();
           const polygon = this.drawPoly({
             coordinates: coordinates,
+            symbol: {
+              lineColor: 'rgba(241,0,23,0.49)',
+              lineWidth: 2,
+              polygonFill: 'rgba(241,0,23,0.49)',
+              polygonOpacity: 0.4,
+            },
             labelSymbol: {
               labelText: this.form.name,
             },

+ 6 - 0
ruoyi-ui/src/views/bd/fenceEvt/index.vue

@@ -110,6 +110,12 @@ export default {
         const polygon = this.drawPoly({
           name: defenceName,
           coordinates: this.polygonToCoordinates(poly),
+          symbol: {
+            lineColor: 'rgba(241,0,23,0.49)',
+            lineWidth: 2,
+            polygonFill: 'rgba(241,0,23,0.49)',
+            polygonOpacity: 0.4,
+          },
           bizAttr: {
             id,
             name: defenceName,

+ 18 - 0
ruoyi-ui/src/views/bd/index.vue

@@ -85,7 +85,25 @@ export default {
   },
   methods: {
     loaded(map) {
+      window.map = this.mapView;
       this.mapLoaded = true;
+      const d3tiles = new BDLayers.Lib.Layer.CB3DtilesLayer('3dtiles', {
+        offet: {
+          from: 'GCJ02',
+          to: 'WGS84',
+        },
+        offset: [13.4, -3.5],
+        mapView: this.mapView,
+        maxCacheSize: 10000,
+        services: [
+          {
+            url: `${process.env.VUE_APP_DOMAIN_BASE_URL}${process.env.VUE_APP_BD_BASE_API}/folder/zy9/tileset.json`, //"http://resource.dvgis.cn/data/3dtiles/dayanta/tileset.json",
+            maximumScreenSpaceError: 16.0,
+            heightOffset: -48, //-420,
+          },
+        ],
+      });
+      map.addCustomLayers(d3tiles, -1, true);
     },
     menuClick(e) {
       const type = e.currentTarget.dataset.type;

+ 8 - 22
ruoyi-ui/src/views/bd/map/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div id="map" class="map" style="width: 100%;height: 100%">
+  <div :id="mapId" class="map" style="width: 100%;height: 100%">
 
   </div>
 </template>
@@ -9,6 +9,10 @@
 export default {
   name: 'bd-map',
   props: {
+    mapId: {
+      type: String,
+      default: 'map',
+    },
     loaded: {
       type: Function,
       default: () => {},
@@ -20,7 +24,7 @@ export default {
       const options = {
         mapType: BDLayers.Lib.Constant.BaseLayerType.Blank,
         mapModel: BDLayers.Lib.Constant.BaseLayerModel.Satellite,
-        center: [118.8738802982145,32.010241883966096],
+        center: [118.8738802982145, 32.010241883966096],
         defaultZoom: 15,
         showCenter: false,
         baseControl: true,
@@ -37,8 +41,8 @@ export default {
           },
         },
       };
-      bdmap.mapWrapper.loadMainMap('map', options);
-      this.mapView = bdmap.mapWrapper.MainMap('map');
+      bdmap.mapWrapper.loadMainMap(this.mapId, options);
+      this.mapView = bdmap.mapWrapper.MainMap(this.mapId);
       this.mapView.createGLScense({
         sceneConfig: {
           environment: {
@@ -71,22 +75,6 @@ export default {
         },
       });
       // http://200.200.19.253:31838/bdgis/folder/zy9?time=1728373968099
-      const d3tiles = new BDLayers.Lib.Layer.CB3DtilesLayer('3dtiles', {
-        offet: {
-          from: 'GCJ02',
-          to: 'WGS84',
-        },
-        offset:[13.4,-3.5],
-        mapView: this.mapView,
-        maxCacheSize: 10000,
-        services: [
-          {
-            url: `${process.env.VUE_APP_DOMAIN_BASE_URL}${process.env.VUE_APP_BD_BASE_API}/folder/zy9/tileset.json`, //"http://resource.dvgis.cn/data/3dtiles/dayanta/tileset.json",
-            maximumScreenSpaceError: 16.0,
-            heightOffset: -48, //-420,
-          },
-        ],
-      });
       const satelliteTileLayer = new BDLayers.Lib.Layer.CBTileLayer('blayer_tdt_s', {
         url: [
           'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=' + BDLayers.Lib
@@ -99,8 +87,6 @@ export default {
         minZoom: [3, 3],
       });
       this.mapView.addCustomLayers(satelliteTileLayer, -1, true);
-      // this.mapView.addCustomLayers(d3tiles, -1, true);
-      window.map = this.mapView;
       this.loaded(this.mapView);
     });
   },

+ 17 - 12
ruoyi-ui/src/views/bd/map/maphandle.js

@@ -19,25 +19,30 @@ export default {
     drawPoly({
       name = '多边形',
       coordinates,
+      altitude = 0,
       symbol = {},
       bizAttr = {},
       labelSymbol = {},
       polyOnClick = () => {},
     }) {
+      let symbolParam = {
+        lineColor: '#34495e',
+        lineWidth: 2,
+        polygonFill: '#1bbc9b',
+        polygonOpacity: 0.4,
+      };
+      let labelSymbolParam = {
+        labelText: name,
+        labelTextColor: '#fefefe',
+        labelTextSize: 15,
+      };
+      Object.assign(labelSymbolParam, labelSymbol);
+      Object.assign(symbolParam, symbol);
       const polygon = new BDLayers.Lib.Overlays.Polygon('p1', {
         coordinates: coordinates,
-        altitude: 0,
-        symbol: Object.assign({
-          lineColor: '#34495e',
-          lineWidth: 2,
-          polygonFill: '#1bbc9b',
-          polygonOpacity: 0.4,
-        }, symbol),
-        labelSymbol: Object.assign({
-          labelText: name,
-          labelColor: '#fefefe',
-          labelTextSize: 20,
-        }, labelSymbol),
+        altitude,
+        symbol: symbolParam,
+        labelSymbol: labelSymbolParam,
         bizAttr: bizAttr,
       });
       //多边形的点击事件

binární
ruoyi-ui/src/views/bd/roomlocation/icon/room_location.jpg


+ 64 - 105
ruoyi-ui/src/views/bd/roomlocation/index.vue

@@ -1,20 +1,17 @@
 <template>
-  <pannel class="fence-location-container">
+  <pannel class="rooms-container">
     <template v-slot:title>
-      围栏闯禁事件
+      室内定位
     </template>
     <template v-slot:action>
 
     </template>
     <template v-slot:content>
       <div class="location-list">
-        <template v-for="evt in evtList">
-          <div :key="`evt_${evt.id}`" class="list-item">
-          <span class="over-flow-hidden" style="width: 40%">
-            {{ evt.evtDesc }}
-          </span>
-            <span class="over-flow-hidden" style="width: 40%">
-           {{ dayjs(evt.evtTime).format('YYYY-MM-DD HH:mm') }}
+        <template v-for="room in roomList">
+          <div :key="`room_${room.id}`" class="list-item">
+          <span class="over-flow-hidden" style="width: 80%">
+            {{ room.room }}
           </span>
             <span class="over-flow-hidden" style="width: 20%">
           </span>
@@ -28,14 +25,12 @@
 
 <script>
 
-import { listFenceInfo } from '@/api/bd/fenceInfo';
-import { listFenceVioEvt } from '@/api/bd/fenceVioEvt';
 import SocketMessage from '@/components/WebsocketMessage/index.vue';
+import { uuid } from '@/utils';
 import maphandle from '@/views/bd/map/maphandle';
 import Pannel from '@/views/bd/pannel/index.vue';
-import FingerprintJS from '@fingerprintjs/fingerprintjs';
 import dayjs from 'dayjs';
-import evt_vio from './icon/evt_vio.svg';
+import room_location from './icon/room_location.jpg';
 
 export default {
   name: 'room-location',
@@ -46,113 +41,78 @@ export default {
   },
   data() {
     return {
-      evtList: [],
+      roomList: [],
       fp: null,
       ws: null,
       markLayer: null,
+      markLayerId: '',
     };
   },
   // 组件卸载前清空图层信息
   beforeDestroy() {
-    this.markLayer && window.map.removeLayersById('real_time_markerLayer');
+    this.markLayer && window.map.removeLayersById(this.markLayerId);
   },
   created() {
-    this.markLayer = new BDLayers.Lib.Layer.CBVectorLayer('real_time_markerLayer', true);
-    window.map.addCustomLayers(this.markLayer,5);
+    if (this.markLayer) {
+      return;
+    }
+    this.markLayerId = `real_time_markerLayer${uuid()}`;
+    this.markLayer = new BDLayers.Lib.Layer.CBVectorLayer(this.markLayerId, {
+      enableAltitude: true,
+    });
+    window.map.addCustomLayers(this.markLayer, 5);
   },
   mounted() {
-    this.getFenceVioEvtList();
-    this.getFingerprint();
-    this.getFenceList();
+    this.getRoom();
   },
   methods: {
     dayjs,
-    async getFenceVioEvtList() {
-      const { rows } = await listFenceVioEvt({
-        pageNum: 1,
-        pageSize: 10,
-      });
-      this.evtList = rows;
-      this.addEvtToMap();
-    },
-    addEvtToMap() {
-      this.evtList.forEach((item, i) => {
-        const {
-          lng,
-          lat,
-        } = item;
-        var marker = new BDLayers.Lib.Overlays.MarkerImg(
-            `marker0${i}`,
-            [lng, lat],
-            {
-              imgurl: evt_vio,
-              iconSize: [45, 45],
-            },
-        );
-        this.markLayer.addMarker(marker);
-      });
-    },
-    async getFenceList() {
-      const { rows } = await listFenceInfo({
-        pageNum: 1,
-        pageSize: 10,
-      });
-      if (!rows || rows.length < 1) {
-        return;
-      }
-      const result = [];
-      rows.forEach(item => {
-        const {
-          id,
-          defenceName,
-          poly,
-        } = item;
-        const polygon = this.drawPoly({
-          name: defenceName,
-          coordinates: this.polygonToCoordinates(poly),
-          bizAttr: {
-            id,
-            name: defenceName,
+    getRoom() {
+      this.roomList = [
+        {
+          id: 1,
+          room: '创研院C4',
+          poly: 'POLYGON((118.869042069359 32.0131156239015, 118.86839482667 32.0131180416999, 118.868399686907 32.0133391503578, 118.869046506393 32.0133281708171, 118.869042069359 32.0131156239015))',
+          altitude: 11.4,
+        },
+      ];
+      // this.roomList.forEach(item => {
+      //   const {
+      //     id,
+      //     room,
+      //     poly,
+      //     altitude,
+      //   } = item;
+      //   const polygon = this.drawPoly({
+      //     name: room,
+      //     altitude,
+      //     coordinates: this.polygonToCoordinates(poly),
+      //     bizAttr: {
+      //       id,
+      //       name: room,
+      //     },
+      //   });
+      // });
+      // var marker = new BDLayers.Lib.Overlays.UIMarker('marker00', [118.869042069359, 32.0131156239015],
+      //     {
+      //       'draggable': false,
+      //       'single': false,
+      //       'content': `<div class="text_marker" style="color:#fff"><img src="${room_location}" width="40px" height="40px"/></div>`,
+      //       altitude: 800,
+      //     });
+      var marker = new BDLayers.Lib.Overlays.MarkerImg(
+          'marker01',
+          [118.869046506393,32.0133281708171], {
+            imgurl: room_location,
+            iconSize: [90, 54],
+            altitude: 20,
           },
-        });
-        result.push({
-          id,
-          name: defenceName,
-          polygon,
-        });
+      );
+      marker.on('click', () => {
+
       });
-    },
-    async getFingerprint() {
-      // 初始化FingerprintJS
-      const fp = await FingerprintJS.load();
-      // 获取访问者的指纹
-      const result = await fp.get();
-      // 配置
-      const {
-        osCpu,
-        webGlBasics,
-        languages,
-        audioBaseLatency,
-        reducedTransparency,
-        vendor,
-        vendorFlavors,
-        fonts,
-        fontPreferences,
-        plugins,
-        forcedColors,
-        domBlockers,
-        pdfViewerEnabled,
-        audio,
-        canvas,
-        webGlExtensions,
-        math,
-        ...components
-      } = result.components;
-      const extendedComponents = {
-        ...components,
-      };
-      const fingerprintId = FingerprintJS.hashComponents(extendedComponents);
-      this.ws = `/ws/evt/${fingerprintId}`;
+      this.markLayer.addMarker(marker);
+      // marker.getMarker().addTo(window.map.map);
     },
     onMessage(a) {
       const data = JSON.parse(a.data);
@@ -162,7 +122,6 @@ export default {
         message: `${data.msg.fenceName}发生闯禁事件。`,
         type: 'warning',
       });
-      this.getFenceVioEvtList();
     },
   },
 };