<template> <Transition name="slideTC"> <div class="LayerControl" v-show="ShowTuCheng"> <div class="GroupBox" v-for="item in AllData.LayerData" v-show="item.children"> <div class="GroupName" @click="item.Show = !item.Show">{{ item.title }}</div> <!-- <Transition name="Group"> --> <div class="TCListBox" v-show="item.Show"> <div class="TCList" v-for="item2 in item.children" :class="item2.layerVisible ? 'TCList_Check' : ''" @click="layerClick(item2)" > <div class="TCList_Select"> <el-icon v-show="item2.layerVisible"><Check /></el-icon> </div> <img class="TCList_Icon" :src="item2.layerIcon" v-if="item2.layerIcon" /> <!-- 当有未配置图片的图层时,将使用备用图片 --> <img class="TCList_Icon" :src="requireTuChengImg('TuCheng')" v-else /> <div class="TCList_Name"> {{ item2.layerName }} </div> </div> </div> <!-- </Transition/> --> </div> </div> </Transition> </template> <script setup name="LayerControl"> import { ref, reactive, toRefs, onMounted } from 'vue'; // 图层控制icon引入 import { requireTuChengImg } from '@/utils/util'; import yanAnPaiShuiArea from '@/assets/yanAnPaiShuiArea.json'; import yanAnRoad from '@/assets/yanAnRoad.json'; import yanAnWater from '@/assets/yanAnWater.json'; import yanAnWSCLC from '@/assets/yanAnWSCLC.json'; import yanAnCenterCity from '@/assets/yanAnCenterCity.json'; import yanAnYSBZ from '@/assets/yanAnYSBZ.json'; import yanAnYiLao from '@/assets/yanAnYiLao.json'; import yanAnFengXian from '@/assets/yanAnFengXian.json'; import yanAnPipeSupervise from '@/assets/yanAnPipeSupervise.json'; import yanAnPKSupervise from '@/assets/yanAnPKSupervise.json'; import yanAnNature from '@/assets/yanAnNature.json'; import yanAnVideo from '@/assets/yanAnVideo.json'; import yanAnMountain from '@/assets/yanAnMountain.json'; import yanAnSmallWater from '@/assets/yanAnSmallWater.json'; import yanAnRainArea from '@/assets/yanAnRainArea.json'; import heDiJiaGu from '@/assets/heDiJiaGu.json'; import heDiShuJun from '@/assets/heDiShuJun.json'; import anXianGaiZao from '@/assets/anXianGaiZao.json'; import bus from '@/bus'; import axios from 'axios'; import mapBoxVectorLayer from '@/utils/GISdocument/mapboxVectorLayer.js'; const AllData = reactive({ // 图层控制面板的渲染数据 /**图层面板数据字段说明 *@param title:渲染在图层控制中的图层分组名称 *@param children:关联图层分组与图层的字段 *@param layerName:渲染在图层控制中的图层名称 *@param layerKey:gis使用的图层唯一id名称 *@param layerIcon:渲染在图层控制中UI设计的图层示意图 *@param layerVisible:代表当前图层是否勾选,true:勾选中且地图上图;false:不勾选且地图不上图 */ LayerData: [ { title: '基本信息', Show: true, children: [ { layerName: '蓝色地图', layerKey: 'blackMap', layerIcon: requireTuChengImg('zhongxinchengqu'), layerVisible: false, }, { layerName: '白色地图', layerKey: 'whiteMap', layerIcon: requireTuChengImg('zhongxinchengqu'), layerVisible: false, }, { layerName: '影像地图', layerKey: 'imageMap', layerIcon: requireTuChengImg('zhongxinchengqu'), layerVisible: false, }, { layerName: '中心城区', layerKey: 'centerCity', layerIcon: requireTuChengImg('zhongxinchengqu'), layerVisible: false, dynamicLineData: yanAnCenterCity, }, { layerName: '三维建筑', layerKey: 'buildingLayer', layerIcon: '', layerVisible: true, }, { layerName: '路网', layerKey: 'road', layerIcon: '', layerVisible: true, dynamicLineData: yanAnRoad, }, { layerName: '河流水系', layerKey: 'waterLake', layerIcon: '', layerVisible: true, dynamicLineData: yanAnWater, }, { layerName: '防洪河道', layerKey: 'fangHongWater', layerIcon: '', layerVisible: false, lineWithLabel: yanAnSmallWater, }, { layerName: '河堤疏浚', layerKey: 'heDiShuJun', layerIcon: '', layerVisible: false, lineWithLabel: heDiShuJun, }, { layerName: '河堤加固', layerKey: 'heDiJiaGu', layerIcon: '', layerVisible: false, lineWithLabel: heDiJiaGu, }, { layerName: '岸线改造', layerKey: 'anXianGaiZao', layerIcon: '', layerVisible: false, lineWithLabel: anXianGaiZao, }, { layerName: '河堤治理', layerKey: 'heDiZhiLi', layerIcon: '', layerVisible: false, lineWithLabel: anXianGaiZao, }, { layerName: '空间格局', layerKey: 'yanAnNature', layerIcon: '', layerVisible: false, areaData: yanAnNature, }, { layerName: '山体修复', layerKey: 'yanAnMountain', layerIcon: '', layerVisible: false, lineWithLabel: yanAnMountain, }, ], }, { title: '燃气系统', Show: true, children: [ { layerName: '燃气管网', layerKey: 'rq_all', layerIcon: null, layerVisible: false, }, { layerName: '干管', layerKey: 'rq_SZLH', layerIcon: null, layerVisible: false, }, { layerName: '干管流向', layerKey: 'sx_ya_smx_rq_line_sz', layerIcon: null, layerVisible: false, }, { layerName: '主管', layerKey: 'rq_TYLH', layerIcon: null, layerVisible: false, }, { layerName: '主管流向', layerKey: 'sx_ya_smx_rq_line_zg', layerIcon: null, layerVisible: false, }, { layerName: '支管', layerKey: 'rq_LGLH', layerIcon: null, layerVisible: false, }, { layerName: '支管流向', layerKey: 'sx_ya_smx_rq_line_zhig', layerIcon: null, layerVisible: false, }, { layerName: '其他管网', layerKey: 'rq_other', layerIcon: null, layerVisible: false, }, { layerName: '调压器', layerKey: 'tiaoYaQi', layerIcon: null, layerVisible: false, }, { layerName: '节点', layerKey: 'rq_jieDian', layerIcon: null, layerVisible: false, }, { layerName: '极性保护', layerKey: 'jiXingBaoHu', layerIcon: null, layerVisible: false, }, { layerName: '流量计', layerKey: 'rq_liuLiangJi', layerIcon: null, layerVisible: false, }, { layerName: '未知设备', layerKey: 'rq_unknow', layerIcon: null, layerVisible: false, }, ], }, { title: '雨水系统', Show: true, children: [ { layerName: '雨水分区', layerKey: 'rainArea', layerIcon: null, layerVisible: false, areaData: yanAnRainArea, }, { layerName: '排水分区', layerKey: 'paishuiArea', layerIcon: null, layerVisible: false, areaData: yanAnPaiShuiArea, }, { layerName: '雨水管网', layerKey: 'ysLine1', layerIcon: null, layerVisible: false, }, { layerName: '雨水管网流向', layerKey: 'pipeline_info_flow_ys', layerIcon: null, layerVisible: false, }, // { // layerName: '雨水排口', // layerKey: '', // layerIcon: null, // layerVisible: false, // }, { layerName: '雨水泵站', layerKey: 'YSBZ', layerIcon: null, layerVisible: false, data: yanAnYSBZ, }, ], }, { title: '污水系统', Show: true, children: [ { layerName: '污水分区', layerKey: 'sewageArea', layerIcon: null, layerVisible: false, }, { layerName: '污水管网', layerKey: 'wsLine1', layerIcon: null, layerVisible: false, }, { layerName: '污水管网流向', layerKey: 'pipeline_info_flow_ws1', layerIcon: null, layerVisible: false, }, // { // layerName: '溢流口', // layerKey: '', // layerIcon: null, // layerVisible: false, // }, // { // layerName: '污水泵站', // layerKey: '', // layerIcon: null, // layerVisible: false, // }, { layerName: '污水处理厂', layerKey: 'WSCLC', layerIcon: null, layerVisible: false, data: yanAnWSCLC, }, ], }, { title: '感知设备', Show: true, children: [ { layerName: '内涝易涝点', layerKey: 'yiLaoPoint', layerIcon: null, layerVisible: false, data: yanAnYiLao, }, { layerName: '内涝风险点', layerKey: 'fengXianPoint', layerIcon: null, layerVisible: false, data: yanAnFengXian, }, { layerName: '排水管网监测', layerKey: 'pipeSupervise', layerIcon: null, layerVisible: false, data: yanAnPipeSupervise, }, { layerName: '排水排口监测', layerKey: 'PKsupervise', layerIcon: null, layerVisible: false, data: yanAnPKSupervise, }, { layerName: '视频监测', layerKey: 'video', layerIcon: null, layerVisible: false, data: yanAnVideo, }, ], }, ], }); onMounted(() => { let initeLegend = AllData.LayerData[0].children .concat(AllData.LayerData[1].children) .concat(AllData.LayerData[2].children) .concat(AllData.LayerData[3].children) .concat(AllData.LayerData[4].children); initeLegend.forEach(element => { element.layername = element.layerKey; }); bus.emit('setLegendData', initeLegend); }); const props = defineProps({ ShowTuCheng: false, }); watch( () => props.ShowTuCheng, (newValue, oldValue) => { console.log('ShowTuCheng变化了', newValue, oldValue); }, { immediate: true, deep: true } ); const layerClick = async item2 => { item2.layerVisible = !item2.layerVisible; item2.isCheck = item2.layerVisible; console.info(`点击了名称为${item2.layerName},图层ID为${item2.layerKey}的图层,点击后的图层展示情况为${item2.layerVisible}`); bus.emit('setLayerVisible', { layername: item2.layerKey, isCheck: item2.isCheck }); if (item2.layerKey == 'whiteMap') { AllData.LayerData[0]['children'][0].layerVisible = false; AllData.LayerData[0]['children'][2].layerVisible = false; let { data } = await axios.get('/static/libs/mapbox/style/customs/whiteMapStyle.json'); let newMapStyle; let oldMapStyle = newfiberMapbox.map.getStyle(); let oldIds = []; oldMapStyle.layers.forEach(layer => { oldIds.push(layer.id); }); let newIds = data.layers.map(i => i.id); oldIds.forEach(id => { let layer = data.layers[newIds.indexOf(id)]; if (!layer) return; Object.keys(layer.layout || {}).forEach(key => newfiberMapbox.map.setLayoutProperty(id, key, layer.layout[key])); Object.keys(layer.paint || {}).forEach(key => newfiberMapbox.map.setPaintProperty(id, key, layer.paint[key])); }); newfiberMapbox.map.setLayoutProperty('newfiber-XYZLayer', 'visibility', 'none'); } if (item2.layerKey == 'blackMap') { AllData.LayerData[0]['children'][1].layerVisible = false; AllData.LayerData[0]['children'][2].layerVisible = false; let { data } = await axios.get('/static/libs/mapbox/style/customs/night-style.json'); let newMapStyle; let oldMapStyle = newfiberMapbox.map.getStyle(); let oldIds = []; oldMapStyle.layers.forEach(layer => { oldIds.push(layer.id); }); let newIds = data.layers.map(i => i.id); oldIds.forEach(id => { let layer = data.layers[newIds.indexOf(id)]; if (!layer) return; Object.keys(layer.layout || {}).forEach(key => newfiberMapbox.map.setLayoutProperty(id, key, layer.layout[key])); Object.keys(layer.paint || {}).forEach(key => newfiberMapbox.map.setPaintProperty(id, key, layer.paint[key])); }); newfiberMapbox.map.setLayoutProperty('newfiber-XYZLayer', 'visibility', 'none'); } if (item2.layerKey == 'imageMap') { AllData.LayerData[0]['children'][0].layerVisible = false; AllData.LayerData[0]['children'][1].layerVisible = false; newfiberMapbox.map.setLayoutProperty('newfiber-XYZLayer', 'visibility', 'visible'); newfiberMapbox.map.moveLayer('newfiber-XYZLayer', 'buildingLayer'); } if (item2.areaData) { if (item2.isCheck) { mapBoxVectorLayer.addGeojsonPolygonWithLabel(item2.layerKey, item2.areaData); } else { mapBoxVectorLayer.removeByIds([item2.layerKey, item2.layerKey + '_label']); } } if (item2.layerKey == 'buildingLayer') { if (item2.isCheck) { newfiberMapbox.map.setLayoutProperty('buildingLayer', 'visibility', 'visible'); } else { newfiberMapbox.map.setLayoutProperty('buildingLayer', 'visibility', 'none'); } } if (item2.lineWithLabel) { if (item2.isCheck) { mapBoxVectorLayer.addGeojsonLineWithLabel(item2.layerKey, item2.lineWithLabel); if (item2.layerKey == 'fangHongWater') { let layer = new mapboxL7.LineLayer({ name: 'fangHongWater', }) .source(item2.lineWithLabel) .size(3) .shape('line') .texture('arrow') .color('rgba(243, 26, 237,1)') .animate({ interval: 2, // 间隔 duration: 3, // 持续时间,延时 trailLength: 3, // 流线长度 }) .style({ opacity: 0.8, lineTexture: true, // 开启线的贴图功能 iconStep: 200, // 设置贴图纹理的间距 borderWidth: 0.4, // 默认文 0,最大有效值为 0.5 borderColor: '#fff', // 默认为 #ccc }); newfiberMapbox.addLayer(layer); } } else { mapBoxVectorLayer.removeByIds([item2.layerKey, item2.layerKey + '_label']); if (newfiberMapbox.getLayerByName('fangHongWater')) { newfiberMapbox.removeLayer(newfiberMapbox.getLayerByName('fangHongWater')); } } } if (item2.layerKey == 'road') { if (item2.isCheck) { if (newfiberMapbox.getLayerByName('dynamicRoad')) { newfiberMapbox.removeLayer(newfiberMapbox.getLayerByName('dynamicRoad')); } let layer = new mapboxL7.LineLayer({ name: 'dynamicRoad', }) .source(item2.dynamicLineData) .size(1.3) .shape('line') .color('rgb(184, 184, 184)') .animate({ interval: 1, // 间隔 duration: 1.5, // 持续时间,延时 trailLength: 2, // 流线长度 }) .style({ opacity: 0.6, }); newfiberMapbox.addLayer(layer); } else { newfiberMapbox.removeLayer(newfiberMapbox.getLayerByName('dynamicRoad')); } } if (item2.layerKey == 'waterLake') { if (item2.isCheck) { if (newfiberMapbox.getLayerByName('waterLake')) { newfiberMapbox.removeLayer(newfiberMapbox.getLayerByName('waterLake')); } let layer = new mapboxL7.LineLayer({ name: 'waterLake', }) .source(item2.dynamicLineData) .size(4) .shape('line') .texture('arrow') .color('aqua') .animate({ interval: 2, // 间隔 duration: 3, // 持续时间,延时 trailLength: 3, // 流线长度 }) .style({ opacity: 0.8, lineTexture: true, // 开启线的贴图功能 iconStep: 200, // 设置贴图纹理的间距 borderWidth: 0.4, // 默认文 0,最大有效值为 0.5 borderColor: '#fff', // 默认为 #ccc }); newfiberMapbox.addLayer(layer); } else { newfiberMapbox.removeLayer(newfiberMapbox.getLayerByName('waterLake')); } } if (item2.layerKey == 'centerCity') { if (item2.isCheck) { mapBoxVectorLayer.addGeojsonLine('centerCity', item2.dynamicLineData, 4, 1, 0.5); } else { mapBoxVectorLayer.removeByIds(['centerCity']); } } }; onMounted(() => { // 清除所有的图层选中 bus.on('clearAllLayer', () => { AllData.LayerData.forEach(data => { data.children.map(item => { // item.layerVisible = true; // 做优化,全局为True,再执行隐藏工作,页面调用api太多了,这里应该只将展示的图层进行取消操作就行 item.layerVisible ? layerClick(item) : ''; }); }); }); /**控制图层的显示 *@param LayerArraya:需要打开的图层名称,示例:["路网","中心城区"] */ bus.on('SetLayerShow', LayerArraya => { AllData.LayerData.forEach(data => { data.children.map(item => { LayerArraya.includes(item.layerName) ? layerClick(item) : ''; }); }); }); }); onBeforeUnmount(() => { bus.off('clearAllLayer'); bus.off('SetLayerShow'); }); </script> <style lang="scss" scoped> .LayerControl { width: 190px; height: 688px; position: absolute; top: 150px; right: 476px; background: url('@/assets/images/Sponge_screen/TuChengBG.png') no-repeat center; background-size: contain; box-sizing: border-box; padding: 25px 0px; overflow: auto; z-index: 998; .GroupBox { width: 100%; height: auto; margin-bottom: 5px; .GroupName { width: 190px; height: 25px; line-height: 25px; background-image: url('@/assets/images/Sponge_screen/TuChengFenZuBG.png'), linear-gradient(to right, #1c899600, #1c8996, #1c899600); background-repeat: no-repeat; background-position: center; background-size: contain; font-family: Source Han Sans CN; font-weight: 500; font-size: 14px; color: #ffffff; text-align: center; cursor: pointer; } .TCListBox { width: 100%; height: auto; .TCList { width: 100%; height: 14px; margin-top: 10px; display: flex; color: #fff; cursor: pointer; flex-direction: row; flex-wrap: nowrap; align-content: center; justify-content: flex-start; align-items: center; box-sizing: border-box; padding-left: 20px; .TCList_Select { width: 14px; height: 14px; box-sizing: border-box; border: 1px solid #fff; } .TCList_Icon { width: 14px; height: 14px; margin: 0 10px; } .TCList_Name { font-family: Source Han Sans CN; font-weight: 500; font-size: 14px; height: 14px; line-height: 14px; } } .TCList_Check { color: #12f3ff; .TCList_Select { border: 1px solid #12f3ff; } } } } } // 动画 /* 进入和离开动画可以使用不同 持续时间和速度曲线。 */ .slideTC-enter-active, .slideTC-leave-active { transition: all 0.2s ease-out; } .slideTC-enter-from, .slideTC-leave-to { height: 0px; opacity: 0; } .Group-enter-active, .Group-leave-active { transition: all 1s ease; } .Group-enter-from, .Group-leave-to { height: 0px; } </style>