// 引入OpenLayers的主模块 import Map from 'ol/Map'; import View from 'ol/View'; import Feature from 'ol/Feature'; import Point from 'ol/geom/Point'; import VectorLayer from 'ol/layer/Vector'; import VectorSource from 'ol/source/Vector'; import Style from 'ol/style/Style'; import Icon from 'ol/style/Icon'; import Text from 'ol/style/Text'; import Projection from 'ol/proj/Projection'; import { getWidth, getTopLeft } from 'ol/extent'; import TileLayer from 'ol/layer/Tile'; import WMTS from 'ol/source/WMTS'; import WMTSTileGrid from 'ol/tilegrid/WMTS'; import WMTSCapabilities from 'ol/format/WMTSCapabilities'; import { Fill, Stroke } from 'ol/style'; import proj4 from 'proj4'; import { register } from 'ol/proj/proj4'; import { defaults } from 'ol/control'; import { fromLonLat } from 'ol/proj'; import axios from 'axios'; // import olPlot from 'ol-plot'; // import { activate } from '../ol-plot/ol-plot' proj4.defs('EPSG:4490', '+proj=longlat +ellps=GRS80 +no_defs +type=crs'); proj4.defs('EPSG:4525', '+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs'); register(proj4); const commonUrl = import.meta.env.VITE_APP_BASE_API + '/api/oneShare/proxyHandler/gd/'; const projection = new Projection({ code: 'EPSG:4490', units: 'degrees' }); const projectionExtent = [-180, -90, 180, 90]; const size = getWidth(projectionExtent) / 256; const resolutions = []; for (let z = 2; z < 22; ++z) { resolutions[z] = size / Math.pow(2, z); } export class olMap { private map; private options; private markers = []; private drawOptions = { graphicsType: 'circle', strokeColor: '#f80102', strokeOpacity: 1, strokeWeight: 2, fillColor: '#f80102', fillOpacity: 0, strokeStyle: 'solid' }; // private { currentState, commit, undo, history, future } = useHistory(); private overlays = []; private overlaysData = []; private graphicsType = ''; private plot; private vectorLayer; constructor(options) { this.options = options; this.map = new Map({ controls: defaults({ zoom: false, rotate: false }), layers: [], target: options.dom, view: new View({ center: options.center && options.center.length === 2 ? [options.center[0], options.center[1]] : [110.90153121597234, 21.98323671981171], zoom: options.zoom ? options.zoom : 9.6, projection: projection, maxZoom: options.maxZoom ? options.maxZoom : 18, minZoom: options.minZoom ? options.minZoom : 1 }) }); // 初始化比例尺 if (options.showScale) { // map.addControl(new AMap.Scale()); } if (options.drawTool?.use) { this.initMouseTool(options.drawTool); } this.initLayer(options); } async initLayer(options) { // 添加新的图层 if (Array.isArray(options.id)) { for (const layer of options.id) { await this.formatXml(layer); // 等待当前 layer 处理完成 } } else if (options.id) { // 如果 options.id 不是数组,但确实是一个图层,则直接处理 await this.formatXml(options.id); } console.log('wan') // 创建Vector层并添加到地图上 this.vectorLayer = new VectorLayer({ source: new VectorSource({ features: [] }) }); this.map.addLayer(this.vectorLayer); if (typeof this.options.onLoadCompleted === 'function') { this.options.onLoadCompleted(this.map); } } formatXml(code, minZoom, maxZoom, zIndex, visible) { const xml = new WMTSCapabilities(); // axios.post(commonUrl + 'YZT1723547712680', '\n' + // '\n' + // ''); return this.getCapabilities(code).then((lists) => { const geojson = xml.read(lists.data); const data = geojson.Contents.Layer[0]; const layerParam = { layerName: data.Abstract, styleName: data.Identifier, tilematrixset: data.TileMatrixSetLink[0].TileMatrixSet, format: data.Format[0] }; this.createWmsLayer(code, layerParam, minZoom, maxZoom, zIndex, visible); }); } // 请求接口获取地图信息 getCapabilities(code) { return axios.get(commonUrl + code + '?SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetCapabilities'); } // 请求地图图片加载图层 createWmsLayer(code, layerParam, minZoom = 0, maxZoom, zIndex = -1, visible = true) { const source = new WMTS({ url: commonUrl + code, crossOrigin: 'Anonymous', layer: layerParam.layerName, style: layerParam.styleName, matrixSet: layerParam.tilematrixset, format: layerParam.format, wrapX: true, tileGrid: new WMTSTileGrid({ origin: getTopLeft(projectionExtent), resolutions: resolutions, matrixIds: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21'] }) }); const layer = new TileLayer({ source: source, zIndex: zIndex, minZoom: minZoom, maxZoom, visible: visible }); layer.set('layerName', code); this.map.addLayer(layer); console.log(code) } // 初始化绘画工具 initMouseTool(options) { this.drawOptions = { graphicsType: options.graphicsType ? options.graphicsType : 'cirlce', strokeColor: options.color, strokeOpacity: 1, strokeWeight: 2, fillColor: options.color, fillOpacity: options.drawType === '1' ? 0 : 0.5, strokeStyle: 'solid' }; // debugger // this.plot = new olPlot(this.map, { // zoomToExtent: true, // ...this.drawOptions // }); // this.plot.plotDraw.on('drawEnd', this.onDrawEnd.bind(this)); } // 绘制结束事件 onDrawEnd(event) { const feature = event.feature; const aa = feature.getGeometry(); // 继续编辑编辑 this.drawGraphics(this.drawOptions.graphicsType); } // 绘制图形 drawGraphics(type: string) { if (type === 'circle') { // 绘制圆形 // activate('Circle'); } else if (type === 'rectangle') { // 绘制矩形 this.plot.plotDraw.activate('RectAngle'); } else if (type === 'polygon') { // 绘制多边形 this.plot.plotDraw.activate('Polygon'); } else if (type === 'freePolygon') { // 绘制索套 this.plot.plotDraw.activate('FreePolygon'); } } // 关闭绘制 closeDraw() { this.plot.plotDraw.deactivate(); } // 切换图层 async replaceLayers(newLayers) { // 遍历当前的所有图层并移除它们 this.map.getLayers().forEach((layer) => { this.map.removeLayer(layer); }); // 添加新的图层 if (Array.isArray(newLayers)) { for (const layer of newLayers) { await this.formatXml(layer); // 等待当前 layer 处理完成 } } else if (newLayers) { // 如果 options.id 不是数组,但确实是一个图层,则直接处理 await this.formatXml(newLayers); } // 创建Vector层并添加到地图上 this.vectorLayer = new VectorLayer({ source: new VectorSource({ features: [] }) }); this.map.addLayer(this.vectorLayer); const point = JSON.parse(JSON.stringify(this.markers)); this.markers = []; this.addMarker(point) } addMarker(points) { points.forEach((point) => { // 创建标注点 const feature = new Feature({ geometry: new Point([point.longitude, point.latitude]), name: point.name }); // 定义样式 const style = new Style({ image: new Icon({ anchor: [0.5, point.size[1]], anchorXUnits: 'fraction', anchorYUnits: 'pixels', src: point.image }), text: new Text({ text: point.name, fill: new Fill({ color: '#000' }), stroke: new Stroke({ color: '#fff', width: 3 }) }) }); feature.setStyle(style); this.markers.push(point); this.vectorLayer.getSource().addFeature(feature); }); } // 清除所有标加 clearMarker(id) { if (!this.vectorLayer) return; this.vectorLayer.getSource().clear(); } }