Skip to content

Commit cac2815

Browse files
committed
fix: 完善 WebMapV3 Sprite 处理与资源引用
- 修正旧版线符号方向并统一 WebMap 图案方向 - 导出 Sprite 加载处理函数供外部 WebApp 使用 - 更新 Mapbox GL Enhance 文档链接并补充相关测试 AI-GEN: 90% gpt5.6-luna
1 parent 238c1ad commit cac2815

9 files changed

Lines changed: 132 additions & 7 deletions

File tree

‎src/common/index.common.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,4 +761,5 @@ export { KeyServiceParameter, SecurityManager, ServerInfo, TokenServiceParameter
761761
export { CartoCSS, ThemeStyle };
762762
export { ElasticSearch };
763763
export { Lang };
764-
export { KnowledgeGraph } from './overlay/KnowledgeGraph';
764+
export { KnowledgeGraph } from './overlay/KnowledgeGraph';
765+
export { createSpriteLoadHandler } from './mapping/WebMapV3';

‎src/common/mapping/WebMapV3.js‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* This program are made available under the terms of the Apache License, Version 2.0
33
* which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html.*/
44
import { FetchRequest } from '../util/FetchRequest';
5-
import { getLayerCatalogRenderLayers, getLayerInfosFromCatalogs, getMainLayerFromCatalog, isSameRasterLayer, mergeFeatures, transformUrl } from './utils/util';
5+
import { getLayerCatalogRenderLayers, getLayerInfosFromCatalogs, getMainLayerFromCatalog, isSameRasterLayer, mergeFeatures, transformUrl, flipImageVertically } from './utils/util';
66
import { SourceListModelV3 } from './utils/SourceListModelV3';
77
import cloneDeep from 'lodash.clonedeep';
88

@@ -162,6 +162,28 @@ export const LEGEND_STYLE_TYPES = {
162162
IMAGE: 'image',
163163
STYLE: 'style'
164164
};
165+
166+
/**
167+
* 按地图版本创建 Sprite 加载处理函数,供 WebMap 和外部 WebApp 共用。
168+
* @param {string} mapVersion 地图版本号。
169+
* @returns {Function|undefined} 旧版地图返回线符号处理函数,新版地图不需要额外处理。
170+
*/
171+
export function createSpriteLoadHandler(mapVersion) {
172+
const [major, minor, patch] = typeof mapVersion === 'string' ? mapVersion.split('.').map(Number) : [];
173+
// 3.3.7 及以前的地图线符号需要垂直翻转;新版本由地图数据自身保证方向。
174+
if (major > 3 || (major === 3 && minor > 3) || (major === 3 && minor === 3 && patch > 7)) {
175+
return;
176+
}
177+
return (id, imageData, width, height) => {
178+
// 翻转所有 line- 开头的图案
179+
if (id && id.startsWith('line-')) {
180+
return flipImageVertically(imageData, width, height);
181+
}
182+
183+
return null;
184+
};
185+
}
186+
165187
export function createWebMapV3Extending(SuperClass, { MapManager, mapRepo, crsManager, l7LayerUtil, webMapService }) {
166188
return class WebMapV3 extends SuperClass {
167189
constructor(mapId, options, mapOptions = {}) {
@@ -291,6 +313,9 @@ export function createWebMapV3Extending(SuperClass, { MapManager, mapRepo, crsMa
291313
// 初始化 map
292314
const mapOptions = {
293315
...this.mapOptions,
316+
// 统一线图案方向,避免 Mapbox GL 默认方向与 WebMap 符号方向约定不一致;旧版资源翻转由 _getSpriteLoad 按地图版本处理。
317+
linePatternOrientation: 'west-to-east',
318+
onSpriteLoad: this._getSpriteLoad(),
294319
transformRequest: this._getTransformRequest(),
295320
container: this.options.target,
296321
crs: this._baseProjection,
@@ -317,6 +342,10 @@ export function createWebMapV3Extending(SuperClass, { MapManager, mapRepo, crsMa
317342
});
318343
}
319344

345+
_getSpriteLoad() {
346+
return createSpriteLoadHandler(this._mapInfo && this._mapInfo.version);
347+
}
348+
320349
_getTransformRequest() {
321350
if (this.mapOptions.transformRequest) {
322351
return this.mapOptions.transformRequest;

‎src/common/mapping/index.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export * from './WebMapV2Base';
22
export * from './WebMapService';
33
export * from './utils/epsg-define';
44
export * from './WebMapBase';
5-
export * from './utils/SourceListModelV2';
5+
export * from './utils/SourceListModelV2';
6+
export { createSpriteLoadHandler } from './WebMapV3';

‎src/common/mapping/utils/util.js‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,19 @@ export function getLayerCatalogRenderLayers(parts, catalogId, layersOnMap) {
216216
export function getMainLayerFromCatalog(layerParts, catalogId, layersOnMap) {
217217
const renderLayers = getLayerCatalogRenderLayers(layerParts, catalogId, layersOnMap);
218218
return layersOnMap.find(item => item.id === renderLayers[0]);
219-
}
219+
}
220+
221+
// 垂直翻转 RGBA 图片,保持像素顺序并避免逐通道复制。
222+
export function flipImageVertically(imageData, width, height) {
223+
const sourceData = imageData.data || imageData;
224+
const flipped = new Uint8Array(sourceData.length);
225+
const rowSize = width * 4;
226+
227+
for (let row = 0; row < height; row++) {
228+
const sourceRowStart = row * rowSize;
229+
const targetRowStart = (height - row - 1) * rowSize;
230+
flipped.set(sourceData.subarray(sourceRowStart, sourceRowStart + rowSize), targetRowStart);
231+
}
232+
233+
return flipped;
234+
}

‎src/mapboxgl/mapping/WebMap.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { GraticuleLayer } from '../overlay/GraticuleLayer';
3131
* <p style="font-size: 13px"><a href="https://iclient.supermap.io/web/libs/antv/g2/4.2.8/g2.min.js">G2: </a>&lt;script type="text/javascript" src="https://iclient.supermap.io/web/libs/antv/g2/4.2.8/g2.min.js"&gt;&lt;/script&gt;</p>
3232
* <p style="font-size: 13px"><a href="https://iclient.supermap.io/web/libs/antv/g6/4.3.2/g6.min.js">G6: </a>&lt;script type="text/javascript" src="https://iclient.supermap.io/web/libs/antv/g6/4.3.2/g6.min.js"&gt;&lt;/script&gt;</p>
3333
* <p style="font-size: 13px"><a href="https://iclient.supermap.io/web/libs/fast-xml-parser/4.2.7/fxparser.min.js">fast-xml-parser: </a>&lt;script type="text/javascript" src="https://iclient.supermap.io/web/libs/fast-xml-parser/4.2.7/fxparser.min.js"&gt;&lt;/script&gt;</p>
34-
* <p style="font-size: 13px"><a href="https://iclient.supermap.io/web/libs/mapbox-gl-js-enhance/1.12.1-13/mapbox-gl-enhance.jss">mapbox-gl-js-enhance: </a>&lt;script type="text/javascript" src="https://iclient.supermap.io/web/libs/mapbox-gl-js-enhance/1.12.1-13/mapbox-gl-enhance.js"&gt;&lt;/script&gt;</p>
34+
* <p style="font-size: 13px"><a href="https://iclient.supermap.io/web/libs/mapbox-gl-js-enhance/1.12.1-13/mapbox-gl-enhance.js">mapbox-gl-js-enhance: </a>&lt;script type="text/javascript" src="https://iclient.supermap.io/web/libs/mapbox-gl-js-enhance/1.12.1-13/mapbox-gl-enhance.js"&gt;&lt;/script&gt;</p>
3535
* </div>
3636
* @modulecategory Mapping
3737
* @param {number} id - iPortal|Online 地图 ID。

‎src/mapboxgl/mapping/index.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export { WebMap } from './WebMap';
22
export { initMap } from './InitMap';
3-
export { VideoMap } from './VideoMap';
3+
export { VideoMap } from './VideoMap';

‎test/common/mapping/WebMapV3Spec.js‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { createWebMapV3Extending } from '../../../src/common/mapping/WebMapV3';
22
import { createMapClassExtending } from '../../../src/common/mapping/MapBase';
3+
import { createSpriteLoadHandler } from '../../../src/common/mapping';
4+
import { createSpriteLoadHandler as createPublicSpriteLoadHandler } from '../../../src/common/index.common';
5+
import { createWebMapBaseExtending } from '../../../src/common/mapping/WebMapBase';
36
import { Events } from '../../../src/common/commontypes';
47
import { FetchRequest } from '../../../src/common/util/FetchRequest';
58

@@ -175,6 +178,58 @@ describe('WebMapV3 - addLocalIdeographFontFamily', () => {
175178
inst._createMap();
176179
expect(capturedOptions).toBeDefined();
177180
expect(capturedOptions.localIdeographFontFamily).toBe('sans-serif,PingFang SC Regular');
181+
expect(capturedOptions.linePatternOrientation).toBe('west-to-east');
182+
expect(capturedOptions.onSpriteLoad).toEqual(jasmine.any(Function));
183+
});
184+
});
185+
186+
describe('_getSpriteLoad', () => {
187+
it('should be exported for external WebApps', () => {
188+
expect(createSpriteLoadHandler('3.3.7')).toEqual(jasmine.any(Function));
189+
expect(createSpriteLoadHandler('3.3.8')).toBeUndefined();
190+
expect(createPublicSpriteLoadHandler).toBe(createSpriteLoadHandler);
191+
});
192+
193+
it('should flip line sprites for maps at version 3.3.7', () => {
194+
instance._mapInfo = { version: '3.3.7' };
195+
const onSpriteLoad = instance._getSpriteLoad();
196+
const imageData = new Uint8Array([
197+
1, 2, 3, 4,
198+
5, 6, 7, 8
199+
]);
200+
201+
expect(onSpriteLoad('line-pattern', imageData, 1, 2)).toEqual(new Uint8Array([
202+
5, 6, 7, 8,
203+
1, 2, 3, 4
204+
]));
205+
expect(onSpriteLoad('point-pattern', imageData, 1, 2)).toBeNull();
206+
});
207+
208+
it('should not add a sprite callback for maps newer than version 3.3.7', () => {
209+
instance._mapInfo = { version: '3.3.8' };
210+
211+
expect(instance._getSpriteLoad()).toBeUndefined();
212+
});
213+
214+
it('should compare version components numerically', () => {
215+
instance._mapInfo = { version: '3.3.10' };
216+
217+
expect(instance._getSpriteLoad()).toBeUndefined();
218+
});
219+
220+
it('should disable the callback for higher major and minor versions', () => {
221+
['4.0.0', '3.4.0'].forEach(version => {
222+
instance._mapInfo = { version };
223+
expect(instance._getSpriteLoad()).toBeUndefined();
224+
});
225+
});
226+
227+
it('should keep the callback when the map version is missing', () => {
228+
instance._mapInfo = {};
229+
const onSpriteLoad = instance._getSpriteLoad();
230+
231+
expect(onSpriteLoad).toEqual(jasmine.any(Function));
232+
expect(onSpriteLoad(null, new Uint8Array(4), 1, 1)).toBeNull();
178233
});
179234
});
180235
});

‎test/common/mapping/utils/UtilSpec.js‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
1-
import { isSameRasterLayer } from '../../../../src/common/mapping/utils/util';
1+
import { flipImageVertically, isSameRasterLayer } from '../../../../src/common/mapping/utils/util';
22

33
describe('util', () => {
4+
describe('flipImageVertically', () => {
5+
it('flips RGBA rows in a typed array', () => {
6+
const pixels = new Uint8Array([
7+
1, 2, 3, 4, 5, 6, 7, 8,
8+
9, 10, 11, 12, 13, 14, 15, 16
9+
]);
10+
11+
expect(flipImageVertically(pixels, 2, 2)).toEqual(new Uint8Array([
12+
9, 10, 11, 12, 13, 14, 15, 16,
13+
1, 2, 3, 4, 5, 6, 7, 8
14+
]));
15+
});
16+
17+
it('accepts ImageData-like objects and a single-row image', () => {
18+
const pixels = new Uint8ClampedArray([1, 2, 3, 4, 5, 6, 7, 8]);
19+
const result = flipImageVertically({ data: pixels }, 2, 1);
20+
21+
expect(result).toEqual(new Uint8Array(pixels));
22+
});
23+
});
424
it('isSameRasterLayer', (done) => {
525
let res = isSameRasterLayer(
626
{ type: 'raster', tiles: ['http:17.0.0.1:8190/iserver/rest/maps/China'] },

‎test/mapboxgl/mapping/WebMapV3Spec.js‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createWebMapV3Extending } from '../../../src/common/mapping/WebMapV3';
44
import { createMapClassExtending } from '../../../src/common/mapping/MapBase';
55
import { L7LayerUtil } from '../../../src/common/mapping/utils/L7LayerUtil';
66
import { WebMap } from '../../../src/mapboxgl/mapping/WebMap';
7+
import { createSpriteLoadHandler } from '../../../src/mapboxgl';
78
import * as MapManagerUtil from '../../../src/mapboxgl/mapping/webmap/MapManager';
89
import { CRSManager } from '../../../src/mapboxgl/mapping/webmap/CRSManager';
910
import { featureFilter, expression } from '@mapbox/mapbox-gl-style-spec';
@@ -15,6 +16,9 @@ import '../../resources/WebMapV3.js';
1516
import '../../resources/WebMapV5.js';
1617
var server = 'http://localhost:8190/iportal/';
1718
describe('mapboxgl-webmap3.0', () => {
19+
it('exports the Sprite load handler from the package entry point', () => {
20+
expect(createSpriteLoadHandler('3.3.7')).toEqual(jasmine.any(Function));
21+
});
1822
var originalTimeout, testDiv;
1923
var id = 617580084;
2024
var mapstudioWebmap;

0 commit comments

Comments
 (0)