From 675b88c80eb29aa9b239c6e183ea2a8d09860c8e Mon Sep 17 00:00:00 2001 From: gerson <1405270578@qq.com> Date: 星期日, 16 二月 2025 11:11:06 +0800 Subject: [PATCH] table 样式 --- src/model/map/OLMap.ts | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 419 insertions(+), 45 deletions(-) diff --git a/src/model/map/OLMap.ts b/src/model/map/OLMap.ts index 810b19e..1b5525b 100644 --- a/src/model/map/OLMap.ts +++ b/src/model/map/OLMap.ts @@ -18,13 +18,16 @@ import VectorSource from 'ol/source/Vector'; import VectorTileSource from 'ol/source/VectorTile'; import WMTS from 'ol/source/WMTS'; -import { Circle, Fill, Stroke, Style } from 'ol/style'; +import { Circle, Fill, Stroke, Style, Text } from 'ol/style'; import WMTSTileGrid from 'ol/tilegrid/WMTS'; import type { ViewOptions } from 'ol/View'; import type { Ref, ShallowRef } from 'vue'; import { markRaw, ref } from 'vue'; import { MarkerOverlay } from './overlay/marker'; -import { Text } from 'ol/style'; +import { Logger } from '../logger/Logger'; +import axios from 'axios'; +import WKT from 'ol/format/WKT'; +import { getCurrentPosition } from '/@/utils/brower'; export type LangType = 'zh_cn' | 'en'; export const enum GaoDeSourceType { @@ -61,7 +64,6 @@ }; type MapConfig = { sourceType: GaoDeSourceType; - markerIsVisible: boolean; }; type OLEventType = 'blackClick' | 'featureChange' | 'featureHoverChange'; @@ -79,6 +81,8 @@ map: OpenLayerMap; source: XYZ; private eventMap: Map<OLEventType, Function[]>; + /** @description 鎺掗櫎鏈仛鐨刲ayer锛屽悗缁叏閮ㄥ仛濂斤紝鍙互涓嶅仛鍒ゆ柇 */ + unsupportedLayers = []; /** @description 鍥惧眰鎺у埗淇℃伅 */ layerInfo = ref([] as any[]); @@ -89,9 +93,8 @@ themeInfo = ref([] as any[]); activeSourceType: Ref<GaoDeSourceType> = ref(GaoDeSourceType.Vector); - markerIsVisible: Ref<boolean> = ref(true); interactLayer: VectorLayer<VectorSource<Feature<Geometry>>, Feature<Geometry>> = null; - + searchHighlightLayer: VectorLayer<VectorSource<Feature<Geometry>>, Feature<Geometry>> = null; /** @description 褰撳墠婵�娲荤姸鎬� feature */ activeFeature: ShallowRef<FeatureLike> = ref(null); private emit(eventName: OLEventType, ...args: any[]) { @@ -124,13 +127,12 @@ } constructor(options: OLMapOptions) { - const { container, view, sourceType, markerIsVisible } = defaultsDeep(options, { + const { container, view, sourceType } = defaultsDeep(options, { view: { center: [13247019.404399557, 4721671.572580107], zoom: 8, }, sourceType: GaoDeSourceType.Vector, - markerIsVisible: true, } as OLMapOptions) as OLMapOptions; this.source = new XYZ({ crossOrigin: 'anonymous', @@ -150,11 +152,152 @@ view: new View(view), interactions: olDefaults({ doubleClickZoom: false }), }); + this.activeSourceType.value = sourceType; - this.markerIsVisible.value = markerIsVisible; this.applySourceType(this.activeSourceType.value); this.listenMapClick(); this.addBasicControl(); + this.initEvent(); + } + + gaodeApiKey = 'eea6302da02576fe3f3dd3ba1fbe0a04'; + + async locationCurrent() { + const position = await getCurrentPosition(); + if (!position) return; + const { latitude, longitude } = position; + + return; + const url = `https://restapi.amap.com/v5/ip/location?key=${this.gaodeApiKey}`; + const response = await axios.get(url); + } + + async gaodeAddressSearch(address) { + this.gaodeApiKey = 'eea6302da02576fe3f3dd3ba1fbe0a04'; + // const url = `https://restapi.amap.com/v3/assistant/inputtips?output=json&city=010&keywords=${address}=${this.gaodeApiKey}`; + // 鎼滅储 POI + const url = `https://restapi.amap.com/v3/place/text?keywords=${address}&city=fuzhou&offset=20&page=1&key=${this.gaodeApiKey}&extensions=all `; + // 鎼滅储 POI 2.0 + // const url = `https://restapi.amap.com/v5/place/text?keywords=${address}&city=beijing&offset=20&page=1&key=${this.gaodeApiKey}&extensions=all + + const response = await axios.get(url); + return response.data; + } + + displaySearchResult(resultList) { + // resultList = [ + // { + // OTYPE: 'WDM_JUNCTIONS', + // ONAME: 'd7513894-38d2-48b5-884a-f9a16fe1298a', + // WKT: 'SRID=3857;POINT(13280607.09109455 3009899.678848996)', + // }, + // { + // OTYPE: 'WDM_JUNCTIONS', + // ONAME: 'f2cbc0f8-de84-449e-9996-8b9425ea8438', + // WKT: 'SRID=3857;POINT(13274453.007984176 3006699.498741431)', + // }, + // { + // OTYPE: 'WDM_JUNCTIONS', + // ONAME: '2a08d246-639e-4169-862f-38bda3e98677', + // WKT: 'SRID=3857;POINT(13285466.77807223 3016023.513009545)', + // }, + // { + // OTYPE: 'WDM_JUNCTIONS', + // ONAME: '1bd4ea12-3a4c-4908-a73c-c5a8e14d20eb', + // WKT: 'SRID=3857;POINT(13282712.61192139 3016897.156892525)', + // }, + // { + // OTYPE: 'WDM_JUNCTIONS', + // ONAME: 'e6d0c5cb-00f5-47aa-846f-0705de983364', + // WKT: 'SRID=3857;POINT(13288425.224571886 3006456.3830214837)', + // }, + // { + // OTYPE: 'WDM_JUNCTIONS', + // ONAME: '6f83eff7-9e7b-46f8-8b1e-f18a69a98587_A', + // WKT: 'SRID=3857;POINT(13287645.018084045 3006696.595101201)', + // }, + // { + // OTYPE: 'WDM_JUNCTIONS', + // ONAME: 'acc43afb-7c59-44f2-a36d-0d22eb1b4594_A', + // WKT: 'SRID=3857;POINT(13286166.586277477 3009094.237136173)', + // }, + // { + // OTYPE: 'WDM_JUNCTIONS', + // ONAME: '8b449ce6-26ba-4c10-b18c-366ded424ec4', + // WKT: 'SRID=3857;POINT(13282290.543926762 3016028.715200386)', + // }, + // { + // OTYPE: 'WDM_JUNCTIONS', + // ONAME: 'a668fe7e-0d08-4cff-9045-1c27d14b9b61', + // WKT: 'SRID=3857;POINT(13278933.218610007 3014782.279195062)', + // }, + // { + // OTYPE: 'WDM_JUNCTIONS', + // ONAME: '6ccacce7-c65d-42b8-b5be-4c15ff648f99', + // WKT: 'SRID=3857;POINT(13275888.24189473 3002108.7952906396)', + // }, + // ]; + const first = resultList[0]; + let features = []; + if (first) { + const firstWktStr = first.WKT; + const srid = firstWktStr.match(/SRID=(\d+);/)?.[1]; + const standardWktStrList = resultList.map((item) => item.WKT.replace(/SRID=\d+;/, '')); + features = standardWktStrList.map((wktStr) => { + return new WKT().readFeature(wktStr, { + dataProjection: `EPSG:${srid}`, + // featureProjection: `EPSG:${srid}`, + }); + }); + } + this.highlightSearch(features); + } + + initEvent() { + const that = this; + this.map.on('moveend', function (e) { + const zoom = that.map.getView().getZoom(); //鑾峰彇褰撳墠鍦板浘鐨勭缉鏀剧骇鍒� + Logger.info('褰撳墠鍦板浘缂╂斁绾у埆涓猴細' + zoom); + }); + } + + hightLightColor: '0000FFFF'; + sizeRate: 0; + + getPointHighLightStyle(feature) { + if (!feature) return null; + let pSize = feature.get('psize') ?? 15; + pSize += pSize * 2; + + const pcolor = '0000FFFF'; + const pstyle = feature.get('pstyle'); + return this.getPointStyles({ color: pcolor, size: pSize, style: pstyle }); + } + + getLineHighLightStyle(feature) { + if (!feature) return null; + + const lcolor = this.hightLightColor; + let lsize = feature.get('lsize') ?? 15; + lsize += lsize * this.sizeRate; + const lstyle = feature.get('lstyle'); + return this.getLineStyles({ lsize: lsize, lcolor: lcolor, lstyle: lstyle }); + } + + getPolygonHighLightStyle(feature) { + if (!feature) return null; + + const lcolor = this.hightLightColor; + // return this.getPolygonStyles({ pcolor: lcolor, lstyle: 'default', lsize: 2 }); + return new Style({ + stroke: new Stroke({ + color: lcolor, + width: 5, + }), + // fill: new Fill({ + // color: lcolor, + // }), + }); } // 淇濆瓨鐐规牱寮忕紦瀛� @@ -167,7 +310,6 @@ */ getPointStyles(config: { size; color; style }) { const pSize = config.size; - if (!pSize) return null; const pcolor = config.color; const pstyle = config.style; @@ -192,6 +334,7 @@ this.pointStyeMap[pkey] = new Style({ text: new Text({ font: `${pSize}px "ywifont"`, + text: config?.text ?? '', fill: new Fill({ color: `#${pcolor}` }), }), @@ -223,12 +366,12 @@ * 鏍规嵁绾跨殑閰嶇疆鑾峰彇鏍峰紡 * @param config */ - getLineStyles(config: { lsize; lcolor; lstyle }) { + getLineStyles(config: { lsize; lcolor; lstyle; psize?; pcolor?; pstyle? }) { const lSize = config.lsize; if (!lSize) return null; const lColor = config.lcolor; const lstyle = config.lstyle; - + const styles = []; const lKey = `${lstyle}_${lSize}_${lColor}`; if (!this.lineStyleMap[lKey]) { const drawStyle = this.drawStyles.value.find((item) => item.id === lstyle + ''); @@ -245,7 +388,37 @@ }), }); } - return [this.lineStyleMap[lKey]]; + styles.push(this.lineStyleMap[lKey]); + + const hasPoint = Object.keys(config).some((key) => key === 'psize' && !!config[key]); + if (hasPoint) { + const psize = config.psize; + const pcolor = config.pcolor; + const pstyle = config.pstyle; + const pointStyle = this.getPointStyles({ size: psize, color: pcolor, style: pstyle }); + styles.push(pointStyle); + } + return styles; + } + polygonStyleMap: Record<string, Style> = {}; + getPolygonStyles(config: { pcolor; lstyle; lsize; lcolor }) { + const styles = []; + const pColor = config.pcolor; + const key = pColor; + if (!this.polygonStyleMap[key]) { + const polygonStyle = new Style({ + fill: new Fill({ color: `#${pColor}` }), + }); + styles.push(polygonStyle); + } + + const lineStyle = this.getLineStyles({ + lsize: config.lsize, + lcolor: config.lcolor, + lstyle: config.lstyle, + }); + lineStyle && styles.push(...lineStyle); + return styles; } private maxTextResolution = 1; @@ -288,13 +461,13 @@ */ getLabelStyles(config: { textContent; resolution }) { const textContent = config.textContent; - if(!textContent) return null; + if (!textContent) return null; const resolution = config.resolution; if (!textContent) return null; if (!this.labelStyleMap[textContent]) { this.labelStyleMap[textContent] = this.createTextStyle(textContent, resolution); } - return this.labelStyleMap[textContent] + return this.labelStyleMap[textContent]; } setDrawStyles(styles: any[]) { @@ -325,6 +498,22 @@ this.adjustViewToOverlays(markers); } + checkEquipIsShow() { + for (const item of this.layerInfo.value) { + if (item.id === 'equip') { + return item.isVisible; + } + } + return false; + } + + getEquipOverlay() { + for (const item of this.layerInfo.value) { + if (item.type === 'equip') { + return item; + } + } + } createEleOverlay(dom: string | HTMLElement, position = [0, 0]) { const ele = typeof dom === 'string' ? (document.querySelector(dom) as HTMLElement) : dom; if (!ele) return; @@ -335,7 +524,7 @@ stopEvent: false, className: 'z-[999]', }); - eleOverlay.setVisible(this.markerIsVisible.value); + eleOverlay.setVisible(this.checkEquipIsShow()); return eleOverlay; } @@ -425,18 +614,13 @@ this.emit('featureChange', feature, layer); } if (feature) { - console.log('馃殌 ~ feature:', feature); const otype = feature.get('otype'); - console.log('馃殌 ~ otype:', otype); const oname = feature.get('oname'); - console.log('馃殌 ~ oname:', oname); const geometryType = feature.getGeometry().getType(); - console.log('馃殌 ~ geometryType:', geometryType); const properties = feature.getProperties(); - console.log('馃殌 ~ properties:', properties); } + this.highlightSelect(feature); this.activeFeature.value = feature; - // this.displayFeatureInfo(feature); }); } @@ -444,23 +628,29 @@ this.themeInfo.value = themeInfo; } + getAllLayers() { + const allLayers = this.layerInfo.value.reduce((preVal, curVal) => { + if (curVal.children && curVal.children.length > 0) { + return preVal.concat(curVal.children.map((item) => item)); + } else { + return preVal; + } + }, []); + return allLayers; + } + + getAllLayerModels() { + return this.layerInfo.value.reduce((preVal, curVal) => { + if (curVal.children && curVal.children.length > 0) { + return preVal.concat(curVal.children.map((item) => item.model)); + } else { + return preVal; + } + }, []); + } + /** @description 璁板綍鎵�鏈夊浘灞� */ setAllLayers(layerModels: Layer[], layers: any[], layerGroup: any[]) { - // this.layerInfo.value = layerModels.map((layer, index) => { - // const layerData = layers[index]; - - // return { - // id: layerData.id, - // title: layerData.title, - // model: markRaw(layer), - // get isVisible() { - // return layer.getVisible(); - // }, - // set isVisible(val) { - // layer.setVisible(val); - // }, - // }; - // }); this.layerInfo.value = layerGroup.reduce((preVal, curVal) => { const group = curVal.group; const groupId = `group-${group}`; @@ -479,9 +669,20 @@ } const layer = layerModels[foundIndex]; const layerData = layers[foundIndex]; + //#region ====================== 璁剧疆缂╂斁绾у埆 ====================== + if (layerData?.max_ratio !== null) { + layer.setMaxZoom(layerData.max_ratio); + } + + if (layerData?.min_ratio !== null) { + layer.setMinZoom(layerData.min_ratio); + } + //#endregion + const data = { id: layerData.id, title: layerData.title, + icon: layerData.icon, model: markRaw(layer), get isVisible() { return layer.getVisible(); @@ -494,6 +695,21 @@ mapGroupItem.children.push(data); return preVal; }, []); + const that = this; + this.layerInfo.value.push({ + id: 'equip', + title: '鐩戞祴璁惧', + children: [], + _isVisible: true, + get isVisible() { + return this._isVisible; + }, + set isVisible(val) { + this._isVisible = val; + that.toggleMarkerOverlayVisible(val); + }, + type: 'equip', + }); } /** @@ -522,21 +738,17 @@ } } }); - this.markerIsVisible.value = visible; } getConfig(): MapConfig { return { sourceType: this.activeSourceType.value, - markerIsVisible: this.markerIsVisible.value, }; } setConfig(config: MapConfig) { this.activeSourceType.value = config.sourceType; - this.markerIsVisible.value = config.markerIsVisible; this.applySourceType(this.activeSourceType.value); - this.toggleMarkerOverlayVisible(this.markerIsVisible.value); } private addBasicControl() { @@ -583,6 +795,9 @@ source: new VectorTileSource({ format: new MVT(), url: url, + // minZoom:5, + // maxZoom:2 + // minZoom:12 }), extent: vectorTileExtent, style: style, @@ -590,14 +805,33 @@ this.map.addLayer(vectorTileLayer); return vectorTileLayer; } - - // highlightFeature = null; - displayFeatureInfo(feature) { + highlightFeature(feature) { const highlightStyle = { + // Point: new Style({ + // // image: new Circle({ + // // radius: 5, + // // fill: new Fill({ color: `blue` }), + // // }), + // image: new Circle({ + // radius: 13, + // stroke: new Stroke({ + // color: `blue`, + // width: 3, + // }), + // }), + // }), + // Point:this.getPointHighLightStyle.call(this,feature), Point: new Style({ + // image: new Circle({ + // radius: 5, + // fill: new Fill({ color: `blue` }), + // }), image: new Circle({ - radius: 5, - fill: new Fill({ color: `blue` }), + radius: 13, + stroke: new Stroke({ + color: `blue`, + width: 3, + }), }), }), LineString: new Style({ @@ -605,6 +839,15 @@ color: `blue`, width: 5, }), + }), + Polygon: new Style({ + stroke: new Stroke({ + color: `blue`, + width: 5, + }), + // fill: new Fill({ + // color: `rgba(0, 0, 255, 0.1)`, + // }), }), }; // 鍒涘缓楂樹寒鍥惧眰 @@ -618,10 +861,115 @@ }, }); } + } + + private searchHighlightStyle = { + // Point: new Style({ + // // image: new Circle({ + // // radius: 5, + // // fill: new Fill({ color: `blue` }), + // // }), + // image: new Circle({ + // radius: 13, + // stroke: new Stroke({ + // color: `blue`, + // width: 3, + // }), + // }), + // }), + // Point:this.getPointHighLightStyle.call(this,feature), + Point: new Style({ + // image: new Circle({ + // radius: 5, + // fill: new Fill({ color: `blue` }), + // }), + image: new Circle({ + radius: 13, + stroke: new Stroke({ + color: `yellow`, + width: 3, + }), + }), + }), + LineString: new Style({ + stroke: new Stroke({ + color: `yellow`, + width: 5, + }), + }), + Polygon: new Style({ + stroke: new Stroke({ + color: `yellow`, + width: 5, + }), + // fill: new Fill({ + // color: `rgba(0, 0, 255, 0.1)`, + // }), + }), + }; + + private selectHighlightStyle = { + // Point: new Style({ + // // image: new Circle({ + // // radius: 5, + // // fill: new Fill({ color: `blue` }), + // // }), + // image: new Circle({ + // radius: 13, + // stroke: new Stroke({ + // color: `blue`, + // width: 3, + // }), + // }), + // }), + // Point:this.getPointHighLightStyle.call(this,feature), + Point: new Style({ + // image: new Circle({ + // radius: 5, + // fill: new Fill({ color: `blue` }), + // }), + image: new Circle({ + radius: 13, + stroke: new Stroke({ + color: `blue`, + width: 3, + }), + }), + }), + LineString: new Style({ + stroke: new Stroke({ + color: `blue`, + width: 5, + }), + }), + Polygon: new Style({ + stroke: new Stroke({ + color: `blue`, + width: 5, + }), + // fill: new Fill({ + // color: `rgba(0, 0, 255, 0.1)`, + // }), + }), + }; + + highlightSelect(feature) { + // 鍒涘缓楂樹寒鍥惧眰 + if (!this.interactLayer) { + this.interactLayer = new VectorLayer({ + source: new VectorSource(), + map: this.map, + style: (feature) => { + const type = feature.getGeometry().getType(); + return this.selectHighlightStyle[type]; + }, + }); + } // 璁剧疆楂樹寒瑕佺礌 if (feature !== this.activeFeature.value) { if (this.activeFeature.value) { + console.log('remove feature:', this.activeFeature.value); this.interactLayer.getSource().removeFeature(this.activeFeature.value as any); } if (feature) { @@ -631,6 +979,32 @@ } } + private preSearchHighlightFeatures: Feature[] = []; + highlightSearch(features) { + if (!Array.isArray(features)) { + features = [features]; + } + // 鍒涘缓楂樹寒鍥惧眰 + if (!this.searchHighlightLayer) { + this.searchHighlightLayer = new VectorLayer({ + source: new VectorSource(), + map: this.map, + style: (feature) => { + const type = feature.getGeometry().getType(); + return this.searchHighlightStyle[type]; + }, + }); + } + if (this.preSearchHighlightFeatures && this.preSearchHighlightFeatures.length > 0) { + this.searchHighlightLayer.getSource().removeFeatures(this.preSearchHighlightFeatures); + } + + // 璁剧疆楂樹寒瑕佺礌 + if (features && features.length > 0) { + this.searchHighlightLayer.getSource().addFeatures(features); + } + this.preSearchHighlightFeatures = features; + } getWMTS = () => { const projection = getProjection('EPSG:3857'); const projectionExtent = projection.getExtent(); -- Gitblit v1.9.3