wmtsManager.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. import axios from 'axios';
  2. import { getMapProduct, getMapProduct2 } from "@/api/globalMap";
  3. class WMTSManager {
  4. constructor(map) {
  5. this.map = map;
  6. this.wmtslayergroup = null;
  7. this.wmtsgroupid = 'wmtsgroup';
  8. this.mapLayerIds = [];
  9. this.currentMapLayerIds = [];
  10. this.index = 0; //记录调用次数
  11. }
  12. init() {
  13. this.createWmtsLayerGroups();
  14. }
  15. createWmtsLayerGroups() {
  16. const that = this;
  17. // let base_wmts_source = {
  18. // type: "geojson",
  19. // data: { type: "FeatureCollection", features: [] },
  20. // };
  21. // let layer = [
  22. // {
  23. // id: "wmtslayer",
  24. // type: "circle",
  25. // source: base_wmts_source,
  26. // },
  27. // ];
  28. if (!that.wmtslayergroup) {
  29. // that.map.on("style.load", () => {
  30. // });
  31. // 新建图层组
  32. that.wmtslayergroup = new GeoGlobe.LayerGroup(that.map);
  33. // 添加指定图层到图层组中
  34. //that.wmtslayergroup.addGroup(that.map, that.wmtsgroupid, layer);
  35. } else {
  36. ElMessage({ message: '图层组已存在!', type: 'error' });
  37. }
  38. }
  39. addWmtsLayers(wmtsInfo, callback, isSpecialLayer) {
  40. const that = this;
  41. if (!wmtsInfo[0]) {
  42. ElMessage({ message: '请传入正确的参数!', type: 'error' });
  43. return false;
  44. }
  45. const val = wmtsInfo[that.index];
  46. if (val) {
  47. let obj = {};
  48. if (val.REQUEST) {
  49. obj = {
  50. REQUEST: val.REQUEST
  51. };
  52. }
  53. getMapProduct(val.serviceCode, obj).then((value) => {
  54. const format = new GeoGlobe.Format.WMTSCapabilities();
  55. //为了解决BoundingBox节点或者WGS84BoundingBox中存在“NaN NaN”的情况,导致format.read解析时报错,出现这个问题时,将坐标改为广东省范围
  56. if (value.indexOf('<ows:LowerCorner>NaN NaN</ows:LowerCorner>') >= 0 || value.indexOf('<ows:UpperCorner>NaN NaN</ows:UpperCorner>') >= 0) {
  57. value = value.replaceAll('<ows:LowerCorner>NaN NaN</ows:LowerCorner>', '<ows:LowerCorner>109.61 20</ows:LowerCorner>');
  58. value = value.replaceAll('<ows:UpperCorner>NaN NaN</ows:UpperCorner>', '<ows:UpperCorner>117.39 25.51</ows:UpperCorner>');
  59. } else if (value.indexOf('<ows:LowerCorner> </ows:LowerCorner>') >= 0 || value.indexOf('<ows:UpperCorner> </ows:UpperCorner>') >= 0) {
  60. value = value.replaceAll('<ows:LowerCorner> </ows:LowerCorner>', '<ows:LowerCorner>109.61 20</ows:LowerCorner>');
  61. value = value.replaceAll('<ows:UpperCorner> </ows:UpperCorner>', '<ows:UpperCorner>117.39 25.51</ows:UpperCorner>');
  62. }
  63. const json = format.read(value);
  64. const layerOptions = that.WMTSMatchAnalyzer(json, val.layerExtent, val.wmtsLoadParam);
  65. // window.location.origin +
  66. const serviceUrl = import.meta.env.VITE_APP_BASE_API + '/api/oneShare/proxyHandler/mm/' + val.serviceCode;
  67. const layerInf = that.createLayer(serviceUrl, layerOptions[0], isSpecialLayer);
  68. that.map.addSource(layerInf.source.id, layerInf.source);
  69. that.wmtslayergroup.addLayerToGroup(that.map, that.wmtsgroupid, layerInf.layer);
  70. let maxt = '';
  71. let extent = '';
  72. if (layerInf.layer.metadata[0]) {
  73. extent = layerInf.layer.metadata[0].maxExtent.split(',');
  74. maxt = GeoGlobe.LngLatBounds.fromString(layer.metadata[0].maxExtent);
  75. } else if (layerInf.layer.metadata.maxExtent) {
  76. extent = layerInf.layer.metadata.maxExtent.split(',');
  77. maxt = GeoGlobe.LngLatBounds.fromString(layerInf.layer.metadata.maxExtent);
  78. } else if (layerInf.layer.metadata.tileFullExtent) {
  79. extent = layerInf.layer.metadata.tileFullExtent.split(',');
  80. maxt = GeoGlobe.LngLatBounds.fromString(layerInf.layer.metadata.tileFullExtent);
  81. }
  82. if (val.layerExtent) {
  83. that.map.fitBounds([
  84. [val.layerExtent.left, val.layerExtent.bottom],
  85. [val.layerExtent.right, val.layerExtent.top]
  86. ]);
  87. } else {
  88. if (that.map.getZoom() < layerInf.layer.minzoom || that.map.getZoom() > layerInf.layer.maxzoom) {
  89. that.map.setZoom(layerInf.layer.minzoom);
  90. }
  91. // 根据地图返回的范围设置地图中心
  92. // if (maxt) {
  93. // //如果当前坐标单位为经纬度,判断范围中的坐标是否在有效范围内
  94. // if (that.map.units === 'degrees') {
  95. // if (
  96. // that.validLonCoord(maxt.getEast()) &&
  97. // that.validLonCoord(maxt.getWest()) &&
  98. // that.validLatCoord(maxt.getSouth()) &&
  99. // that.validLatCoord(maxt.getNorth())
  100. // ) {
  101. // var centerPoint = maxt.getCenterLonLat();
  102. // that.map.setCenter(centerPoint);
  103. // }
  104. // } else {
  105. // var centerPoint = maxt.getCenterLonLat();
  106. // that.map.setCenter(centerPoint);
  107. // }
  108. // var centerPoint = maxt.getCenterLonLat();
  109. // that.map.setCenter(centerPoint);
  110. // }
  111. }
  112. that.mapLayerIds.push(layerInf.layer.id);
  113. that.currentMapLayerIds.push(layerInf.layer.id);
  114. that.index++;
  115. that.addWmtsLayers(wmtsInfo, callback);
  116. });
  117. } else {
  118. that.index = 0;
  119. callback(true, that.currentMapLayerIds);
  120. that.currentMapLayerIds = [];
  121. }
  122. }
  123. addWmtsLayers2(wmtsInfo, callback, isSpecialLayer) {
  124. const that = this;
  125. if (!wmtsInfo[0]) {
  126. ElMessage({ message: '请传入正确的参数!', type: 'error' });
  127. return false;
  128. }
  129. const val = wmtsInfo[that.index];
  130. if (val) {
  131. getMapProduct2(val).then((value) => {
  132. const format = new GeoGlobe.Format.WMTSCapabilities();
  133. //为了解决BoundingBox节点或者WGS84BoundingBox中存在“NaN NaN”的情况,导致format.read解析时报错,出现这个问题时,将坐标改为广东省范围
  134. if (value.indexOf('<ows:LowerCorner>NaN NaN</ows:LowerCorner>') >= 0 || value.indexOf('<ows:UpperCorner>NaN NaN</ows:UpperCorner>') >= 0) {
  135. value = value.replaceAll('<ows:LowerCorner>NaN NaN</ows:LowerCorner>', '<ows:LowerCorner>109.61 20</ows:LowerCorner>');
  136. value = value.replaceAll('<ows:UpperCorner>NaN NaN</ows:UpperCorner>', '<ows:UpperCorner>117.39 25.51</ows:UpperCorner>');
  137. } else if (value.indexOf('<ows:LowerCorner> </ows:LowerCorner>') >= 0 || value.indexOf('<ows:UpperCorner> </ows:UpperCorner>') >= 0) {
  138. value = value.replaceAll('<ows:LowerCorner> </ows:LowerCorner>', '<ows:LowerCorner>109.61 20</ows:LowerCorner>');
  139. value = value.replaceAll('<ows:UpperCorner> </ows:UpperCorner>', '<ows:UpperCorner>117.39 25.51</ows:UpperCorner>');
  140. }
  141. const json = format.read(value);
  142. const layerOptions = that.WMTSMatchAnalyzer(json, val.layerExtent, val.wmtsLoadParam);
  143. const serviceUrl = window.location.origin + import.meta.env.VITE_APP_BASE_API + '/gmap/proxyHandler?paasId=' + val.paasId + "&paasToken=" + val.paasToken + "&serviceCode=" + val.serviceCode + "&url=" + val.url;
  144. const layerInf = that.createLayer(serviceUrl, layerOptions[0], isSpecialLayer);
  145. that.map.addSource(layerInf.source.id, layerInf.source);
  146. that.wmtslayergroup.addLayerToGroup(that.map, that.wmtsgroupid, layerInf.layer);
  147. let maxt = '';
  148. let extent = '';
  149. if (layerInf.layer.metadata[0]) {
  150. extent = layerInf.layer.metadata[0].maxExtent.split(',');
  151. maxt = GeoGlobe.LngLatBounds.fromString(layer.metadata[0].maxExtent);
  152. } else if (layerInf.layer.metadata.maxExtent) {
  153. extent = layerInf.layer.metadata.maxExtent.split(',');
  154. maxt = GeoGlobe.LngLatBounds.fromString(layerInf.layer.metadata.maxExtent);
  155. } else if (layerInf.layer.metadata.tileFullExtent) {
  156. extent = layerInf.layer.metadata.tileFullExtent.split(',');
  157. maxt = GeoGlobe.LngLatBounds.fromString(layerInf.layer.metadata.tileFullExtent);
  158. }
  159. if (val.layerExtent) {
  160. that.map.fitBounds([
  161. [val.layerExtent.left, val.layerExtent.bottom],
  162. [val.layerExtent.right, val.layerExtent.top]
  163. ]);
  164. } else {
  165. if (that.map.getZoom() < layerInf.layer.minzoom || that.map.getZoom() > layerInf.layer.maxzoom) {
  166. that.map.setZoom(layerInf.layer.minzoom);
  167. }
  168. // 根据地图返回的范围设置地图中心
  169. // if (maxt) {
  170. // //如果当前坐标单位为经纬度,判断范围中的坐标是否在有效范围内
  171. // if (that.map.units === 'degrees') {
  172. // if (
  173. // that.validLonCoord(maxt.getEast()) &&
  174. // that.validLonCoord(maxt.getWest()) &&
  175. // that.validLatCoord(maxt.getSouth()) &&
  176. // that.validLatCoord(maxt.getNorth())
  177. // ) {
  178. // var centerPoint = maxt.getCenterLonLat();
  179. // that.map.setCenter(centerPoint);
  180. // }
  181. // } else {
  182. // var centerPoint = maxt.getCenterLonLat();
  183. // that.map.setCenter(centerPoint);
  184. // }
  185. // var centerPoint = maxt.getCenterLonLat();
  186. // that.map.setCenter(centerPoint);
  187. // }
  188. }
  189. that.mapLayerIds.push(layerInf.layer.id);
  190. that.currentMapLayerIds.push(layerInf.layer.id);
  191. that.index++;
  192. that.addWmtsLayers(wmtsInfo, callback);
  193. });
  194. } else {
  195. that.index = 0;
  196. callback(true, that.currentMapLayerIds);
  197. that.currentMapLayerIds = [];
  198. }
  199. }
  200. /**
  201. * 验证经度坐标值是否为有效值范围内
  202. * @param {number} coord
  203. */
  204. validLonCoord(coord) {
  205. return coord >= -180 && coord <= 180;
  206. }
  207. /**
  208. * 验证纬度坐标值是否为有效值范围内
  209. * @param {number} coord
  210. * @returns
  211. */
  212. validLatCoord(coord) {
  213. return coord >= -90 && coord <= 90;
  214. }
  215. WMTSMatchAnalyzer(json, layerExtent, wmtsLoadParam) {
  216. const layers = json.contents.layers;
  217. const tileMatrixSets = json.contents.tileMatrixSets;
  218. const layerArr = [];
  219. for (const data of layers) {
  220. const layerObj = {};
  221. layerObj['name'] = data.identifier;
  222. layerObj['type'] = 'WMTS';
  223. layerObj['alias'] = data.identifier;
  224. layerObj['opacity'] = 1;
  225. layerObj['visibility'] = true;
  226. layerObj['formats'] = data.formats;
  227. if (wmtsLoadParam && wmtsLoadParam.format && wmtsLoadParam.layer == data.identifier) {
  228. layerObj['format'] = wmtsLoadParam.format;
  229. } else {
  230. layerObj['format'] = data.formats[0];
  231. }
  232. if (wmtsLoadParam && wmtsLoadParam.style && wmtsLoadParam.layer == data.identifier) {
  233. layerObj['style'] = wmtsLoadParam.style;
  234. } else {
  235. layerObj['style'] = data.styles[0].identifier;
  236. }
  237. if (layerExtent) {
  238. layerObj['tileFullExtent'] = layerExtent.left + ',' + layerExtent.bottom + ',' + layerExtent.right + ',' + layerExtent.top;
  239. } else if (data.bounds) {
  240. layerObj['tileFullExtent'] =
  241. data.bounds.getWest() + ',' + data.bounds.getSouth() + ',' + data.bounds.getEast() + ',' + data.bounds.getNorth();
  242. }
  243. if (wmtsLoadParam && wmtsLoadParam.tileMatrixset && wmtsLoadParam.layer == data.identifier) {
  244. layerObj['matrixSet'] = wmtsLoadParam.tileMatrixset;
  245. } else {
  246. layerObj['matrixSet'] = data.tileMatrixSetLinks[0].tileMatrixSet;
  247. }
  248. const matrixIds = [];
  249. for (const d of tileMatrixSets[layerObj.matrixSet].matrixIds) {
  250. const matrixid = {};
  251. matrixid.identifier = d.identifier;
  252. matrixid.scaleDenominator = d.scaleDenominator;
  253. matrixid.tileHeight = d.tileHeight;
  254. matrixid.tileWidth = d.tileWidth;
  255. matrixIds.push(matrixid);
  256. }
  257. layerObj['matrixIds'] = matrixIds;
  258. layerArr.push(layerObj);
  259. }
  260. return layerArr;
  261. }
  262. createLayer(url, options, isSpecialLayer) {
  263. const layerInf = {};
  264. if (url.indexOf('?') > -1) {
  265. url =
  266. url +
  267. '&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=' +
  268. options.name +
  269. '&STYLE=' +
  270. options.style +
  271. '&TILEMATRIXSET=' +
  272. options.matrixSet +
  273. '&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=' +
  274. options.formats[0];
  275. } else {
  276. url =
  277. url +
  278. '?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=' +
  279. options.name +
  280. '&STYLE=' +
  281. options.style +
  282. '&TILEMATRIXSET=' +
  283. options.matrixSet +
  284. '&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=' +
  285. options.formats[0];
  286. }
  287. // let index = url.lastIndexOf("?")
  288. // var resolves = url.substring(index + 1, url.length);
  289. // if(resolves.indexOf('token')>-1||resolves.indexOf('TOKEN')>-1){
  290. // }
  291. const matrixIds = options.matrixIds;
  292. const minzoom = matrixIds[0].identifier;
  293. const maxzoom = matrixIds[matrixIds.length - 1].identifier;
  294. const wmtsSource = new GeoGlobe.Source.RasterSource({
  295. id:
  296. 'sourceId_' +
  297. options.name +
  298. (isSpecialLayer ? '_isSpecialLayer' : '') +
  299. '_' +
  300. // Date.parse(new Date()),
  301. this.guid(),
  302. type: 'raster',
  303. url: [url],
  304. minzoom: parseInt(minzoom),
  305. maxzoom: parseInt(maxzoom) + 1,
  306. // tileSize: 256
  307. tileSize: 1024
  308. });
  309. wmtsSource['minzoom'] = parseInt(minzoom);
  310. wmtsSource['maxzoom'] = parseInt(maxzoom) + 1;
  311. let visibility = options.visibility;
  312. if (options.cityName && parseInt(minzoom) > 17) {
  313. visibility = 'false';
  314. }
  315. const wmtsLayer = new GeoGlobe.Layer.RasterLayer({
  316. id: 'layerId_' + options.name + '_' + this.guid(),
  317. type: 'raster',
  318. source: wmtsSource.id,
  319. name: options.name,
  320. metadata: options,
  321. minzoom: parseInt(minzoom),
  322. maxzoom: parseInt(maxzoom) + 2,
  323. paint: {
  324. 'raster-opacity': 1
  325. },
  326. layout: {
  327. visibility: visibility == true || visibility == 'true' ? 'visible' : 'none'
  328. }
  329. });
  330. layerInf['layer'] = wmtsLayer;
  331. layerInf['source'] = wmtsSource;
  332. return layerInf;
  333. }
  334. S4() {
  335. return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  336. }
  337. guid() {
  338. return this.S4() + this.S4() + '-' + this.S4() + '-' + this.S4() + '-' + this.S4() + '-' + this.S4() + this.S4() + this.S4();
  339. }
  340. removeWmtsLayers() {
  341. if (this.mapLayerIds) {
  342. for (const val of this.mapLayerIds) {
  343. const layer = this.map.getLayer(val);
  344. if (layer) {
  345. this.map.removeLayer(layer.id);
  346. if (this.map.getSource(layer.source)) {
  347. this.map.removeSource(layer.source);
  348. }
  349. }
  350. }
  351. }
  352. }
  353. }
  354. export default WMTSManager;