Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3112a13

Browse files
[fix]webmap xyz叠加图层支持添加非3857图层 review by xiongjj
1 parent d11d813 commit 3112a13

File tree

8 files changed

+2339
-2129
lines changed

8 files changed

+2339
-2129
lines changed

‎.gitignore‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
/web/
1010
/package-lock.json
1111
.npmrc
12-
/dist/mapboxgl/resources/
12+
/dist/mapboxgl/resources/
13+
/dist/maplibregl/resources/

‎src/common/mapping/WebMapBase.js‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const WORLD_WIDTH = 360;
4949
* @fires WebMapBase#mapbeforeremove
5050
* @fires WebMapBase#getmapfailed
5151
* @fires WebMapBase#getlayersfailed
52+
* @fires WebMapBase#xyztilelayernotsupport
5253
* @usage
5354
*/
5455
export function createWebMapBaseExtending(SuperClass, { mapRepo }) {
@@ -160,6 +161,11 @@ export function createWebMapBaseExtending(SuperClass, { mapRepo }) {
160161
* @description 底图投影与底图投影不匹配。
161162
*/
162163
'projectionnotmatch',
164+
/**
165+
* @event WebMapBase#xyztilelayernotsupport
166+
* @description XYZ TILE图层与底图的分辨率或原点不匹配。
167+
*/
168+
'xyztilelayernotsupport',
163169
'layeraddchanged',
164170
'layerupdatechanged',
165171
/**

‎src/common/mapping/WebMapV2.js‎

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -687,12 +687,47 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa
687687
}
688688

689689
_createZXYLayer(layerInfo, addedCallback) {
690-
const { url, subdomains, layerID, name, visible } = layerInfo;
690+
const { url, subdomains, layerID, name, visible, tileSize, resolutions, origin,minZoom: minzoom,maxZoom: maxzoom } = layerInfo;
691691
const urls = (subdomains && subdomains.length) ? subdomains.map(item => url.replace('{s}', item)) : [url];
692692
const layerId = layerID || name;
693-
this._addBaselayer({ url: urls, layerID: layerId, visibility: visible });
693+
const isSupport = this._isSupportZXYTileLayer({ resolutions, tileSize, origin });
694+
if (isSupport) {
695+
this._addBaselayer({ url: urls, layerID: layerId, visibility: visible, minzoom, maxzoom, isIserver: false, tileSize });
696+
} else {
697+
this.fire('xyztilelayernotsupport', { error: `The resolutions or origin of layer ${name} on XYZ Tile does not match the map`, error_code: 'XYZ_TILE_LAYER_NOT_SUPPORTED', layer: layerInfo});
698+
}
694699
addedCallback && addedCallback();
695700
}
701+
_isSupportZXYTileLayer({ resolutions, tileSize, origin }) {
702+
const isOldWebMecartor = origin === undefined && resolutions === undefined;
703+
if (isOldWebMecartor) {
704+
return true;
705+
}
706+
return this._isSameOrigin(origin) && this._isSameResolutions(resolutions, tileSize);
707+
}
708+
_isSameOrigin(origin) {
709+
const extent = this.map.getCRS().getExtent();
710+
return origin[0].toFixed(2) === extent[0].toFixed(2) && origin[1].toFixed(2) === extent[3].toFixed(2);
711+
}
712+
_isSameResolutions(resolutions, tileSize, mapTileSize = 512) {
713+
const mapResolutions = this._getMapResolutions();
714+
const conversion = mapTileSize / tileSize;
715+
return resolutions.every((item, i) => (item).toFixed(6) === (conversion * mapResolutions[i]).toFixed(6));
716+
}
717+
_getMapResolutions() {
718+
return this._getResolutionsByExtent({extent: this.map.getCRS().getExtent(), tileSize: 512})
719+
}
720+
_getResolutionsByExtent({ extent, maxZoom = 24, tileSize }) {
721+
const width = extent[2] - extent[0];
722+
const height = extent[3] - extent[1];
723+
const size = width >= height ? width : height;
724+
const maxReolution = size / tileSize;
725+
const resolutions = [];
726+
for (let i = 0; i <= maxZoom; i++) {
727+
resolutions.push(maxReolution / Math.pow(2, i));
728+
}
729+
return resolutions;
730+
}
696731

697732
_createDynamicTiledLayer(layerInfo, addedCallback) {
698733
const url = layerInfo.url;
@@ -2424,14 +2459,15 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa
24242459
minzoom = 0,
24252460
maxzoom = 22,
24262461
isIserver = false,
2462+
tileSize = 256,
24272463
bounds
24282464
}) {
24292465
const source = {
24302466
type: 'raster',
24312467
tiles: url,
24322468
minzoom: minzoom || 0,
24332469
maxzoom: maxzoom || 22,
2434-
tileSize: isIserver ? this.rasterTileSize : 256,
2470+
tileSize: isIserver ? this.rasterTileSize : tileSize,
24352471
rasterSource: isIserver ? 'iserver' : '',
24362472
prjCoordSys:
24372473
isIserver && !this.isOnlineBaseLayer(url[0], this.baseProjection) && +this.baseProjection.split(':')[1] > 0

‎src/mapboxgl/mapping/WebMap.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import { GraticuleLayer } from '../overlay/GraticuleLayer';
6868
* @fires WebMap#dataflowfeatureupdated
6969
* @fires WebMap#projectionnotmatch
7070
* @fires WebMap#mapbeforeremove
71+
* @fires WebMap#xyztilelayernotsupport
7172
* @fires WebMap#getmapfailed
7273
* @fires WebMap#getlayersfailed
7374
* @usage

‎src/openlayers/mapping/WebMap.js‎

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import * as olLayer from 'ol/layer';
3232
import WMTSCapabilities from 'ol/format/WMTSCapabilities';
3333
import WMSCapabilities from 'ol/format/WMSCapabilities';
3434
import TileGrid from 'ol/tilegrid/TileGrid';
35+
import * as olTilegrid from 'ol/tilegrid';
3536
import WMTSTileGrid from 'ol/tilegrid/WMTS';
3637
import * as olGeometry from 'ol/geom';
3738
import Vector from 'ol/source/Vector';
@@ -988,7 +989,8 @@ export class WebMap extends Observable {
988989
var layer = new olLayer.Tile({
989990
source: source,
990991
zIndex: layerInfo.zIndex || 1,
991-
visible: layerInfo.visible
992+
visible: layerInfo.visible,
993+
...this.getLayerOtherOptions(layerInfo)
992994
});
993995
var layerID = Util.newGuid(8);
994996
if (layerInfo.name) {
@@ -1324,6 +1326,38 @@ export class WebMap extends Observable {
13241326
});
13251327
}
13261328

1329+
getLayerOtherOptions(layerInfo) {
1330+
const { layerType, extent, minZoom, maxZoom } = layerInfo;
1331+
const extentVal = layerType === 'ZXY_TILE' ? this._getZXYTileMapBounds(layerInfo) : extent;
1332+
const options = { extent: extentVal };
1333+
if (typeof minZoom === 'number') {
1334+
options.minZoom = minZoom;
1335+
}
1336+
if (typeof maxZoom === 'number') {
1337+
options.maxZoom = maxZoom;
1338+
}
1339+
return options;
1340+
}
1341+
_getZXYTileMapBounds(layerInfo) {
1342+
const { mapBounds, tileSize = 256, resolutions, origin } = layerInfo;
1343+
if (mapBounds) {
1344+
return mapBounds;
1345+
}
1346+
const getBoundsByResoutions = (maxResolution, origin) => {
1347+
const size = maxResolution * tileSize;
1348+
return [origin[0], origin[1] - size, origin[0] + size, origin[1]];
1349+
};
1350+
1351+
if (resolutions) {
1352+
const maxResolution = resolutions.sort((a, b) => b - a)[0];
1353+
return getBoundsByResoutions(maxResolution, origin);
1354+
}
1355+
// 兼容之前的3857全球剖分
1356+
const projection = this.baseProjection;
1357+
if (projection === 'EPSG:3857') {
1358+
return [-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892];
1359+
}
1360+
}
13271361
/**
13281362
* @private
13291363
* @function WebMap.prototype.createXYZTileSource
@@ -1332,17 +1366,26 @@ export class WebMap extends Observable {
13321366
* @returns {ol.source.XYZ} xyz的source
13331367
*/
13341368
createXYZTileSource(layerInfo) {
1335-
const { url, subdomains } = layerInfo;
1336-
const urls = (subdomains && subdomains.length) ? subdomains.map(item => url.replace('{s}', item)) : [url];
1337-
const tileGrid = TileSuperMapRest.createTileGrid([-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892]);
1338-
return new XYZ({
1369+
const { url, subdomains, origin, resolutions, tileSize } = layerInfo;
1370+
const urls = subdomains && subdomains.length ? subdomains.map((item) => url.replace('{s}', item)) : [url];
1371+
const options = {
13391372
urls,
13401373
wrapX: false,
13411374
crossOrigin: 'anonymous',
1342-
tileGrid
1343-
});
1375+
tileGrid: this._getTileGrid({ origin, resolutions, tileSize }),
1376+
projection: this.baseProjection
1377+
};
1378+
return new XYZ(options);
1379+
}
1380+
_getTileGrid({ origin, resolutions, tileSize }) {
1381+
if (origin === undefined && resolutions === undefined) {
1382+
// 兼容上一版webMercator全球剖分
1383+
const extent = [-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892];
1384+
return olTilegrid.createXYZ({ extent });
1385+
} else {
1386+
new TileGrid({ origin, resolutions, tileSize });
1387+
}
13441388
}
1345-
13461389
/**
13471390
* @private
13481391
* @function WebMap.prototype.createWMSSource

‎test/mapboxgl/mapping/WebMapV2Spec.js‎

Lines changed: 76 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,8 +1382,6 @@ describe('mapboxgl_WebMapV2', () => {
13821382
datavizWebmap.on('mapcreatesucceeded', callback);
13831383
});
13841384

1385-
1386-
13871385
it('updateOverlayLayer unique', (done) => {
13881386
spyOn(FetchRequest, 'get').and.callFake((url) => {
13891387
if (url.indexOf('portal.json') > -1) {
@@ -1492,7 +1490,7 @@ describe('mapboxgl_WebMapV2', () => {
14921490
});
14931491
});
14941492

1495-
it('add zxytile layer', (done) => {
1493+
it('add zxytile layer 3857全球剖分', (done) => {
14961494
spyOn(FetchRequest, 'get').and.callFake((url) => {
14971495
if (url.indexOf('portal.json') > -1) {
14981496
return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy)));
@@ -1522,6 +1520,36 @@ describe('mapboxgl_WebMapV2', () => {
15221520
});
15231521
});
15241522

1523+
it('add zxytile layer 4326 world', (done) => {
1524+
spyOn(FetchRequest, 'get').and.callFake((url) => {
1525+
if (url.indexOf('portal.json') > -1) {
1526+
return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy)));
1527+
} else if (url.indexOf('/map.json') > -1) {
1528+
return Promise.resolve(new Response(datavizWebmap_ZXYTILE_4326));
1529+
}
1530+
return Promise.resolve(new Response(JSON.stringify({})));
1531+
});
1532+
datavizWebmap = new WebMap(
1533+
'test',
1534+
{
1535+
target: 'map',
1536+
serverUrl: 'http://fake/fakeiportal',
1537+
withCredentials: false
1538+
},
1539+
{
1540+
style: {
1541+
version: 8,
1542+
sources: {},
1543+
layers: []
1544+
}
1545+
}
1546+
);
1547+
datavizWebmap.on('mapcreatesucceeded', ({ layers }) => {
1548+
expect(layers.length).toBe(2);
1549+
done();
1550+
});
1551+
});
1552+
15251553
it('isvj-5215', (done) => {
15261554
spyOn(FetchRequest, 'get').and.callFake((url) => {
15271555
if (url.indexOf('portal.json') > -1) {
@@ -2683,28 +2711,69 @@ describe('mapboxgl_WebMapV2', () => {
26832711
});
26842712
});
26852713

2686-
it('initial_xyzLayer', (done) => {
2714+
it('initial_xyzLayer 3857全球剖分', (done) => {
26872715
spyOn(FetchRequest, 'get').and.callFake((url) => {
26882716
if (url.indexOf('map.json') > -1) {
26892717
return Promise.resolve(new Response(JSON.stringify(xyzLayer)));
26902718
} else if (url.indexOf('portal.json') > -1) {
26912719
return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy)));
26922720
}
2693-
return Promise.resolve();
2721+
return Promise.resolve(newResponse(JSON.stringify({})));
26942722
});
26952723
datavizWebmap = new WebMap(id, {
26962724
server: server
26972725
});
26982726
datavizWebmap.on('mapcreatesucceeded', ({ map }) => {
26992727
const layers = map.getStyle().layers;
2700-
expect(layers.length).toBe(1);
2728+
expect(layers.length).toBe(2);
27012729
const xyzLayer = layers[0];
27022730
expect(xyzLayer.id).toBe('OpenStreetMap');
27032731
expect(xyzLayer.type).toBe('raster');
2732+
const xyzLayer1 = layers[1];
2733+
expect(xyzLayer1.id).toBe('xyz');
2734+
expect(xyzLayer1.type).toBe('raster');
2735+
done();
2736+
});
2737+
});
2738+
it('initial_xyzLayer world 4326', (done) => {
2739+
spyOn(FetchRequest, 'get').and.callFake((url) => {
2740+
if (url.indexOf('map.json') > -1) {
2741+
return Promise.resolve(new Response(JSON.stringify(xyzLayer4326)));
2742+
} else if (url.indexOf('portal.json') > -1) {
2743+
return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy)));
2744+
}
2745+
return Promise.resolve(new Response(JSON.stringify({})));
2746+
});
2747+
datavizWebmap = new WebMap(id, {
2748+
server: server
2749+
});
2750+
datavizWebmap.on('mapcreatesucceeded', ({ map }) => {
2751+
const layers = map.getStyle().layers;
2752+
expect(layers.length).toBe(2);
2753+
const xyzLayer = layers[1];
2754+
expect(xyzLayer.id).toBe('mapboxgl-256x2');
2755+
expect(xyzLayer.type).toBe('raster');
2756+
done();
2757+
});
2758+
});
2759+
it('initial_xyzLayer jingjin 4326', (done) => {
2760+
spyOn(FetchRequest, 'get').and.callFake((url) => {
2761+
if (url.indexOf('map.json') > -1) {
2762+
return Promise.resolve(new Response(JSON.stringify(xyzLayerjingjin4326)));
2763+
} else if (url.indexOf('portal.json') > -1) {
2764+
return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy)));
2765+
}
2766+
return Promise.resolve();
2767+
});
2768+
datavizWebmap = new WebMap(id, {
2769+
server: server
2770+
});
2771+
datavizWebmap.on('xyztilelayernotsupport', (e) => {
2772+
expect(e.error).toBe(`The resolutions or origin of layer jingjin on XYZ Tile does not match the map`);
2773+
expect(e.error_code).toBe(`XYZ_TILE_LAYER_NOT_SUPPORTED`);
27042774
done();
27052775
});
27062776
});
2707-
27082777
it('initial_mapboxstyleLayer', (done) => {
27092778
spyOn(FetchRequest, 'get').and.callFake((url) => {
27102779
if (url.indexOf('map.json') > -1) {

‎test/openlayers/mapping/WebMapSpec.js‎

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ describe('openlayers_WebMap', () => {
184184
}
185185
});
186186

187-
it('initialize_ZXYtILE', (done) => {
187+
it('initialize_ZXYtILE 3857全球剖分', (done) => {
188188
let options = {
189189
server: server,
190190
successCallback,
@@ -195,17 +195,38 @@ describe('openlayers_WebMap', () => {
195195
var mapJson = datavizWebmap_ZXYTILE;
196196
return Promise.resolve(new Response(mapJson));
197197
}
198-
return Promise.resolve();
198+
return Promise.resolve(newResponse(JSON.stringify({})));
199199
});
200200
var datavizWebmap = new WebMap(id, options);
201201

202202
function successCallback() {
203203
expect(datavizWebmap.mapParams.title).toBe('xyz');
204-
// expect(datavizWebmap.layerAdded).toBe(2);
204+
expect(datavizWebmap.layerAdded).toBe(1);
205205
done();
206206
}
207207
});
208208

209+
it('initialize_ZXYtILE world 4326', (done) => {
210+
let options = {
211+
server: server,
212+
successCallback,
213+
errorCallback: function () { }
214+
};
215+
spyOn(FetchRequest, 'get').and.callFake((url) => {
216+
if (url.indexOf('map.json') > -1) {
217+
var mapJson = datavizWebmap_ZXYTILE_4326;
218+
return Promise.resolve(new Response(mapJson));
219+
}
220+
return Promise.resolve(new Response(JSON.stringify({})));
221+
});
222+
var datavizWebmap = new WebMap(id, options);
223+
function successCallback() {
224+
expect(datavizWebmap.mapParams.title).toBe('4326-zxy-tile');
225+
expect(datavizWebmap.layerAdded).toBe(1);
226+
done();
227+
}
228+
});
229+
209230
it('jsonsql', (done) => {
210231
let options = {
211232
server: server,

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /