<template>
|
<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>
|
</div>
|
</div>
|
</div>
|
<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 { 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) => {
|
const checkedKeys = node.checkedKeys;
|
isHumanCheckTrigger = true;
|
travelTree(layerInfo.value, (layer) => {
|
if (layer.type === 'layer' || layer.type === 'equip') {
|
const id = layer.id;
|
if (!checkedKeys.includes(id)) {
|
layer.isVisible = false;
|
} else {
|
layer.isVisible = true;
|
}
|
}
|
});
|
|
props.olMap.displayFeatureInfo(null);
|
};
|
|
const handleNodeClick = () => {};
|
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,
|
(val) => {
|
if (isHumanCheckTrigger) {
|
isHumanCheckTrigger = false;
|
return;
|
}
|
const keys = [];
|
travelTree(val, (item) => {
|
if (item.type === 'layer' || item.type === 'equip') {
|
if (item.isVisible) {
|
keys.push(item.id);
|
}
|
}
|
});
|
// const keys = val.filter((item) => item.isVisible).map((item) => item.id);
|
checkTreeRef.value?.setCheckedKeys(keys);
|
}
|
);
|
</script>
|
<style scoped lang="scss">
|
.map-type-active {
|
img {
|
border: 2px solid #1989fa;
|
border-radius: 4px;
|
}
|
|
span:last-child {
|
color: #1989fa;
|
font-weight: bold;
|
}
|
}
|
</style>
|