From f77e5ccf3a95ccb5ea428a0997bed286a89d93f0 Mon Sep 17 00:00:00 2001 From: songyumeng Date: Sun, 28 Apr 2024 17:56:58 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90feature=E3=80=91webmap3.0=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E5=A4=9A=E6=8A=95=E5=BD=B1=20commit=20by=20xiongjj=20?= =?UTF-8?q?=20review=20by=20songym?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mapboxgl/mapping/webmap/v3/WebMap.js | 36 +++++- test/mapboxgl/mapping/WebMapV3Spec.js | 136 +++++++++++++++++++++-- 2 files changed, 159 insertions(+), 13 deletions(-) diff --git a/src/mapboxgl/mapping/webmap/v3/WebMap.js b/src/mapboxgl/mapping/webmap/v3/WebMap.js index 4c402b15b..4411b45ca 100644 --- a/src/mapboxgl/mapping/webmap/v3/WebMap.js +++ b/src/mapboxgl/mapping/webmap/v3/WebMap.js @@ -106,6 +106,7 @@ export class WebMap extends mapboxgl.Evented { this._layerIdRenameMapList = []; this.excludeSourceNames = ['tdt-search-', 'tdt-route-', 'smmeasure', 'mapbox-gl-draw']; this._appendLayers = false; + this._baseProjection = ''; } /** @@ -158,6 +159,18 @@ export class WebMap extends mapboxgl.Evented { maxzoom, sprite = '' } = this._mapInfo; + let baseProjection = crs; + if (typeof crs === 'object') { + baseProjection = crs.name; + if (!mapboxgl.CRS) { + const error = `The EPSG code ${baseProjection} needs to include mapbox-gl-enhance.js. Refer to the example: https://iclient.supermap.io/examples/mapboxgl/editor.html#mvtVectorTile_2362`; + this.fire('getmapinfofailed', { error: error }); + console.error(error); + return; + } + this._setCRS(crs); + } + this._baseProjection = baseProjection; center = this.mapOptions.center || center; zoom = this.mapOptions.zoom || zoom; bearing = this.mapOptions.bearing || bearing; @@ -166,7 +179,7 @@ export class WebMap extends mapboxgl.Evented { // 初始化 map const mapOptions = { container: this.options.target, - crs, + crs: this._baseProjection, center, zoom, style: { @@ -190,13 +203,18 @@ export class WebMap extends mapboxgl.Evented { }); } + _setCRS({ name, wkt, extent }) { + const crs = new mapboxgl.CRS(name, wkt, extent, extent[2] > 180 ? 'meter' : 'degree'); + mapboxgl.CRS.set(crs); + } + /** * @private * @function WebMap.prototype._initLayers * @description emit 图层加载成功事件。 */ _initLayers() { - if (this.map && this.map.getCRS && this.map.getCRS().epsgCode !== this._mapInfo.crs) { + if (this.map.getCRS && this.map.getCRS().epsgCode !== this._baseProjection) { this.fire('projectionisnotmatch'); return; } @@ -371,11 +389,19 @@ export class WebMap extends mapboxgl.Evented { _getLayersOnMap() { const layersOnMap = this.map.getStyle().layers.map((layer) => this.map.getLayer(layer.id)); const overlayLayers = Object.values(this.map.overlayLayersManager).reduce((layers, overlayLayer) => { - if (overlayLayer.id) { + if (overlayLayer.id && !layers.some(item => item.id === overlayLayer.id)) { + let visibility = overlayLayer.visibility; + if (!visibility && 'visible' in overlayLayer) { + visibility = overlayLayer.visible ? 'visible' : 'none'; + } + let source = overlayLayer.source || overlayLayer.sourceId; + if (typeof source === 'object') { + source = overlayLayer.id; + } layers.push({ id: overlayLayer.id, - visibility: overlayLayer.visibility || 'visible', - source: typeof overlayLayer.source === 'object' ? overlayLayer.id : overlayLayer.source, + visibility, + source, type: overlayLayer.type }); } diff --git a/test/mapboxgl/mapping/WebMapV3Spec.js b/test/mapboxgl/mapping/WebMapV3Spec.js index 7505c3a36..e2407aed0 100644 --- a/test/mapboxgl/mapping/WebMapV3Spec.js +++ b/test/mapboxgl/mapping/WebMapV3Spec.js @@ -1,3 +1,4 @@ +import mapboxgl from 'mapbox-gl'; import { WebMap } from '../../../src/mapboxgl/mapping/WebMap'; import { WebMap as WebMapV3 } from '../../../src/mapboxgl/mapping/webmap/v3/WebMap'; import '../../resources/WebMapV3.js'; @@ -22,9 +23,9 @@ describe('mapboxgl-webmap3.0', () => { }); afterEach(() => { if (mapstudioWebmap && mapstudioWebmap.map) { - const webMapV3 = mapstudioWebmap._getWebMapInstance ? mapstudioWebmap._getWebMapInstance() : mapstudioWebmap; - webMapV3.clean && webMapV3.clean(); - mapstudioWebmap = null; + const webMapV3 = mapstudioWebmap._getWebMapInstance ? mapstudioWebmap._getWebMapInstance() : mapstudioWebmap; + webMapV3.clean && webMapV3.clean(); + mapstudioWebmap = null; } window.document.body.removeChild(testDiv); jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; @@ -50,7 +51,7 @@ describe('mapboxgl-webmap3.0', () => { expect(mapstudioWebmap.map).toEqual(map); expect(mapstudioWebmap.mapParams.title).toBe('空地图'); expect(mapstudioWebmap.mapParams.description).toBe(''); - var style = map.getStyle(); + const style = map.getStyle(); expect(style.name).toBe(mapstudioWebmap.mapParams.title); expect(style.layers.length).toBe(1); expect(style.sources).toEqual({}); @@ -85,7 +86,7 @@ describe('mapboxgl-webmap3.0', () => { expect(+center.lng.toFixed(4)).toEqual(116.3949); expect(mapstudioWebmap.mapParams.title).toBe('restmap服务'); expect(mapstudioWebmap.mapParams.description).toBe(''); - var style = map.getStyle(); + const style = map.getStyle(); expect(style.name).toBe(mapstudioWebmap.mapParams.title); expect(style.layers.length).toBe(2); done(); @@ -110,14 +111,13 @@ describe('mapboxgl-webmap3.0', () => { mapstudioWebmap.on('addlayerssucceeded', ({ map }) => { expect(map).not.toBeUndefined(); expect(mapstudioWebmap.map).toEqual(map); - var style = map.getStyle(); + const style = map.getStyle(); const webMapV3 = mapstudioWebmap._getWebMapInstance(); const mapInfo = JSON.parse(mapstudioWebMap_symbol); expect(style.layers.length).toBe(mapInfo.layers.length); expect(webMapV3.getAppreciableLayers().length).toBeGreaterThanOrEqual(mapInfo.layers.length); expect(webMapV3.getLegendInfo().length).not.toBe(0); expect(webMapV3.getLayerCatalog().length).not.toBe(0); - expect(webMapV3.getLegendInfo().length).not.toBe(0); done(); }); }); @@ -139,7 +139,7 @@ describe('mapboxgl-webmap3.0', () => { mapstudioWebmap.on('addlayerssucceeded', ({ map }) => { expect(map).not.toBeUndefined(); expect(mapstudioWebmap.map).toEqual(map); - var style = map.getStyle(); + const style = map.getStyle(); expect(style.layers.length).toBe(mapInfo.layers.length); const appreciableLayers = mapstudioWebmap.getAppreciableLayers(); const layerCatalogs = mapstudioWebmap.getLayerCatalog(); @@ -159,4 +159,124 @@ describe('mapboxgl-webmap3.0', () => { done(); }); }); + + it('projection is 4490 and not include mapbox-gl-enhance', (done) => { + const mapInfo = JSON.parse(mapstudioWebMap_symbol); + const nextMapInfo = { + ...mapInfo, + crs: { + name: 'EPSG:4490', + extent: [-180, -270, 180, 90], + wkt: 'GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4490"]]' + } + }; + mapstudioWebmap = new WebMapV3(nextMapInfo, { + server: server, + target: 'map' + }); + mapstudioWebmap.on('getmapinfofailed', ({ error }) => { + const throwError = `The EPSG code ${nextMapInfo.crs.name} needs to include mapbox-gl-enhance.js. Refer to the example: https://iclient.supermap.io/examples/mapboxgl/editor.html#mvtVectorTile_2362`; + expect(mapstudioWebmap.map).toBeUndefined(); + expect(error).toBe(throwError); + done(); + }); + mapstudioWebmap.initializeMap(nextMapInfo); + }); + + it('projection is 4490 and include mapbox-gl-enhance', (done) => { + spyOn(FetchRequest, 'get').and.callFake((url) => { + if (url.indexOf('/sprite') > -1) { + return Promise.resolve(new Response(msSpriteInfo)); + } + return Promise.resolve(); + }); + const mapInfo = JSON.parse(mapstudioWebMap_symbol); + const nextMapInfo = { + ...mapInfo, + crs: { + name: 'EPSG:4490', + extent: [-180, -270, 180, 90], + wkt: 'GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4490"]]' + } + }; + mapboxgl.CRS = function (epsgCode, wkt, bounds, unit) { + expect(epsgCode).toBe(nextMapInfo.crs.name); + expect(wkt).toBe(nextMapInfo.crs.wkt); + expect(bounds).toEqual(nextMapInfo.crs.extent); + expect(unit).toBe(nextMapInfo.crs.extent[2] > 180 ? 'meter' : 'degree'); + }; + mapboxgl.CRS.set = function () {}; + mapstudioWebmap = new WebMapV3(nextMapInfo, { + server: server, + target: 'map' + }); + mapstudioWebmap.initializeMap(nextMapInfo); + + mapstudioWebmap.on('addlayerssucceeded', ({ map }) => { + expect(map).not.toBeUndefined(); + expect(mapstudioWebmap.map).toEqual(map); + const style = map.getStyle(); + expect(style.layers.length).toBe(nextMapInfo.layers.length); + const appreciableLayers = mapstudioWebmap.getAppreciableLayers(); + const layerCatalogs = mapstudioWebmap.getLayerCatalog(); + expect(appreciableLayers.length).toBeGreaterThanOrEqual(nextMapInfo.layers.length); + expect(layerCatalogs.length).toBeLessThanOrEqual(appreciableLayers.length); + expect(mapstudioWebmap.getLegendInfo().length).toBe(0); + delete mapboxgl.CRS; + done(); + }); + }); + + it('overlayLayersManager', (done) => { + spyOn(FetchRequest, 'get').and.callFake((url) => { + if (url.indexOf('/sprite') > -1) { + return Promise.resolve(new Response(msSpriteInfo)); + } + return Promise.resolve(); + }); + const mapInfo = JSON.parse(mapstudioWebMap_symbol); + mapstudioWebmap = new WebMapV3(mapInfo, { + server: server, + target: 'map' + }); + mapstudioWebmap.initializeMap(mapInfo); + + mapstudioWebmap.on('addlayerssucceeded', ({ map }) => { + expect(map).not.toBeUndefined(); + expect(mapstudioWebmap.map).toEqual(map); + const style = map.getStyle(); + expect(style.layers.length).toBe(mapInfo.layers.length); + const appreciableLayers = mapstudioWebmap.getAppreciableLayers(); + const layerCatalogs = mapstudioWebmap.getLayerCatalog(); + expect(appreciableLayers.length).toBeGreaterThanOrEqual(mapInfo.layers.length); + expect(layerCatalogs.length).toBeLessThanOrEqual(appreciableLayers.length); + expect(mapstudioWebmap.getLegendInfo().length).toBe(0); + map.overlayLayersManager = { + GraticuleLayer: { + id: 'GraticuleLayer', + overlay: true, + sourceId: 'GraticuleLayer', + visible: true + }, + EchartLayer: { + id: 'EchartLayer', + visibility: 'visible', + source: { + type: 'geoJSON', + data: null + } + }, + GraticuleLayer1: { + id: 'GraticuleLayer', + overlay: true, + sourceId: 'GraticuleLayer' + } + }; + const appreciableLayers2 = mapstudioWebmap.getAppreciableLayers(); + expect(appreciableLayers2.length).toBe(appreciableLayers.length + 2); + expect(mapstudioWebmap.getLayerCatalog().length).toBe(layerCatalogs.length + 2); + expect(appreciableLayers2.find((item) => item.renderSource.id === 'EchartLayer')).toBeTruthy(); + done(); + }); + }); });