WholeProcessPlatform/frontend/src/components/gis/GisView.vue
2026-07-09 11:33:04 +08:00

190 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="gis-view">
<div id="mapContainer" />
<div ref="popupRef" class="map-popup-container" style="display: none"></div>
<!-- - 1. 切换菜单的时候图层没有切换 是因为接口的原因现在没有接口
2. 切换菜单的时候图例现在是不对的默认选中的数据他们没有做处理
-->
<!-- 地图图例 -->
<MapLegend />
<!-- 地图筛选器 -->
<MapFilter v-if="showMapFilter" :map="mapClass" />
<!-- 地图控制器 -->
<MapController :map="mapClass" :onClick="handleMapController" />
<!-- 基础图层切换器 -->
<BaseLayerSwitcher :map="mapClass" />
<!-- 梯级弹框 -->
<TjLayerModal v-model:open="tjModalVisible" />
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, onUnmounted, computed } from 'vue';
import MapLegend from '@/components/mapLegend/index.vue';
import MapFilter from '@/components/mapFilter/index.vue';
import MapController from '@/components/mapController/index.vue';
import BaseLayerSwitcher from '@/components/BaseLayerSwitcher/index.vue';
import TjLayerModal from './TjLayerModal.vue';
import { useRoute } from 'vue-router';
import { useMapOrchestrator } from '@/modules/map/application/map-orchestrator';
import { MapClass } from './map.class';
import { getQgcRvcd } from '@/api/map';
import { servers } from './mapurlManage';
const mapOrchestrator = useMapOrchestrator();
const route = useRoute();
const mapClass = MapClass.getInstance();
const mapIsInited = ref(false);
const tlyLayerVisible = ref(false);
const tjModalVisible = ref(false);
const popupRef = ref<HTMLDivElement | null>(null);
// 备注:根据当前路由生成页面配置 key供统一编排器加载页面地图配置。
const pageKey = computed(() => {
const path = route.path;
const parts = path.split('/');
if (parts.length >= 3) {
return parts[1] + '_' + parts[2];
}
return '';
});
// 备注:仅根据页面路径控制筛选器显隐,不在组件内承载地图业务逻辑。
const showMapFilter = computed(() => {
const path = route.path;
return !path.includes('dianZhanZhuanTi/dianZhanZhuanTi');
});
// 备注:仅保留当前菜单类型判断,缩放联动细节由编排器内部处理。
const isShuiDianKaiFaMenu = computed(() => {
return route.path.includes('home/shuiDianKaiFaZhuangKuang');
});
// 备注:页面只负责触发地图初始化,初始化后的缩放监听和基地监听由编排器接管。
const init = async () => {
const container = document.getElementById('mapContainer') as HTMLElement;
if (!container) return;
await mapOrchestrator.mountView({
container,
popupContainer: popupRef.value,
pageKey: pageKey.value,
getIsHydroMenu: () => isShuiDianKaiFaMenu.value
});
mapIsInited.value = true;
};
// 备注:地图控制器只分发简单视图切换命令,避免在页面入口堆叠复杂业务逻辑。
const handleMapController = async (e: any, mapType: any) => {
switch (e) {
case 'dim':
await mapClass.switchView(mapType);
break;
case 4: // 梯级流域显示
tlyLayerVisible.value = !tlyLayerVisible.value;
if (tlyLayerVisible.value) {
tjModalVisible.value = true;
fetchTjData();
} else {
tjModalVisible.value = false;
mapClass.hideTertiarybasinLayer(servers.Tertiarybasin);
}
break;
default:
break;
}
};
const fetchTjData = async () => {
const res = await getQgcRvcd({});
if (res && res.data) {
let datas = [];
for (let i = 0; i < res.data.data.length; i++) {
datas.push(res.data.data[i].rvcd);
}
mapClass.addTertiarybasinLayer(
servers.Tertiarybasin,
'#4DFFDD',
'#92A0A5',
datas
);
}
};
// 备注:页面切换后仅触发编排器重载页面,不在组件内继续拼装业务联动。
watch(
() => pageKey.value,
newVal => {
if (newVal && mapIsInited.value) {
void mapOrchestrator.handlePageChange(newVal, isShuiDianKaiFaMenu.value);
}
}
);
onMounted(() => {
init();
window.mapClass = mapClass;
});
onUnmounted(() => {
mapOrchestrator.unmountView();
mapClass.destroy();
});
</script>
<style lang="scss" scoped>
.gis-view {
width: 100%;
height: 100%;
position: absolute;
visibility: visible;
}
#mapContainer {
width: 100%;
height: 100%;
position: absolute;
background-color: #fff;
cursor: grab;
z-index: 1;
}
/* 消除瓦片之间的缝隙和默认边框 */
.leaflet-tile {
border: none !important;
margin: 0 !important;
padding: 0 !important;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
}
/* 确保地图容器背景色与瓦片一致,避免透出底色 */
.leaflet-container {
background-color: #fff;
}
/* 如果使用 Canvas 模式,确保 Canvas 没有边框 */
.leaflet-pane canvas {
border: none;
}
.map-popup-container {
z-index: 1000;
pointer-events: auto;
}
.custom-popup {
padding: 10px;
}
.custom-popup h4 {
margin: 0 0 5px 0;
color: #333;
}
.custom-popup p {
margin: 2px 0;
font-size: 12px;
color: #666;
}
</style>