From e50196bff10f0196307b2567ed6c0829eadd8ff6 Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期一, 10 二月 2025 12:12:25 +0800 Subject: [PATCH] 设备显示隐藏 --- src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/BasicMap.vue | 336 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 329 insertions(+), 7 deletions(-) diff --git a/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/BasicMap.vue b/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/BasicMap.vue index 912640b..ee1ac3e 100644 --- a/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/BasicMap.vue +++ b/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/BasicMap.vue @@ -34,39 +34,83 @@ </div> </div> </div> - <LayerControl v-if="olMap" :olMap="olMap" class="absolute top-3 left-3 z-10" /> + <!-- <LayerControl v-if="olMap" :olMap="olMap" class="absolute top-3 left-3 z-10" /> --> + + <!-- <PropertyPanel class="absolute top-14 left-10 z-14"></PropertyPanel> --> + <PanelTool + v-if="olMap" + ref="panelToolRef" + :propertyMap="propertyMap" + :propertyConfigMap="propertyConfigMap" + class="absolute top-0 right-2 z-14 h-full" + :olMap="olMap" + :isFullscreen="isFullscreen" + @toggleFullScreen="toggleFullScreen" + ></PanelTool> + <!-- <el-button class="absolute top-3 right-4" @click="changeTheme" type="primary">鍒囨崲涓婚</el-button> --> </div> </template> <script setup lang="ts" name="BasicMap"> -import type { Overlay } from 'ol'; +import { reverse } from 'lodash-es'; +import type { Feature, Overlay } from 'ol'; +import type { FeatureLike } from 'ol/Feature'; +import type Layer from 'ol/layer/Layer'; +import type VectorTileLayer from 'ol/layer/VectorTile'; import 'ol/ol.css'; - +import type LayerRenderer from 'ol/renderer/Layer'; +import type Source from 'ol/source/Source'; +import { Text } from 'ol/style'; +import Circle from 'ol/style/Circle'; +import Fill from 'ol/style/Fill'; +import Stroke from 'ol/style/Stroke'; +import Style from 'ol/style/Style'; import { computed, onMounted, ref, shallowRef } from 'vue'; import equipSelectPic from './img/equip-select.svg'; import equipPic from './img/equip.svg'; import LayerControl from './LayerControl.vue'; +import PanelTool from './panelTool/index.vue'; +import { + getMapDrawStyles, + getMapLayerGroupList, + getMapLayersByPost, + getMapThemeList, + getMapVpropsByPost, + getMapVpropsConfigByPost, + switchMapTheme, +} from '/@/api/map'; +import { MAIN_URL } from '/@/constants'; import { GaoDeSourceType, OLMap } from '/@/model/map/OLMap'; +import { MarkerOverlay } from '/@/model/map/overlay/marker'; +import { useCompRef } from '/@/utils/types'; +import { formatDate } from '/@/utils/formatTime'; +import { MapPanelTool } from './types'; + +const panelToolRef = useCompRef(PanelTool); const props = withDefaults( defineProps<{ data: any; config?: { sourceType: GaoDeSourceType; - markerIsVisible: boolean; }; + isFullscreen: boolean; }>(), { config: () => ({ sourceType: GaoDeSourceType.Vector, - markerIsVisible: true, }), } ); + const colsArray = computed(() => { return props.data.cols ?? []; }); -const emit = defineEmits(['markerClick', 'closeInfoWindow']); +const emit = defineEmits(['markerClick', 'closeInfoWindow','toggleFullScreen']); + +const toggleFullScreen = () => { + emit('toggleFullScreen'); +}; const containerRef = ref<HTMLDivElement>(null); const infoWindowRef = ref<HTMLDivElement>(null); @@ -132,15 +176,291 @@ }, }); }; + +const hoverStyleMap = {}; + +const resetLastActiveStyle = () => { + if (!olMap.value.activeFeature.value) return; + const originStyle = olMap.value.activeFeature.value?.get('originStyle'); + + (olMap.value.activeFeature.value as Feature).setStyle(originStyle); +}; + +const setActiveStyle = (feature: FeatureLike, layer: Layer<Source, LayerRenderer<any>>) => { + resetLastActiveStyle(); + + const geometryType = feature.getGeometry().getType(); + const otype = feature.get('otype'); + const key = `${geometryType}_${otype}`; + const style = hoverStyleMap[key]; + const source = layer.getSource(); + + // const isFeatureLike = feature instanceof FeatureLike; + const curStyle = feature?.getStyle(); + if (curStyle) { + feature.set('originStyle', curStyle); + } + if (style) { + feature?.setStyle(style); + } else { + let style = null; + if (geometryType === 'Point') { + style = new Style({ + image: new Circle({ + radius: 5, + fill: new Fill({ color: 'yellow' }), + }), + }); + } else if (geometryType === 'LineString') { + style = new Style({ + stroke: new Stroke({ + color: 'yellow', + width: 2, + }), + }); + } + if (style) { + feature?.setStyle(style); + hoverStyleMap[key] = style; + } + } +}; + +const overlayLabelMap = {}; + +const renderFeatureLabel = new Set(); + +const setOverlayLabel = (feature: FeatureLike, resolution: any) => { + const oname = feature.get('oname'); + const otype = feature.get('otype'); + const key = `${oname}_${otype}`; + if (resolution > 30) { + const overlay = overlayLabelMap[key]; + if (overlay) { + (overlay as MarkerOverlay).setVisible(false); + } + return; + } + + if (overlayLabelMap.hasOwnProperty(key)) { + return; + } + + const position = (feature as any).getFlatCoordinates(); + const div = document.createElement('div'); + + div.innerHTML = `first-${oname[0]}`; + const overlay = new MarkerOverlay({ + position, + element: div, + stopEvent: false, + }); + // overlayLabelMap[key] = overlay; + // renderFeatureLabel.add(olUid); + renderFeatureLabel.add(key); + overlayLabelMap[key] = overlay; + + olMap.value.map.addOverlay(overlay); +}; + +const handleVectorTileClick = (feature, layer) => { + panelToolRef.value.featureClick(feature); + feature && panelToolRef.value.setActivePanel(MapPanelTool.Property); + // setActiveStyle(feature,layer); +}; +const propertyMap = ref({}); +const propertyConfigMap = ref({}); +const getPropertyList = async () => { + const res = await getMapVpropsByPost(); + const otypes = res?.otypes ?? {}; + propertyMap.value = otypes; + + const res1 = await getMapVpropsConfigByPost(); + propertyConfigMap.value = res1?.values ?? {}; +}; + +const maxResolution = 1; + +const getText = function (textContent, resolution) { + let text = `${textContent}`; + if (resolution > maxResolution) { + text = ''; + } + + // else if (type == 'hide') { + // text = ''; + // } else if (type == 'shorten') { + // text = text.trunc(12); + // } else if (type == 'wrap' && (!dom.placement || dom.placement.value != 'line')) { + // text = stringDivider(text, 16, '\n'); + // } + + return text; +}; +const createTextStyle = (textContent, resolution) => { + return new Style({ + text: new Text({ + text: getText(textContent, resolution), + font: '14px Arial', + fill: new Fill({ color: '#000' }), + stroke: new Stroke({ color: '#fff', width: 2 }), + offsetX: 10, // 鏂囧瓧鐩稿浜庡嚑浣曚腑蹇冪殑姘村钩鍋忕Щ + offsetY: 20, // 鏂囧瓧鐩稿浜庡嚑浣曚腑蹇冪殑鍨傜洿鍋忕Щ + }), + }); +}; + +const styleMap: Record<string, Record<string, Style>> = { + point: {}, + line: {}, + polygon: {}, +}; + +const unsupportedLayers = ['dma1', 'dma2', 'dma3']; +const layerStyleFunc = function (feature, resolution) { + const shape = feature.getGeometry().getType(); + const styles = []; + switch (shape) { + case 'Point': + const pSize = feature.get('psize'); + + const pcolor = feature.get('pcolor'); + const pstyle = feature.get('pstyle'); + const pointStyle = olMap.value.getPointStyles({ + size: pSize, + color: pcolor, + style: pstyle, + }); + + styles.push(pointStyle); + break; + case 'LineString': + const lSize = feature.get('lsize'); + const lColor = feature.get('lcolor'); + const lstyle = feature.get('lstyle'); + const pSize1 = feature.get('psize'); + const pcolor1 = feature.get('pcolor'); + const pStyle1 = feature.get('pstyle'); + const lineStyle = olMap.value.getLineStyles({ + lsize: lSize, + lcolor: lColor, + lstyle: lstyle, + psize: pSize1, + pcolor: pcolor1, + pstyle: pStyle1, + }); + styles.push(...lineStyle); + break; + case 'Polygon': + const pColor = feature.get('pcolor'); + const lSize1 = feature.get('lsize'); + const lColor1 = feature.get('lcolor'); + const lstyle1 = feature.get('lstyle'); + const polygonStyle = olMap.value.getPolygonStyles({ + pcolor: pColor, + lsize: lSize1, + lcolor: lColor1, + lstyle: lstyle1, + }); + styles.push(...polygonStyle); + break; + default: + break; + } + + // switch (otype) { + // case 'WDM_JUNCTIONS': + // const textStyle = createTextStyle(feature, resolution); + // styles.push(textStyle); + + // case 'WDM_PIPES': + // break; + // } + //#region ====================== 娣诲姞鏍囨敞 ====================== + const tString = feature.get('tstring'); + + const tStringStyle = olMap.value.getLabelStyles({ + textContent: tString, + resolution, + }); + if (tStringStyle) { + styles.push(tStringStyle); + } + //#endregion + + return styles; +}; + +const getGroupList = async () => { + const res = await getMapLayerGroupList(); + const groupList = res?.values ?? []; + return groupList; +}; + +const getDrawStyles = async () => { + const res = await getMapDrawStyles(); + const styleList = res?.values ?? []; + // console.log("馃殌 ~ styleList:", styleList) + olMap.value.setDrawStyles(styleList); +}; + +const getThemeList = async () => { + const res = await getMapThemeList(); + const themeList = res?.values ?? []; + const themeTreeData = themeList.reduce((preVal, curVal) => { + const group = curVal.group; + const groupId = `group-${group}`; + let mapGroupItem = preVal.find((item) => item.id === groupId); + if (!mapGroupItem) { + mapGroupItem = { id: groupId, title: group, type: 'theme-group' }; + preVal.push(mapGroupItem); + } + if (!mapGroupItem.children) { + mapGroupItem.children = []; + } + const id = curVal.id; + const data = { + id, + title: curVal.title, + type: 'theme', + activeTheme: null, + legends: null, + }; + mapGroupItem.children.push(data); + return preVal; + }, []); + olMap.value.setAllThemes(themeTreeData); +}; +const initVectorTileLayer = async () => { + await getDrawStyles(); + const res = await getMapLayersByPost(); + const layers = reverse(res?.layers ?? []); + if (layers.length === 0) return; + const layerModels = []; + for (const item of layers) { + const styleFunc = olMap.value.unsupportedLayers.includes(item.id) ? undefined : layerStyleFunc; + const layer = olMap.value.addCustomLayer(`${MAIN_URL}map/get_vector_tile?x={x}&y={y}&z={z}&layer_id=${item.id}`, styleFunc); + + layer.set('originStyle', styleFunc); + layerModels.push(layer); + } + getGroupList().then((groupList) => { + olMap.value.setAllLayers(layerModels, layers, groupList); + }); + getThemeList(); + getPropertyList(); + olMap.value.on('featureChange', handleVectorTileClick); +}; const initMap = () => { olMap.value = new OLMap({ container: containerRef.value, sourceType: props.config?.sourceType, - markerIsVisible: props.config?.markerIsVisible, }); + addMarkerLayer(); infoWindowOverlay = olMap.value.createEleOverlay(infoWindowRef.value); olMap.value.map.addOverlay(infoWindowOverlay); + initVectorTileLayer(); }; defineExpose({ @@ -149,6 +469,8 @@ onMounted(() => { initMap(); + // window.olMap = olMap.value; + // window.map = olMap.value.map; }); </script> <style scoped lang="scss"></style> -- Gitblit v1.9.3