| | |
| | | <template> |
| | | <div class="layer-control bg-white"> |
| | | <div class="w-[370px] bg-white p-3 rounded"> |
| | | <div class="layer-control bg-white h-full flex-col" style="display: flex"> |
| | | <div class="bg-white rounded flex-0"> |
| | | <div class="header flex-items-center pb-1.5" style="border-bottom: 1px solid black"> |
| | | <div class="flex-items-center"> |
| | | <span class="ywifont ywicon-guanbi cursor-pointer mr-1.5" @click="closeClick"></span> |
| | | <span class="text-lg font-bold">图层</span> |
| | | <span class="text-lg font-bold">图层及背景地图</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="content rounded-lg max-h-[700px] overflow-y-auto min-h-[600px]"> |
| | | <el-tree |
| | | class="w-full" |
| | | :data="layerInfo" |
| | | :props="defaultProps" |
| | | show-checkbox |
| | | node-key="id" |
| | | default-expand-all |
| | | ref="checkTreeRef" |
| | | @check="handleCheck" |
| | | @node-click="handleNodeClick" |
| | | > |
| | | <template #default="{ node, data }"> |
| | | <span>{{ node.label }}</span> |
| | | </template> |
| | | </el-tree> |
| | | <div class="content rounded-lg flex-auto overflow-y-auto"> |
| | | <div class="theme-item"> |
| | | <div class="theme-item-title h-fit flex-items-center gap-2 mb-1"> |
| | | <div class="w-1 h-4 bg-[#1677ff]"></div> |
| | | <span class="font-bold">图层控制</span> |
| | | </div> |
| | | <div> |
| | | <el-tree |
| | | class="w-full" |
| | | :data="layerInfo" |
| | | :props="defaultProps" |
| | | show-checkbox |
| | | node-key="id" |
| | | default-expand-all |
| | | ref="checkTreeRef" |
| | | @check="handleCheck" |
| | | @node-click="handleNodeClick" |
| | | > |
| | | <template #default="{ node, data }"> |
| | | <div class="flex-items-center gap-2"> |
| | | <span :style="[{ 'font-family': `ywifont` }]">{{ getIconText(node, data) }}</span> |
| | | <!-- e6b4 --> |
| | | <span>{{ node.label }}</span> |
| | | </div> |
| | | </template> |
| | | </el-tree> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="theme-item"> |
| | | <div class="theme-item-title h-fit flex-items-center gap-2 mb-1"> |
| | | <div class="w-1 h-4 bg-[#1677ff]"></div> |
| | | <span class="font-bold">背景地图</span> |
| | | </div> |
| | | <div> |
| | | <div class="grid grid-cols-2 gap-1 p-1"> |
| | | <div |
| | | v-for="item in mapTypes" |
| | | :key="item.type" |
| | | class="relative cursor-pointer flex flex-col items-center gap-0.5" |
| | | :class="{ 'map-type-active': activeSourceType === item.type }" |
| | | @click="changeSourceType(item.type)" |
| | | > |
| | | <img :src="item.img" class="w-full h-[60px] object-cover rounded" /> |
| | | <span>{{ item.label }}</span> |
| | | <span |
| | | v-show="activeSourceType === item.type" |
| | | class="ywifont absolute bottom-[25px] right-1 text-blue-500 text-lg" |
| | | ></span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts" name="LayerControl"> |
| | | import { computed, ref, watch, watchEffect } from 'vue'; |
| | | import type { OLMap } from '/@/model/map/OLMap'; |
| | | import { ElTree } from 'element-plus'; |
| | | import { computed, ref, watch } from 'vue'; |
| | | import type { OLMap } from '/@/model/map/OLMap'; |
| | | import { GaoDeSourceType, gaoDeSourceTypeMap } from '/@/model/map/OLMap'; |
| | | import { travelTree } from '/@/utils/util'; |
| | | |
| | | import terrainMap from '/@/assets/images/business/map/road_map.png'; |
| | | import satelliteMap from '/@/assets/images/business/map/satellite_map.png'; |
| | | import vectorMap from '/@/assets/images/business/map/vector_map.png'; |
| | | const props = defineProps(['olMap']); |
| | | const emit = defineEmits(['close']); |
| | | |
| | | const activeSourceType = computed(() => props.olMap.activeSourceType.value); |
| | | const defaultProps = { |
| | | children: 'children', |
| | | label: 'title', |
| | | }; |
| | | |
| | | const closeClick = () => { |
| | | emit('close'); |
| | | }; |
| | | const getIconText = (node, data) => { |
| | | if (data.type === 'equip') { |
| | | return '\ue63f'; |
| | | } else { |
| | | return data.icon ?? (node.expanded ? '\ue6b4' : ' \ue671'); |
| | | } |
| | | }; |
| | | |
| | | // 地图类型 |
| | | const mapTypes = [ |
| | | { |
| | | type: GaoDeSourceType.Vector, |
| | | label: gaoDeSourceTypeMap[GaoDeSourceType.Vector], |
| | | img: vectorMap, |
| | | }, |
| | | { |
| | | type: GaoDeSourceType.Satellite, |
| | | label: gaoDeSourceTypeMap[GaoDeSourceType.Satellite], |
| | | img: satelliteMap, |
| | | }, |
| | | { |
| | | type: GaoDeSourceType.SatelliteRoad, |
| | | label: gaoDeSourceTypeMap[GaoDeSourceType.SatelliteRoad], |
| | | img: terrainMap, |
| | | }, |
| | | ]; |
| | | const changeSourceType = (val: GaoDeSourceType) => { |
| | | props.olMap.setSourceType(val); |
| | | // props.olMap.applySourceType(val); |
| | | }; |
| | | const checkTreeRef = ref<InstanceType<typeof ElTree>>(); |
| | | |
| | | let isHumanCheckTrigger = false; |
| | | const handleCheck = (data: any, node: any) => { |
| | | console.log('🚀 ~ dataaa:', data); |
| | | const checkedKeys = node.checkedKeys; |
| | | isHumanCheckTrigger = true; |
| | | travelTree(layerInfo.value, (layer) => { |
| | | if (layer.type === 'layer') { |
| | | if (layer.type === 'layer' || layer.type === 'equip') { |
| | | const id = layer.id; |
| | | if (!checkedKeys.includes(id)) { |
| | | layer.isVisible = false; |
| | |
| | | } |
| | | } |
| | | }); |
| | | |
| | | props.olMap.displayFeatureInfo(null); |
| | | }; |
| | | |
| | | const handleNodeClick = () => {}; |
| | | const layerInfo = computed(() => (props.olMap as OLMap).layerInfo.value); |
| | | const layerInfo = computed(() => { |
| | | const info = (props.olMap as OLMap).layerInfo.value; |
| | | // const info = (props.olMap as OLMap).layerInfo.value.filter((item) => item.type !== 'equip'); |
| | | return info; |
| | | const result = info.concat([ |
| | | { |
| | | id: 'overlays', |
| | | title: '监测设备', |
| | | children: [], |
| | | |
| | | type: 'equip', |
| | | }, |
| | | ]); |
| | | return result; |
| | | }); |
| | | |
| | | watch( |
| | | () => layerInfo.value, |
| | |
| | | } |
| | | const keys = []; |
| | | travelTree(val, (item) => { |
| | | if (item.type === 'layer') { |
| | | if (item.type === 'layer' || item.type === 'equip') { |
| | | if (item.isVisible) { |
| | | keys.push(item.id); |
| | | } |
| | |
| | | } |
| | | ); |
| | | </script> |
| | | <style scoped lang="scss"></style> |
| | | <style scoped lang="scss"> |
| | | .map-type-active { |
| | | img { |
| | | border: 2px solid #1989fa; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | span:last-child { |
| | | color: #1989fa; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | </style> |