From 4c20089472b20319746649decbce3a11f16cb6a0 Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期五, 07 二月 2025 18:43:24 +0800 Subject: [PATCH] 切换主题,自身设置颜色、大小 --- src/model/map/OLMap.ts | 136 ++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 120 insertions(+), 16 deletions(-) diff --git a/src/model/map/OLMap.ts b/src/model/map/OLMap.ts index 7434965..648fc18 100644 --- a/src/model/map/OLMap.ts +++ b/src/model/map/OLMap.ts @@ -1,7 +1,6 @@ import { defaultsDeep } from 'lodash-es'; import type { Overlay } from 'ol'; import { Map as OpenLayerMap, View } from 'ol'; -import { ZoomSlider } from 'ol/control'; import type { Extent } from 'ol/extent'; import { getTopLeft, getWidth } from 'ol/extent'; import Tile from 'ol/layer/Tile'; @@ -10,10 +9,19 @@ import WMTS from 'ol/source/WMTS'; import WMTSTileGrid from 'ol/tilegrid/WMTS'; import type { ViewOptions } from 'ol/View'; - +import MVT from 'ol/format/MVT.js'; +import VectorTileLayer from 'ol/layer/VectorTile'; +import VectorTileSource from 'ol/source/VectorTile'; +import { defaults as olDefaults } from 'ol/interaction'; import type { Ref } from 'vue'; import { ref } from 'vue'; import { MarkerOverlay } from './overlay/marker'; +import { TileGrid } from 'ol/tilegrid'; +import Style from 'ol/style/Style'; +import Fill from 'ol/style/Fill'; +import Stroke from 'ol/style/Stroke'; +import Circle from 'ol/style/Circle'; + export type LangType = 'zh_cn' | 'en'; export const enum GaoDeSourceType { /** @description 榛樿鍦板浘 */ @@ -25,13 +33,17 @@ /** @description 褰卞儚璺綉 */ SatelliteRoad = 3, } +export const enum OverlayType { + Marker = 'marker', +} export const MARKER_OVERLAY_CLASS_NAME = 'marker-overlay'; export const gaoDeSourceTypeMap = { - [GaoDeSourceType.Default]: '榛樿鍦板浘', - [GaoDeSourceType.Satellite]: '褰卞儚鍦板浘', - [GaoDeSourceType.Vector]: '鐭㈤噺鍦板浘', - [GaoDeSourceType.SatelliteRoad]: '褰卞儚璺綉', + // [GaoDeSourceType.Default]: '榛樿鍦板浘', + [GaoDeSourceType.Vector]: '鏍囧噯鍦板浘', + + [GaoDeSourceType.Satellite]: '鍗槦鍦板浘', + [GaoDeSourceType.SatelliteRoad]: '璺綉鍦板浘', }; export const getGaoDeSourceUrl = (type: GaoDeSourceType, lang: LangType = 'zh_cn') => { @@ -43,19 +55,29 @@ }; return urlMap[type]; }; +type MapConfig = { + sourceType: GaoDeSourceType; + markerIsVisible: boolean; +}; type OLEventType = 'blackClick'; type OLMapOptions = { container: HTMLDivElement; view?: ViewOptions; -}; +} & MapConfig; + +const resolutions = []; +for (let i = 0; i <= 8; ++i) { + resolutions.push(156543.03392804097 / Math.pow(2, i * 2)); +} export class OLMap { map: OpenLayerMap; source: XYZ; private eventMap: Map<OLEventType, Function[]>; + activeSourceType: Ref<GaoDeSourceType> = ref(GaoDeSourceType.Vector); - overlayIsVisible: Ref<boolean> = ref(true); + markerIsVisible: Ref<boolean> = ref(true); private emit(eventName: OLEventType, ...args: any[]) { const handlers = this.eventMap?.get(eventName); if (handlers) { @@ -86,11 +108,13 @@ } constructor(options: OLMapOptions) { - const { container, view } = defaultsDeep(options, { + const { container, view, sourceType, markerIsVisible } = 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', @@ -108,15 +132,23 @@ target: container, // 缁戝畾 DOM 瀹瑰櫒 layers: [layer], // 娣诲姞鍥惧眰 view: new View(view), + interactions: olDefaults({ doubleClickZoom: false }), }); - this.setSourceUrl(this.activeSourceType.value); + this.activeSourceType.value = sourceType; + this.markerIsVisible.value = markerIsVisible; + this.applySourceType(this.activeSourceType.value); this.listenMapClick(); this.addBasicControl(); } - setSourceUrl(type: GaoDeSourceType = GaoDeSourceType.Vector) { + applySourceType(type: GaoDeSourceType = GaoDeSourceType.Vector) { const url = getGaoDeSourceUrl(type); this.source.setUrl(url); + } + + setSourceType(type: GaoDeSourceType = GaoDeSourceType.Vector) { + this.activeSourceType.value = type; + this.applySourceType(type); } addMarkerLayer(dataList: any[], options: any) { const { markerOpt } = options; @@ -143,12 +175,11 @@ stopEvent: false, className: 'z-[999]', }); - eleOverlay.setVisible(this.overlayIsVisible.value); + eleOverlay.setVisible(this.markerIsVisible.value); return eleOverlay; } - private createMarker(id: string, item: any, markerOpt: any): Overlay { // 鍒涘缓鍥剧墖鍏冪礌 const markerImg = document.createElement('img'); @@ -171,6 +202,7 @@ }); overlay.set('extData', item.extData); + overlay.set('type', OverlayType.Marker); // 娣诲姞鐐瑰嚮浜嬩欢 markerImg.addEventListener('click', (event) => { if (markerOpt.icon.selectUrl) { @@ -182,7 +214,18 @@ return overlay; } - adjustViewToOverlays(overlays: Overlay[]) { + adjustViewToMarkers() { + const overlays = this.map.getOverlays().getArray(); + + const filteredOverlays = overlays.filter((overlay) => { + const type = overlay.get('type'); + return type === OverlayType.Marker; + }); + this.adjustViewToOverlays(filteredOverlays); + } + + adjustViewToOverlays(overlays: Overlay[]) { + if (overlays.length === 0) return; const extent = overlays.reduce<number[] | null>((ext, item) => { const coord = item.getPosition(); @@ -228,12 +271,73 @@ } } }); - this.overlayIsVisible.value = visible; + 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() { - this.map.addControl(new ZoomSlider()); + // this.map.addControl(new ZoomSlider()); // this.map.addControl(new FullScreen()); + const container = this.map.getViewport(); + if (!container) return; + const olZoom = container.querySelector('.ol-zoom') as HTMLElement; + if (!olZoom) return; + olZoom.style.display = 'none'; + } + + /** + * 鏀惧ぇ鍦板浘 + */ + zoomIn() { + const view = this.map.getView(); + const zoom = view.getZoom(); + view.setZoom(zoom + 1); + } + + /** + * 缂╁皬鍦板浘 + */ + zoomOut() { + const view = this.map.getView(); + const zoom = view.getZoom(); + view.setZoom(zoom - 1); + } + + private tileUrlFunction(url) { + return (tileCoord) => + url + .replace('{z}', String(tileCoord[0] * 2 - 1)) + .replace('{x}', String(tileCoord[1])) + .replace('{y}', String(tileCoord[2])) + .replace('{a-d}', 'abcd'.substr(((tileCoord[1] << tileCoord[0]) + tileCoord[2]) % 4, 1)); + } + + addCustomLayer(url: string, style?: any) { + const vectorTileExtent = [13270414.528705932, 2994644.904997596, 13295641.139349712, 3018305.0256410106]; + + const vectorTileLayer = new VectorTileLayer({ + source: new VectorTileSource({ + format: new MVT(), + url: url, + }), + extent: vectorTileExtent, + style: style + }); + this.map.addLayer(vectorTileLayer); + return vectorTileLayer; } getWMTS = () => { -- Gitblit v1.9.3