Browse Source

要素测试

CzRger 1 year ago
parent
commit
317ebdcba6

+ 2 - 2
src/components/easyMapGL/index.vue

@@ -58,7 +58,7 @@ export default defineComponent({
       const BBOX = [sw.lng, sw.lat, ne.lng, ne.lat]
       return BBOX
     };
-    const addImg = async (name, url) => {
+    const addImg = async (name, url, sdf = false) => {
       const loadImage = (url) => {
         return new Promise((resolve, reject) => {
           const img = new Image();
@@ -70,7 +70,7 @@ export default defineComponent({
         });
       }
       const img = await loadImage(url);
-      state.map.addImage(name, img, {sdf: true});
+      state.map.addImage(name, img, {sdf: sdf});
     }
     const addCss = () => {}
     onMounted(() => {

+ 14 - 0
src/views/element/img/AIS.svg

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="14px" height="21px" viewBox="0 0 14 21" version="1.1" xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>融合船舶-AIS</title>
+    <g id="船舶状态2备份-2"
+       transform="translate(-48.000000, -1054.000000)"
+       style="fill: #fff;"
+       stroke="#000000"
+    >
+        <polygon id="融合船舶-AIS-"
+                 transform="translate(55.000000, 1064.000000) scale(-1, 1) translate(-55.000000, -1064.000000) "
+                 points="55 1054 61 1074 49 1074"></polygon>
+    </g>
+</svg>

File diff suppressed because it is too large
+ 16 - 0
src/views/element/img/tools-element-dept-0.svg


File diff suppressed because it is too large
+ 18 - 0
src/views/element/img/tools-element-police-PDT.svg


File diff suppressed because it is too large
+ 15 - 0
src/views/element/img/tools-element-port-bayonet.svg


File diff suppressed because it is too large
+ 15 - 0
src/views/element/img/tools-element-port-facilities.svg


File diff suppressed because it is too large
+ 16 - 0
src/views/element/img/tools-element-port-industry.svg


File diff suppressed because it is too large
+ 24 - 0
src/views/element/img/tools-element-shoreline-government.svg


+ 35 - 0
src/views/element/img/tools-element-shoreline-island.svg

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组 40</title>
+    <defs>
+        <path d="M7.05882353,0 C10.9573041,0 14.1176471,3.16034294 14.1176471,7.05882353 C14.1176471,10.9573041 10.9573041,14.1176471 7.05882353,14.1176471 C3.16034294,14.1176471 0,10.9573041 0,7.05882353 C0,3.16034294 3.16034294,0 7.05882353,0 Z" id="path-1"></path>
+    </defs>
+    <g id="首页" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="图层图标" transform="translate(-170.000000, -243.000000)">
+            <g id="编组-40" transform="translate(170.000000, 243.000000)">
+                <path d="M8,0 C3.581722,0 0,3.581722 0,8 C0,12.418278 3.581722,16 8,16 C12.418278,16 16,12.418278 16,8 C16,3.581722 12.418278,0 8,0 Z" id="路径" fill="#3DC38A" fill-rule="nonzero"></path>
+                <path d="M8,0.941176471 C11.8984806,0.941176471 15.0588235,4.10151941 15.0588235,8 C15.0588235,11.8984806 11.8984806,15.0588235 8,15.0588235 C4.10151941,15.0588235 0.941176471,11.8984806 0.941176471,8 C0.941176471,4.10151941 4.10151941,0.941176471 8,0.941176471 Z" id="路径" fill="#FFFFFF" fill-rule="nonzero"></path>
+                <g id="面性岛屿休闲度假" transform="translate(0.941176, 0.941176)">
+                    <mask id="mask-2" fill="white">
+                        <use xlink:href="#path-1"></use>
+                    </mask>
+                    <use id="蒙版" fill="#FFFFFF" fill-rule="nonzero" xlink:href="#path-1"></use>
+                    <g mask="url(#mask-2)" fill-rule="nonzero" id="路径">
+                        <g transform="translate(1.293459, 2.717871)">
+                            <path d="M6.08938841,3.02767128 C6.08938841,3.3168657 6.32382681,3.55130409 6.61302122,3.55130409 C6.90221564,3.55130409 7.13665404,3.3168657 7.13665404,3.02767128 C7.13665404,2.73847686 6.90221564,2.50403847 6.61302122,2.50403847 C6.32382681,2.50403847 6.08938841,2.73847686 6.08938841,3.02767128 Z" fill="#F2B843"></path>
+                            <path d="M0.0174119704,9.4011632 C0.484282664,8.5468302 1.63479696,7.85521034 2.98040404,7.85521034 C4.73997435,7.85521034 6.16595091,9.03782753 6.16595091,10.2204447 C3.90670475,10.2204447 2.21227012,10.2204447 1.08264704,10.2204447 C0.653383748,10.2204447 -0.126216366,9.66399063 0.0174119704,9.4011632 Z" fill="#2F9B77"></path>
+                            <path d="M7.3376306,7.8702494 C7.5454431,7.58724159 7.95696654,3.85071815 6.72239622,2.62981972 C6.6813806,2.54642128 6.71692747,2.4452494 6.80032591,2.40423378 C6.88509154,2.36321815 6.98489622,2.39739784 7.02591185,2.48216347 C8.19622435,3.40228065 8.60774779,6.1749369 8.40540404,7.8702494 L7.3376306,7.8702494 Z" fill="#EA800C"></path>
+                            <path d="M6.68821654,2.5436869 C6.68821654,2.73076289 6.78802038,2.90362824 6.95003294,2.99716624 C7.1120455,3.09070424 7.3116532,3.09070424 7.47366576,2.99716624 C7.63567832,2.90362824 7.73548216,2.73076289 7.73548216,2.5436869 C7.73548216,2.35661091 7.63567832,2.18374556 7.47366576,2.09020757 C7.3116532,1.99666957 7.1120455,1.99666957 6.95003294,2.09020757 C6.78802038,2.18374556 6.68821654,2.35661091 6.68821654,2.5436869 Z" fill="#F2B843"></path>
+                            <path d="M7.07786497,2.06653847 L5.06809935,5.21517128 C4.60872435,4.56575722 4.5595056,3.67708534 5.01477904,2.96478065 C5.46868529,2.25247597 6.29583372,1.92298378 7.07786497,2.06653847 L7.07786497,2.06653847 Z" fill="#3DC38A"></path>
+                            <path d="M8.91673216,0.149741591 L6.55696654,2.43978065 C6.29446654,1.79036659 6.43255247,1.01927284 6.9657556,0.501108779 C7.50032591,-0.017055284 8.27552122,-0.131899034 8.91673216,0.149741591 Z" fill="#2F9B77"></path>
+                            <path d="M7.08743529,2.29485878 L3.81165404,2.58333534 C4.01809935,1.91341347 4.61145872,1.40208534 5.35247435,1.33782753 C6.09348997,1.27220253 6.76751341,1.67142128 7.08743529,2.29485878 L7.08743529,2.29485878 Z" fill="#2F9B77"></path>
+                            <path d="M6.89602904,2.03099159 L4.35032591,0.643296279 C4.82884154,0.252280654 5.51516966,0.167515029 6.0907556,0.480600966 C6.66634154,0.795054091 6.9657556,1.41849159 6.89602904,2.03099159 L6.89602904,2.03099159 Z" fill="#3DC38A"></path>
+                            <path d="M10.0514978,2.87728065 L6.34095091,2.44798378 C6.72376341,1.75071815 7.5016931,1.31731972 8.34114622,1.41439003 C9.17923216,1.51009315 9.83821654,2.11165565 10.0514978,2.87728065 L10.0514978,2.87728065 Z" fill="#3DC38A"></path>
+                            <path d="M11.3323786,9.15866413 C10.7594502,7.993658 9.30241787,7.04446815 7.59602904,7.04446815 C5.38938841,7.04446815 3.59837279,8.63177284 3.59837279,10.2204447 C6.65433632,10.2204447 8.94630896,10.2204447 10.4742907,10.2204447 C10.8469665,10.2204447 11.5003406,9.500202 11.3323786,9.15866413 Z" fill="#3DC38A"></path>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

File diff suppressed because it is too large
+ 16 - 0
src/views/element/img/tools-element-shoreline-policing.svg


File diff suppressed because it is too large
+ 16 - 0
src/views/element/img/tools-element-water-port.svg


+ 218 - 44
src/views/element/index.vue

@@ -1,10 +1,13 @@
 <template>
   <div class="main">
     <div class="tree">
-      <div class="buttons">
-        <el-button type="primary" @click="setSourceData">上图</el-button>
-      </div>
+      <el-input
+        v-model="treeText"
+        placeholder="Please enter keyword"
+        @input="handleTreeFilter"
+      />
       <el-tree-v2
+        ref="ref_tree"
         :data="treeData"
         :props="{
           value: 'mapId',
@@ -12,7 +15,16 @@
           children: 'children'
         }"
         :height="800"
-      />
+        :filter-method="filterMethod"
+      >
+        <template #default="{ node }">
+          <div>
+            <span>{{ node.label }}</span>
+            <el-link v-if="!node.data._show" href="javascript:;" type="primary" @click.stop="onShow(node)">显示</el-link>
+            <el-link v-else href="javascript:;" type="primary" @click.stop="onHide(node)">隐藏</el-link>
+          </div>
+        </template>
+      </el-tree-v2>
     </div>
     <div class="map">
       <EasyMapGLComponent
@@ -32,13 +44,25 @@ import {
   getCurrentInstance,
   ComponentInternalInstance,
   toRefs,
-  nextTick
+  nextTick, createApp
 } from 'vue'
 import {useStore} from 'vuex'
 import {useRouter, useRoute} from 'vue-router'
 import {ElMessage, ElMessageBox} from "element-plus";
 import xqysJson from './xqys.json'
 import * as format from "ol/format";
+import defaultImg from "./img/AIS.svg";
+import axBayonetListImg from "./img/tools-element-port-bayonet.svg";
+import axSiteListImg from "./img/tools-element-port-industry.svg";
+import governmentalListImg from "./img/tools-element-shoreline-government.svg";
+import islandListImg from "./img/tools-element-shoreline-island.svg";
+import monitoringListImg from "./img/tools-element-water-port.svg";
+import radarListImg from "./img/tools-element-police-PDT.svg";
+import terminalListImg from "./img/tools-element-shoreline-policing.svg";
+import waterBasedFacilitiesListImg from "./img/tools-element-port-facilities.svg";
+import deptInfoImg from "./img/tools-element-dept-0.svg";
+import ShipHover from "@/views/ship-test/business/v2/ship-hover.vue";
+import mapboxgl from "mapbox-gl";
 
 export default defineComponent({
   name: '',
@@ -53,8 +77,11 @@ export default defineComponent({
       map: <any>null,
       mapFunc: <any>null,
       treeData: <any>[],
-      sourceElement: 'source_element'
+      sourceElement: 'source_element',
+      popupHover: <any>null,
+      treeText: ''
     })
+    const ref_tree = ref()
     const mapGLLoad = (map, func) => {
       state.map = map
       state.mapFunc = func
@@ -67,11 +94,13 @@ export default defineComponent({
         const obj = {
           mapId: key,
           mapLabel: pName,
-          children: []
+          children: [],
+          _show: true
         }
         xqysJson.data[key].forEach(v => {
-          v.mapId = key + '_' + v.id
-          v.mapLabel = v.name
+          v.mapId = key + '_' + v[idKey]
+          v.mapLabel = v[labelKey]
+          v._show = true
           obj.children.push(v)
         })
         state.treeData.push(obj)
@@ -91,8 +120,19 @@ export default defineComponent({
       formatData('terminalList', '自助报备终端')
       formatData('waterAreaList', '水域-警务区')
       formatData('waterBasedFacilitiesList', '水域-水上设施')
+      setSourceData()
     }
     const initMap = () => {
+      state.mapFunc.addImg('defaultImg', defaultImg)
+      state.mapFunc.addImg('axBayonetListImg', axBayonetListImg)
+      state.mapFunc.addImg('axSiteListImg', axSiteListImg)
+      state.mapFunc.addImg('governmentalListImg', governmentalListImg)
+      state.mapFunc.addImg('islandListImg', islandListImg)
+      state.mapFunc.addImg('monitoringListImg', monitoringListImg)
+      state.mapFunc.addImg('radarListImg', radarListImg)
+      state.mapFunc.addImg('terminalListImg', terminalListImg)
+      state.mapFunc.addImg('waterBasedFacilitiesListImg', waterBasedFacilitiesListImg)
+      state.mapFunc.addImg('deptInfoImg', deptInfoImg)
       state.map.addSource(state.sourceElement, {
         type: 'geojson',
         data: {
@@ -120,6 +160,90 @@ export default defineComponent({
           'fill-color': ['get', 'fillColor']
         }
       })
+      state.map.addLayer({
+        id: 'layer_element-symbol',
+        type: "symbol",
+        source: state.sourceElement,
+        layout: {
+          'icon-allow-overlap': true,
+          'icon-ignore-placement': true,
+          'icon-image': [
+            'match',
+            ['get', 'iconImage'], // 根据属性值'type'来匹配
+            'axBayonetListImg', 'axBayonetListImg',
+            'axSiteListImg', 'axSiteListImg',
+            'governmentalListImg', 'governmentalListImg',
+            'islandListImg', 'islandListImg',
+            'monitoringListImg', 'monitoringListImg',
+            'radarListImg', 'radarListImg',
+            'terminalListImg', 'terminalListImg',
+            'waterBasedFacilitiesListImg', 'waterBasedFacilitiesListImg',
+            'deptInfoImg', 'deptInfoImg',
+            '' // 默认样式
+          ],
+          "symbol-spacing": 1,
+        },
+        paint: {
+          'icon-color': 'red',
+          'icon-halo-color': '#000000',
+          'icon-halo-width': 4,
+        }
+      })
+      state.map.on('click', 'layer_element-line', (e) => {
+        const features = state.map.queryRenderedFeatures(e.point);
+        if (!features.length) {
+          return;
+        }
+        const properties: any = features[0].properties;
+        const html = '线_' + properties.mapLabel
+        if (state.popupHover) {
+          state.popupHover.setLngLat(e.lngLat).setHTML(html)
+        } else {
+          state.popupHover = new mapboxgl.Popup({
+            closeOnClick: false
+          }).setLngLat(e.lngLat).setHTML(html).addTo(state.map);
+          state.popupHover.on('close', () => {
+            state.popupHover = null
+          })
+        }
+      });
+      state.map.on('click', 'layer_element-polygon', (e) => {
+        const features = state.map.queryRenderedFeatures(e.point);
+        if (!features.length) {
+          return;
+        }
+        const properties: any = features[0].properties;
+        const html = '面_' + properties.mapLabel
+        if (state.popupHover) {
+          state.popupHover.setLngLat(e.lngLat).setHTML(html)
+        } else {
+          state.popupHover = new mapboxgl.Popup({
+            closeOnClick: false
+          }).setLngLat(e.lngLat).setHTML(html).addTo(state.map);
+          state.popupHover.on('close', () => {
+            state.popupHover = null
+          })
+        }
+      });
+      state.map.on('click', 'layer_element-symbol', (e) => {
+        const features = state.map.queryRenderedFeatures(e.point);
+        console.log(features)
+        if (!features.length) {
+          return;
+        }
+        const properties: any = features[0].properties;
+        const html = '点_' + properties.mapLabel
+        if (state.popupHover) {
+          state.popupHover.setLngLat(e.lngLat).setHTML(html)
+        } else {
+          state.popupHover = new mapboxgl.Popup({
+            closeOnClick: false
+          }).setLngLat(e.lngLat).setHTML(html).addTo(state.map);
+          state.popupHover.on('close', () => {
+            state.popupHover = null
+          })
+        }
+      });
     }
     const globalLineDash = [
       [0, 0], //实线
@@ -129,54 +253,104 @@ export default defineComponent({
     const setSourceData = () => {
       const arr: any = []
       state.treeData.forEach(p => {
-        p.children.forEach(v => {
-          try {
-            const geometry: any = new format.WKT().readFeature(v.location).getGeometry()
-            const obj = {
-              type: 'Feature',
-              geometry: {
-                type: geometry.getType(),
-                coordinates: geometry.getCoordinates()
-              },
-              properties: v
-            }
-            let fillColor = 'rgba(20, 129, 241, 0.3)'
-            let lineColor = '#2860F1'
-            let lineWidth = 1
-            let lineDasharray = globalLineDash[0]
-            if (v.regionalColor) {
-              fillColor = v.regionalColor
-            }
-            if (v.segmentColor) {
-              lineColor = v.segmentColor
-            }
-            if (v.segmentWidth) {
-              lineWidth = v.segmentWidth
-            }
-            if (v.segmentType) {
-              lineDasharray = globalLineDash[Number(v.segmentType)]
+        console.log(p)
+        if (p.mapId === 'deptInfo') {
+
+        } else {
+          p.children.forEach(v => {
+            try {
+              const geometry: any = new format.WKT().readFeature(v.location).getGeometry()
+              const obj = {
+                type: 'Feature',
+                geometry: {
+                  type: geometry.getType(),
+                  coordinates: geometry.getCoordinates()
+                },
+                properties: v
+              }
+              let fillColor = 'rgba(20, 129, 241, 0.3)'
+              let lineColor = '#2860F1'
+              let lineWidth = 1
+              let lineDasharray = globalLineDash[0]
+              if (v.regionalColor) {
+                fillColor = v.regionalColor
+              }
+              if (v.segmentColor) {
+                lineColor = v.segmentColor
+              }
+              if (v.segmentWidth) {
+                lineWidth = v.segmentWidth
+              }
+              if (v.segmentType) {
+                lineDasharray = globalLineDash[Number(v.segmentType)]
+              }
+              obj.properties.fillColor = fillColor
+              obj.properties.lineColor = lineColor
+              obj.properties.lineWidth = lineWidth
+              obj.properties.lineDasharray = lineDasharray
+              switch (p.mapId) {
+                case 'axBayonetList': obj.properties.iconImage = 'axBayonetListImg'
+                  break
+                case 'axSiteList': obj.properties.iconImage = 'axSiteListImg'
+                  break
+                case 'governmentalList': obj.properties.iconImage = 'governmentalListImg'
+                  break
+                case 'islandList': obj.properties.iconImage = 'islandListImg'
+                  break
+                case 'monitoringList': obj.properties.iconImage = 'monitoringListImg'
+                  break
+                case 'radarList': obj.properties.iconImage = 'radarListImg'
+                  break
+                case 'terminalList': obj.properties.iconImage = 'terminalListImg'
+                  break
+                case 'waterBasedFacilitiesList': obj.properties.iconImage = 'waterBasedFacilitiesListImg'
+                  break
+              }
+              arr.push(obj)
+            } catch (e) {
             }
-            obj.properties.fillColor = fillColor
-            obj.properties.lineColor = lineColor
-            obj.properties.lineWidth = lineWidth
-            obj.properties.lineDasharray = lineDasharray
-            arr.push(obj)
-          } catch (e) {
-          }
-        })
+          })
+        }
       })
       state.map.getSource(state.sourceElement).setData({
         type: 'FeatureCollection',
         features: arr
       })
     }
+    const filterMethod = (text: string, node: any) => {
+      return node.mapLabel?.includes(text)
+    }
+    const handleTreeFilter = (text) => {
+      ref_tree.value?.filter(text)
+    }
+    const onShow = (node) => {
+      console.log(node)
+      node.data._show = true
+      node.children?.forEach(v => {
+        v._show = true
+      })
+      setSourceData()
+    }
+    const onHide = (node) => {
+      console.log(node)
+      node.data._show = false
+      node.children?.forEach(v => {
+        v._show = false
+      })
+      setSourceData()
+    }
     onMounted(() => {
       console.log(xqysJson)
     })
     return {
       ...toRefs(state),
       mapGLLoad,
-      setSourceData
+      setSourceData,
+      filterMethod,
+      handleTreeFilter,
+      ref_tree,
+      onShow,
+      onHide
     }
   },
 })

+ 1 - 1
src/views/index.vue

@@ -4,7 +4,7 @@
     <el-button @click="$router.push('/track-status')">船舶轨迹状态查询</el-button>
     <el-button @click="$router.push('/ship-test')">船舶测试</el-button>
     <el-button @click="$router.push('/ship-playback')">船舶回放</el-button>
-    <el-button @click="$router.push('/element')">辖区要素</el-button>
+<!--    <el-button @click="$router.push('/element')">辖区要素</el-button>-->
   </div>
 </template>
 

+ 2 - 2
src/views/ship-test/business/v2/index.vue

@@ -184,8 +184,8 @@ export default defineComponent({
         state.hoverShip.popup = new mapboxgl.Popup({
           className: 'cus',
           maxWidth: 'none',
-          closeButton: false,
-          closeOnClick: true,
+          closeButton: true,
+          closeOnClick: false,
           offset: 15
         }).setLngLat(e.lngLat).setDOMContent(contentElement).addTo(props.map);
       });

+ 11 - 1
vite.config.ts

@@ -16,9 +16,19 @@ export default defineConfig({
   },
   plugins: [vue(), viteCompression(), VitePluginHtmlEnv(), visualizer(), createSvgIconsPlugin({
     // 指定需要缓存的图标文件夹
-    iconDirs: [resolve(process.cwd(), 'src/assets/svg/global'), resolve(process.cwd(), 'src/assets/svg/business')],
+    iconDirs: [resolve(process.cwd(), 'src/assets/svg/menu'), resolve(process.cwd(), 'src/assets/svg/business')],
     // 指定symbolId格式
     symbolId: 'icon-[dir]-[name]',
+    svgoOptions: {
+      plugins: [
+        {
+          name: 'removeAttrs',
+          params: {
+            attrs: ['class', 'data-name', 'fill', 'stroke']
+          }
+        }
+      ]
+    }
   }), topLevelAwait({
     promiseExportName: '__tla',
     promiseImportName: i => `__tla_${i}`