<template>
|
<div class="layer-controls">
|
<span
|
v-show="!panelIsShow"
|
class="ywifont ywicon-jiegou !text-[20px] bg-black text-gray-300 p-2 cursor-pointer"
|
@click="triggerPanelClick"
|
></span>
|
|
<div class="relative">
|
<el-card
|
class="w-64 bg-white/90"
|
ref="layerControlCard"
|
v-show="panelIsShow"
|
:style="layerControlCardStyle"
|
@mousedown="startDrag"
|
>
|
<el-icon class="absolute top-2 right-2 cursor-pointer z-10" @click="closePanel">
|
<Close />
|
</el-icon>
|
|
<!-- <div class="search-box mb-2">
|
<el-input v-model="searchText" placeholder="请输入关键词搜索" :prefix-icon="Search" clearable size="small" />
|
</div> -->
|
|
<el-tabs v-model="activeTab">
|
<el-tab-pane label="底图" name="components"
|
><div class="flex flex-col gap-2">
|
<el-radio-group v-model="activeSourceType" class="flex flex-col gap-2" @change="changeSourceType">
|
<el-radio class="w-full mr-0" v-for="item in layerList" :key="item" :label="item">
|
<span>{{ gaoDeSourceTypeMap[item] }}</span>
|
</el-radio>
|
</el-radio-group>
|
</div></el-tab-pane
|
>
|
<el-tab-pane label="覆盖物" name="overlays">
|
<el-tree
|
class="w-full"
|
:data="treeData"
|
:props="defaultProps"
|
show-checkbox
|
node-key="id"
|
default-expand-all
|
:filter-node-method="filterNode"
|
ref="overlayTreeRef"
|
@check="handleCheck"
|
@node-click="handleNodeClick"
|
>
|
<template #default="{ node, data }">
|
<span>{{ node.label }}</span>
|
</template>
|
</el-tree>
|
</el-tab-pane>
|
<!-- <el-tab-pane label="覆盖层" name="overlays">
|
<el-tree
|
class="w-full"
|
:data="treeData"
|
:props="defaultProps"
|
show-checkbox
|
node-key="id"
|
default-expand-all
|
:filter-node-method="filterNode"
|
ref="overlayTreeRef"
|
@check="handleCheck"
|
>
|
<template #default="{ node, data }">
|
<span>{{ node.label }}</span>
|
</template>
|
</el-tree>
|
</el-tab-pane> -->
|
</el-tabs>
|
</el-card>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { Close } from '@element-plus/icons-vue';
|
import { ElTree } from 'element-plus';
|
import { computed, onMounted, ref, watch } from 'vue';
|
import { useDrag } from '/@/hooks/useDrag';
|
import type { OLMap } from '/@/model/map/OLMap';
|
import { GaoDeSourceType, gaoDeSourceTypeMap, OverlayType } from '/@/model/map/OLMap';
|
import { sleep } from '/@/utils/util';
|
const searchText = ref('');
|
const activeTab = ref('components');
|
const treeRef = ref();
|
const layerList = [GaoDeSourceType.Vector, GaoDeSourceType.Satellite, GaoDeSourceType.SatelliteRoad];
|
const props = defineProps<{
|
olMap: OLMap;
|
}>();
|
enum ROOT_OVERLAY_TYPE {
|
Marker = 'marker',
|
}
|
type TreeData = {
|
id: string;
|
label: string;
|
checked?: boolean;
|
children?: TreeData[];
|
};
|
const activeSourceType = ref(props.olMap.activeSourceType);
|
|
const changeSourceType = (val: GaoDeSourceType) => {
|
props.olMap.applySourceType(val);
|
};
|
|
const overlayTreeRef = ref<InstanceType<typeof ElTree>>();
|
|
const treeData = ref<TreeData[]>([
|
{
|
id: ROOT_OVERLAY_TYPE.Marker,
|
label: '设备',
|
},
|
]);
|
const initTreeChecked = () => {
|
treeData.value.forEach((item) => {
|
if (item.checked) {
|
overlayTreeRef.value?.setCheckedKeys([item.id]);
|
}
|
});
|
};
|
|
const setTreeChecked = (checked: boolean) => {
|
treeData.value.forEach((item) => {
|
if (checked) {
|
overlayTreeRef.value?.setCheckedKeys([ROOT_OVERLAY_TYPE.Marker]);
|
} else {
|
overlayTreeRef.value?.setCheckedKeys([]);
|
}
|
});
|
};
|
|
let isHumanCheckTrigger = false;
|
|
|
const handleNodeClick = (data: any, node: any) => {
|
if (data.id === ROOT_OVERLAY_TYPE.Marker) {
|
props.olMap.adjustViewToMarkers();
|
}
|
};
|
|
const iniTreeData = async () => {
|
await sleep(0.4);
|
const foundMarker = treeData.value.find((item) => item.id === ROOT_OVERLAY_TYPE.Marker);
|
if (!foundMarker) {
|
return;
|
}
|
foundMarker.children = props.olMap.map
|
.getOverlays()
|
.getArray()
|
.map((item) => {
|
const extData = item.get('extData');
|
return {
|
id: item.getId() as string,
|
label: extData?.name,
|
// checked: item.getVisible(),
|
};
|
});
|
};
|
const handleCheck = (data: any, node: any) => {
|
const checkedKeys = node.checkedKeys;
|
isHumanCheckTrigger = true;
|
const isVisible = checkedKeys.includes(ROOT_OVERLAY_TYPE.Marker);
|
props.olMap.toggleMarkerOverlayVisible(isVisible);
|
};
|
|
const layerControlCard = ref<HTMLDivElement>(null);
|
|
const { startDrag, style: layerControlCardStyle } = useDrag();
|
|
const defaultProps = {
|
children: 'children',
|
label: 'label',
|
};
|
|
const filterNode = (value: string, data: any) => {
|
if (!value) return true;
|
return data.label.toLowerCase().includes(value.toLowerCase());
|
};
|
|
const panelIsShow = ref(false);
|
const triggerPanelClick = () => {
|
panelIsShow.value = !panelIsShow.value;
|
};
|
const closePanel = () => {
|
panelIsShow.value = false;
|
};
|
|
watch(searchText, (val) => {
|
treeRef.value?.filter(val);
|
});
|
onMounted(() => {
|
initTreeChecked();
|
// iniTreeData();
|
// window.olMap = props.olMap;
|
// window.map = props.olMap.map;
|
});
|
defineEmits(['close']);
|
</script>
|
|
<style scoped>
|
:deep(.el-card__header) {
|
padding: 10px 15px;
|
}
|
:deep(.el-card__body) {
|
padding: 5px 10px;
|
}
|
.layer-controls {
|
position: absolute;
|
|
z-index: 1000;
|
}
|
|
:deep(.el-tabs__header) {
|
margin-bottom: 12px;
|
padding: 0px 0px;
|
}
|
:deep(.el-tabs__body) {
|
padding: 0px 0px;
|
}
|
:deep(.el-tabs__nav-wrap::after) {
|
height: 1px;
|
}
|
|
:deep(.el-tree-node__content) {
|
height: 32px;
|
}
|
|
:deep(.el-card) {
|
cursor: inherit;
|
}
|
|
:deep(.el-tree-node__expand-icon.is-leaf) {
|
display: none;
|
}
|
</style>
|