| | |
| | | </div> |
| | | </div> |
| | | <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-12 right-2 z-14" |
| | | :olMap="olMap" |
| | | ></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'; |
| | | |
| | | const panelToolRef = useCompRef(PanelTool); |
| | | const props = withDefaults( |
| | | defineProps<{ |
| | | data: any; |
| | |
| | | }), |
| | | } |
| | | ); |
| | | |
| | | const colsArray = computed(() => { |
| | | return props.data.cols ?? []; |
| | | }); |
| | |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | 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); |
| | | // 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: {}, |
| | | }; |
| | | /** @description 已经做的layer,后续全部做好,可以不做判断 */ |
| | | 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 lineStyle = olMap.value.getLineStyles({ |
| | | lsize: lSize, |
| | | lcolor: lColor, |
| | | lstyle: lstyle, |
| | | }); |
| | | styles.push(...lineStyle); |
| | | break; |
| | | case 'Polygon': |
| | | 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 ?? []; |
| | | 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 = 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({ |
| | |
| | | |
| | | onMounted(() => { |
| | | initMap(); |
| | | // window.olMap = olMap.value; |
| | | // window.map = olMap.value.map; |
| | | }); |
| | | </script> |
| | | <style scoped lang="scss"></style> |