olMap.ts 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. // 引入OpenLayers的主模块
  2. import Map from 'ol/Map';
  3. import View from 'ol/View';
  4. import Feature from 'ol/Feature';
  5. import Point from 'ol/geom/Point';
  6. import VectorLayer from 'ol/layer/Vector';
  7. import VectorSource from 'ol/source/Vector';
  8. import Style from 'ol/style/Style';
  9. import Icon from 'ol/style/Icon';
  10. import Text from 'ol/style/Text';
  11. import Projection from 'ol/proj/Projection';
  12. import { getWidth, getTopLeft } from 'ol/extent';
  13. import TileLayer from 'ol/layer/Tile';
  14. import WMTS from 'ol/source/WMTS';
  15. import WMTSTileGrid from 'ol/tilegrid/WMTS';
  16. import WMTSCapabilities from 'ol/format/WMTSCapabilities';
  17. import { Fill, Stroke } from 'ol/style';
  18. import proj4 from 'proj4';
  19. import { register } from 'ol/proj/proj4';
  20. import { defaults } from 'ol/control';
  21. import { fromLonLat } from 'ol/proj';
  22. import axios from 'axios';
  23. // import olPlot from 'ol-plot';
  24. // import { activate } from '../ol-plot/ol-plot'
  25. proj4.defs('EPSG:4490', '+proj=longlat +ellps=GRS80 +no_defs +type=crs');
  26. 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');
  27. register(proj4);
  28. const commonUrl = import.meta.env.VITE_APP_BASE_API + '/api/oneShare/proxyHandler/gd/';
  29. const projection = new Projection({
  30. code: 'EPSG:4490',
  31. units: 'degrees'
  32. });
  33. const projectionExtent = [-180, -90, 180, 90];
  34. const size = getWidth(projectionExtent) / 256;
  35. const resolutions = [];
  36. for (let z = 2; z < 22; ++z) {
  37. resolutions[z] = size / Math.pow(2, z);
  38. }
  39. export class olMap {
  40. private map;
  41. private options;
  42. private markers = [];
  43. private drawOptions = {
  44. graphicsType: 'circle',
  45. strokeColor: '#f80102',
  46. strokeOpacity: 1,
  47. strokeWeight: 2,
  48. fillColor: '#f80102',
  49. fillOpacity: 0,
  50. strokeStyle: 'solid'
  51. };
  52. // private { currentState, commit, undo, history, future } = useHistory();
  53. private overlays = [];
  54. private overlaysData = [];
  55. private graphicsType = '';
  56. private plot;
  57. private vectorLayer;
  58. constructor(options) {
  59. this.options = options;
  60. this.map = new Map({
  61. controls: defaults({
  62. zoom: false,
  63. rotate: false
  64. }),
  65. layers: [],
  66. target: options.dom,
  67. view: new View({
  68. center: options.center && options.center.length === 2 ? [options.center[0], options.center[1]] : [110.90153121597234, 21.98323671981171],
  69. zoom: options.zoom ? options.zoom : 9.6,
  70. projection: projection,
  71. maxZoom: options.maxZoom ? options.maxZoom : 18,
  72. minZoom: options.minZoom ? options.minZoom : 1
  73. })
  74. });
  75. // 初始化比例尺
  76. if (options.showScale) {
  77. // map.addControl(new AMap.Scale());
  78. }
  79. if (options.drawTool?.use) {
  80. this.initMouseTool(options.drawTool);
  81. }
  82. this.initLayer(options);
  83. }
  84. async initLayer(options) {
  85. // 添加新的图层
  86. if (Array.isArray(options.id)) {
  87. for (const layer of options.id) {
  88. await this.formatXml(layer); // 等待当前 layer 处理完成
  89. }
  90. } else if (options.id) {
  91. // 如果 options.id 不是数组,但确实是一个图层,则直接处理
  92. await this.formatXml(options.id);
  93. }
  94. console.log('wan')
  95. // 创建Vector层并添加到地图上
  96. this.vectorLayer = new VectorLayer({
  97. source: new VectorSource({
  98. features: []
  99. })
  100. });
  101. this.map.addLayer(this.vectorLayer);
  102. if (typeof this.options.onLoadCompleted === 'function') {
  103. this.options.onLoadCompleted(this.map);
  104. }
  105. }
  106. formatXml(code, minZoom, maxZoom, zIndex, visible) {
  107. const xml = new WMTSCapabilities();
  108. // axios.post(commonUrl + 'YZT1723547712680', '<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs"service="WFS"version="1.0.0"outputFormat="GeoJson"maxFeatures="99999"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.opengis.net/wfshttp://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd">\n' +
  109. // '<wfs:QuerytypeName="GDSMMSZJGZDTJX_2023"userecent="true"/>\n' +
  110. // '</wfs:GetFeature>');
  111. return this.getCapabilities(code).then((lists) => {
  112. const geojson = xml.read(lists.data);
  113. const data = geojson.Contents.Layer[0];
  114. const layerParam = {
  115. layerName: data.Abstract,
  116. styleName: data.Identifier,
  117. tilematrixset: data.TileMatrixSetLink[0].TileMatrixSet,
  118. format: data.Format[0]
  119. };
  120. this.createWmsLayer(code, layerParam, minZoom, maxZoom, zIndex, visible);
  121. });
  122. }
  123. // 请求接口获取地图信息
  124. getCapabilities(code) {
  125. return axios.get(commonUrl + code + '?SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetCapabilities');
  126. }
  127. // 请求地图图片加载图层
  128. createWmsLayer(code, layerParam, minZoom = 0, maxZoom, zIndex = -1, visible = true) {
  129. const source = new WMTS({
  130. url: commonUrl + code,
  131. crossOrigin: 'Anonymous',
  132. layer: layerParam.layerName,
  133. style: layerParam.styleName,
  134. matrixSet: layerParam.tilematrixset,
  135. format: layerParam.format,
  136. wrapX: true,
  137. tileGrid: new WMTSTileGrid({
  138. origin: getTopLeft(projectionExtent),
  139. resolutions: resolutions,
  140. matrixIds: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21']
  141. })
  142. });
  143. const layer = new TileLayer({
  144. source: source,
  145. zIndex: zIndex,
  146. minZoom: minZoom,
  147. maxZoom,
  148. visible: visible
  149. });
  150. layer.set('layerName', code);
  151. this.map.addLayer(layer);
  152. console.log(code)
  153. }
  154. // 初始化绘画工具
  155. initMouseTool(options) {
  156. this.drawOptions = {
  157. graphicsType: options.graphicsType ? options.graphicsType : 'cirlce',
  158. strokeColor: options.color,
  159. strokeOpacity: 1,
  160. strokeWeight: 2,
  161. fillColor: options.color,
  162. fillOpacity: options.drawType === '1' ? 0 : 0.5,
  163. strokeStyle: 'solid'
  164. };
  165. // debugger
  166. // this.plot = new olPlot(this.map, {
  167. // zoomToExtent: true,
  168. // ...this.drawOptions
  169. // });
  170. // this.plot.plotDraw.on('drawEnd', this.onDrawEnd.bind(this));
  171. }
  172. // 绘制结束事件
  173. onDrawEnd(event) {
  174. const feature = event.feature;
  175. const aa = feature.getGeometry();
  176. // 继续编辑编辑
  177. this.drawGraphics(this.drawOptions.graphicsType);
  178. }
  179. // 绘制图形
  180. drawGraphics(type: string) {
  181. if (type === 'circle') {
  182. // 绘制圆形
  183. // activate('Circle');
  184. } else if (type === 'rectangle') {
  185. // 绘制矩形
  186. this.plot.plotDraw.activate('RectAngle');
  187. } else if (type === 'polygon') {
  188. // 绘制多边形
  189. this.plot.plotDraw.activate('Polygon');
  190. } else if (type === 'freePolygon') {
  191. // 绘制索套
  192. this.plot.plotDraw.activate('FreePolygon');
  193. }
  194. }
  195. // 关闭绘制
  196. closeDraw() {
  197. this.plot.plotDraw.deactivate();
  198. }
  199. // 切换图层
  200. async replaceLayers(newLayers) {
  201. // 遍历当前的所有图层并移除它们
  202. this.map.getLayers().forEach((layer) => {
  203. this.map.removeLayer(layer);
  204. });
  205. // 添加新的图层
  206. if (Array.isArray(newLayers)) {
  207. for (const layer of newLayers) {
  208. await this.formatXml(layer); // 等待当前 layer 处理完成
  209. }
  210. } else if (newLayers) {
  211. // 如果 options.id 不是数组,但确实是一个图层,则直接处理
  212. await this.formatXml(newLayers);
  213. }
  214. // 创建Vector层并添加到地图上
  215. this.vectorLayer = new VectorLayer({
  216. source: new VectorSource({
  217. features: []
  218. })
  219. });
  220. this.map.addLayer(this.vectorLayer);
  221. const point = JSON.parse(JSON.stringify(this.markers));
  222. this.markers = [];
  223. this.addMarker(point)
  224. }
  225. addMarker(points) {
  226. points.forEach((point) => {
  227. // 创建标注点
  228. const feature = new Feature({
  229. geometry: new Point([point.longitude, point.latitude]),
  230. name: point.name
  231. });
  232. // 定义样式
  233. const style = new Style({
  234. image: new Icon({
  235. anchor: [0.5, point.size[1]],
  236. anchorXUnits: 'fraction',
  237. anchorYUnits: 'pixels',
  238. src: point.image
  239. }),
  240. text: new Text({
  241. text: point.name,
  242. fill: new Fill({
  243. color: '#000'
  244. }),
  245. stroke: new Stroke({
  246. color: '#fff',
  247. width: 3
  248. })
  249. })
  250. });
  251. feature.setStyle(style);
  252. this.markers.push(point);
  253. this.vectorLayer.getSource().addFeature(feature);
  254. });
  255. }
  256. // 清除所有标加
  257. clearMarker(id) {
  258. if (!this.vectorLayer) return;
  259. this.vectorLayer.getSource().clear();
  260. }
  261. }