From f07405d8787e8bbd43453c81ec4f599dc34153b9 Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期三, 02 四月 2025 16:44:34 +0800 Subject: [PATCH] Merge branch 'master' into huishui_iframe --- src/model/map/OLMap.ts | 348 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 335 insertions(+), 13 deletions(-) diff --git a/src/model/map/OLMap.ts b/src/model/map/OLMap.ts index d1d9a90..1666f55 100644 --- a/src/model/map/OLMap.ts +++ b/src/model/map/OLMap.ts @@ -3,7 +3,7 @@ import type { Overlay } from 'ol'; import { Feature, Map as OpenLayerMap, View } from 'ol'; import type { Extent } from 'ol/extent'; -import { extend, getTopLeft, getWidth } from 'ol/extent'; +import { extend, getCenter, getTopLeft, getWidth } from 'ol/extent'; import type { FeatureLike } from 'ol/Feature'; import MVT from 'ol/format/MVT.js'; import WKT from 'ol/format/WKT'; @@ -30,17 +30,21 @@ import { Logger } from '../logger/Logger'; import { MarkerOverlay } from './overlay/marker'; import { getCurrentPosition } from '/@/utils/brower'; +import { travelTree } from '/@/utils/util'; +import { ElLoadingService } from 'element-plus'; +import { switchMapTheme } from '/@/api/map'; +import { formatDate } from '/@/utils/formatTime'; export type LangType = 'zh_cn' | 'en'; export const enum GaoDeSourceType { /** @description 榛樿鍦板浘 */ - Default = 0, + Default = 'default', /** @description 褰卞儚鍦板浘 */ - Satellite = 1, + Satellite = 'satellite', /** @description 鐭㈤噺鍦板浘 */ - Vector = 2, + Vector = 'standard', /** @description 褰卞儚璺綉 */ - SatelliteRoad = 3, + SatelliteRoad = 'road_network', } export const enum OverlayType { Marker = 'marker', @@ -88,6 +92,9 @@ /** @description 鍥惧眰鎺у埗淇℃伅 */ layerInfo = ref([] as any[]); + + /** @description 鍥惧眰鎺у埗淇℃伅 */ + legendList = ref([] as any[]); drawStyles = ref([] as any[]); @@ -400,6 +407,7 @@ const zoom = that.map.getView().getZoom(); //鑾峰彇褰撳墠鍦板浘鐨勭缉鏀剧骇鍒� Logger.info('褰撳墠鍦板浘缂╂斁绾у埆涓猴細' + zoom); }); + this.pointermove(); } hightLightColor: '0000FFFF'; @@ -762,8 +770,11 @@ layers.push(layer); }); const feature = features[0]; + feature?.get('click')?.(event); + const layer = layers[0]; if (layer === this.drawLayer) return; + this.labelOverlay?.setVisible(false); if (feature !== this.activeFeature.value) { this.emit('featureChange', feature, layer); @@ -813,7 +824,6 @@ // 鍚堝苟鑼冨洿 return extend(extent, layerExtent); }, extent); - } // 鑱氱劍鍒板悎骞跺悗鐨勮寖鍥� @@ -831,6 +841,189 @@ return preVal; } }, []); + } + + setLayerVisible(layerId: string, visible: boolean) { + const layer = this.getAllLayers().find((item) => item.id === layerId); + if (layer) { + layer.isVisible = visible; + } + } + + setThemeById(themeId: string) { + let group; + let theme; + travelTree(this.themeInfo.value, (item, index, array, parent) => { + if (item.type === 'theme' && item.id === themeId) { + group = parent; + theme = item; + return true; + } + }); + if (group) { + group.activeTheme = themeId; + this.handleThemeChange(themeId, group); + } + } + + async changeTheme(ids: string) { + const loadingInstance = ElLoadingService({ + text: '鍔犺浇涓婚涓�...', + target: '.layout-parent', + }); + const res = await switchMapTheme({ + theme_id: ids, + time: formatDate(new Date()), + }).finally(() => { + loadingInstance.close(); + }); + + // 鍔犲叆涓婚涔嬪悗鐨勬牱寮忓嚱鏁� + const themeLayerStyleFunc = (feature, resolution) => { + const otype = feature.get('otype'); + const oname = feature.get('oname'); + // oname 鏄犲皠鏍峰紡 + const onameStyleMap = res?.[`O_${otype}`] ?? {}; + const themeStyles = res?.styles ?? []; + const styleIndex = onameStyleMap[oname]?.style_id; + const themeStyle = styleIndex == null ? null : themeStyles[styleIndex]; + // if(themeStyle){ + // } + const shape = feature.getGeometry().getType(); + const styles = []; + switch (shape) { + case 'Point': + const pSize = themeStyle?.PSIZE ?? feature.get('psize'); + + const pcolor = themeStyle?.PCOLOR ?? feature.get('pcolor'); + + const pStyle = themeStyle?.PSTYLE ?? feature.get('pstyle'); + + const pointStyle = this.getPointStyles({ + size: pSize, + color: pcolor, + style: pStyle, + }); + pointStyle && styles.push(pointStyle); + break; + case 'LineString': + const lSize = themeStyle?.LSIZE ?? feature.get('lsize'); + const lColor = themeStyle?.LCOLOR ?? feature.get('lcolor'); + const lStyle = themeStyle?.LSTYLE ?? feature.get('lstyle'); + + const pSize1 = themeStyle?.PSIZE ?? feature.get('psize'); + const pcolor1 = themeStyle?.PCOLOR ?? feature.get('pcolor'); + const pStyle1 = themeStyle?.PSTYLE ?? feature.get('pstyle'); + + const lineStyle = this.getLineStyles({ + lsize: lSize, + lcolor: lColor, + lstyle: lStyle, + psize: pSize1, + pcolor: pcolor1, + pstyle: pStyle1, + }); + lineStyle && styles.push(...lineStyle); + + break; + case 'Polygon': + const pColor = themeStyle?.PCOLOR ?? feature.get('pcolor'); + const lSize1 = themeStyle?.LSIZE ?? feature.get('lsize'); + const lColor1 = themeStyle?.LCOLOR ?? feature.get('lcolor'); + const lstyle1 = themeStyle?.LSTYLE ?? feature.get('lstyle'); + const polygonStyle = this.getPolygonStyles({ + pcolor: pColor, + lsize: lSize1, + lcolor: lColor1, + lstyle: lstyle1, + }); + polygonStyle && 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 = themeStyle?.TSTRING ?? feature.get('tstring'); + const tStringStyle = this.getLabelStyles({ + textContent: tString, + resolution, + }); + tStringStyle && styles.push(tStringStyle); + //#endregion + + return styles; + }; + const allLayers = this.getAllLayers(); + for (const item of allLayers) { + if (this.unsupportedLayers.includes(item.id)) { + continue; + } + item.model.setStyle(themeLayerStyleFunc); + } + return res?.legends ?? []; + } + + async handleThemeChange(val?, themeGroup?) { + const allIds = []; + for (const item of this.themeInfo.value) { + if (item.activeTheme) { + allIds.push(item.activeTheme); + } + } + const ids = allIds.join(','); + + if (!ids) { + const allLayers = this.getAllLayerModels(); + for (const item of allLayers) { + const originStyle = item.get('originStyle'); + originStyle && item.setStyle(originStyle); + } + return; + } + const legends = await this.changeTheme(ids); + this.legendList.value = this.parseLegends(legends); + } + + parseLegends(legends) { + const result = legends.map((item) => { + const isEqual = item.operate === '='; + const result = { + ...item, + legend: item.legend.map((legendItem, index, array) => { + const preItem = array[index - 1]; + let label = ''; + if (isEqual) { + label = legendItem.value; + } else if (preItem) { + label = `>${preItem.value}涓�${item.operate}${legendItem.value}`; + } else { + label = `${item.operate}${legendItem.value}`; + } + return { + ...legendItem, + label: label, + }; + }), + }; + + result.legend.push({ + style: item.default, + value: '', + label: result.legend.length == 0 ? '榛樿' : `>${item.legend[item.legend.length - 1].value}`, + }); + return result; + }); + return result; } /** @description 璁板綍鎵�鏈夊浘灞� */ @@ -948,19 +1141,59 @@ /** * 鏀惧ぇ鍦板浘 */ - zoomIn() { + zoomIn(offsetLevel = 1) { const view = this.map.getView(); const zoom = view.getZoom(); - view.setZoom(zoom + 1); + view.setZoom(zoom + offsetLevel); } /** * 缂╁皬鍦板浘 */ - zoomOut() { + zoomOut(offsetLevel = 1) { const view = this.map.getView(); const zoom = view.getZoom(); - view.setZoom(zoom - 1); + view.setZoom(zoom - offsetLevel); + } + + /** + * 鍦板浘宸︾Щ + */ + panLeft(offset = 1000) { + const view = this.map.getView(); + const center = view.getCenter(); + if (!center) return; + view.setCenter([center[0] - offset, center[1]]); + } + + /** + * 鍦板浘鍙崇Щ + */ + panRight(offset = 1000) { + const view = this.map.getView(); + const center = view.getCenter(); + if (!center) return; + view.setCenter([center[0] + offset, center[1]]); + } + + /** + * 鍦板浘涓婄Щ + */ + panUp(offset = 1000) { + const view = this.map.getView(); + const center = view.getCenter(); + if (!center) return; + view.setCenter([center[0], center[1] + offset]); + } + + /** + * 鍦板浘涓嬬Щ + */ + panDown(offset = 1000) { + const view = this.map.getView(); + const center = view.getCenter(); + if (!center) return; + view.setCenter([center[0], center[1] - offset]); } private tileUrlFunction(url) { @@ -1163,11 +1396,85 @@ } } + private labelOverlay: MarkerOverlay = null; + private initLabelOverlay() { + if (this.labelOverlay) return; + // 鍒涘缓涓�涓� div 鍏冪礌鐢ㄤ簬鏄剧ず鏍囩 + const labelElement = document.createElement('div'); + labelElement.className = 'ol-label-overlay'; + labelElement.style.position = 'relative'; + labelElement.style.background = 'rgba(0,0,0,0.6)'; + labelElement.style.borderRadius = '4px'; + labelElement.style.color = '#fff'; + labelElement.style.padding = '4px 8px'; + labelElement.style.whiteSpace = 'nowrap'; + labelElement.style.fontSize = '12px'; + labelElement.style.transform = 'translate(-50%, -100%)'; + labelElement.style.marginBottom = '8px'; + + // 鍒涘缓 overlay + this.labelOverlay = new MarkerOverlay({ + element: labelElement, + offset: [0, 0], + positioning: 'bottom-center', + }); + + // 娣诲姞鍒板湴鍥� + this.map.addOverlay(this.labelOverlay); + } private preSearchHighlightFeatures: Feature[] = []; highlightSearch(features) { if (!Array.isArray(features)) { features = [features]; } + + const positionFeatures = features.map((feature, index, array) => { + const geometry = feature.getGeometry(); + const center = geometry.getExtent ? getCenter(geometry.getExtent()) : geometry.getCoordinates(); + + // 鍒涘缓涓�涓柊鐨凢eature鐢ㄤ簬鏄剧ず瀛椾綋鍥炬爣 + const iconFeature = new Feature({ + geometry: new Point(center), + }); + + // 璁剧疆瀛椾綋鍥炬爣鏍峰紡 + // 娣诲姞鐐瑰嚮浜嬩欢鐩戝惉 + // iconFeature.set('click', (event) => { + // // 鍒濆鍖� labelOverlay + // this.initLabelOverlay(); + // // 鑾峰彇鐐瑰嚮浣嶇疆鐨勫潗鏍� + // const coordinate = event.coordinate; + // // 璁剧疆 labelOverlay 鐨勫唴瀹瑰拰浣嶇疆 + // const element = this.labelOverlay.getElement(); + // element.innerHTML = `绗�${index + 1}涓綅缃甡; + // this.labelOverlay.setPosition(coordinate); + // }); + + iconFeature.setStyle([ + new Style({ + text: new Text({ + text: '\ue642', // 浣跨敤瀛椾綋鍥炬爣鐨剈nicode缂栫爜 + font: '24px "ywifont"', // 璁剧疆瀛椾綋澶у皬鍜屽瓧浣撳悕绉� + fill: new Fill({ + color: '#1677ff', + }), + offsetY: -20, // 璋冩暣鍥炬爣浣嶇疆 + }), + }), + new Style({ + text: new Text({ + text: array.length === 1 ? '' : index + 1, // 娣诲姞鏁板瓧 + font: '14px Arial', // 璁剧疆鏁板瓧瀛椾綋 + fill: new Fill({ + color: '#ffffff', // 鏁板瓧棰滆壊璁句负鐧借壊 + }), + offsetY: -20, // 涓庡浘鏍囦繚鎸佺浉鍚岀殑鍋忕Щ + }), + }), + ]); + + return iconFeature; + }); // 鍒涘缓楂樹寒鍥惧眰 if (!this.searchHighlightLayer) { this.searchHighlightLayer = new VectorLayer({ @@ -1184,11 +1491,26 @@ } // 璁剧疆楂樹寒瑕佺礌 - if (features && features.length > 0) { - this.searchHighlightLayer.getSource().addFeatures(features); + if (positionFeatures && positionFeatures.length > 0) { + this.searchHighlightLayer.getSource().addFeatures(positionFeatures); } - this.preSearchHighlightFeatures = features; + this.preSearchHighlightFeatures = positionFeatures; } + + pointermove() { + this.map.on('pointermove', (e) => { + if (this.map.hasFeatureAtPixel(e.pixel)) { + this.map.getViewport().style.cursor = 'pointer'; + } else { + this.map.getViewport().style.cursor = 'inherit'; + } + }); + } + + clearMarker() { + this.clearObjectSearch(); + } + getWMTS = () => { const projection = getProjection('EPSG:3857'); const projectionExtent = projection.getExtent(); -- Gitblit v1.9.3