From 6a71c216a24a6623e4aa0b45d7c3240562c09c96 Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期一, 17 二月 2025 10:38:17 +0800 Subject: [PATCH] 定位高亮 --- src/model/map/OLMap.ts | 246 +++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 226 insertions(+), 20 deletions(-) diff --git a/src/model/map/OLMap.ts b/src/model/map/OLMap.ts index 6f8f29b..a586b7c 100644 --- a/src/model/map/OLMap.ts +++ b/src/model/map/OLMap.ts @@ -18,16 +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 { Select } from 'ol/interaction'; -import { click } from 'ol/events/condition'; -import { Polygon } from 'ol/geom'; +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 { @@ -94,7 +94,7 @@ activeSourceType: Ref<GaoDeSourceType> = ref(GaoDeSourceType.Vector); 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[]) { @@ -152,10 +152,68 @@ view: new View(view), interactions: olDefaults({ doubleClickZoom: false }), }); + this.activeSourceType.value = sourceType; 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; + } + + readWKT(wktStr) { + const srid = wktStr.match(/SRID=(\d+);/)?.[1]; + const standardWktStr = wktStr.replace(/SRID=\d+;/, ''); + const feature = new WKT().readFeature(standardWktStr, { + dataProjection: `EPSG:${srid}`, + }); + return feature; + } + + clearObjectSearch() { + this.highlightSearch([]); + } + + displaySearchResult(searchItem) { + if (!searchItem?.WKT) return; + const feature = this.readWKT(searchItem.WKT); + this.highlightSearch(feature); + const geometry = feature.getGeometry(); + + const center = geometry.getCoordinates(); + this.map.getView().setCenter(center); + this.map.getView().setZoom(16); + } + + initEvent() { + const that = this; + this.map.on('moveend', function (e) { + const zoom = that.map.getView().getZoom(); //鑾峰彇褰撳墠鍦板浘鐨勭缉鏀剧骇鍒� + Logger.info('褰撳墠鍦板浘缂╂斁绾у埆涓猴細' + zoom); + }); } hightLightColor: '0000FFFF'; @@ -164,11 +222,10 @@ getPointHighLightStyle(feature) { if (!feature) return null; let pSize = feature.get('psize') ?? 15; - pSize += pSize * this.sizeRate; + pSize += pSize * 2; - const pcolor = this.hightLightColor; + const pcolor = '0000FFFF'; const pstyle = feature.get('pstyle'); - return this.getPointStyles({ color: pcolor, size: pSize, style: pstyle }); } @@ -512,17 +569,12 @@ 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.displayFeatureInfo(feature); + this.highlightSelect(feature); this.activeFeature.value = feature; }); } @@ -543,7 +595,6 @@ } getAllLayerModels() { - console.log('馃殌 ~ this.layerInfo.value:', this.layerInfo.value); return this.layerInfo.value.reduce((preVal, curVal) => { if (curVal.children && curVal.children.length > 0) { return preVal.concat(curVal.children.map((item) => item.model)); @@ -573,10 +624,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, + icon: layerData.icon, model: markRaw(layer), get isVisible() { return layer.getVisible(); @@ -689,6 +750,9 @@ source: new VectorTileSource({ format: new MVT(), url: url, + // minZoom:5, + // maxZoom:2 + // minZoom:12 }), extent: vectorTileExtent, style: style, @@ -696,10 +760,22 @@ 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, @@ -740,6 +816,110 @@ }, }); } + } + + 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) { @@ -754,6 +934,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