@@ -130,7 +130,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa
130130 extent: [extent.leftBottom.x, extent.leftBottom.y, extent.rightTop.x, extent.rightTop.y],
131131 wkt: this._getProjectionWKT(projection)
132132 };
133- if (!crsManager.getCRS(epsgCode) && baseLayer.layerType !== 'ZXY_TILE' ) {
133+ if (!crsManager.getCRS(epsgCode)) {
134134 switch (baseLayer.layerType) {
135135 case 'MAPBOXSTYLE': {
136136 let url = baseLayer.dataSource.url;
@@ -165,6 +165,11 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa
165165 }
166166 break;
167167 }
168+ case 'ZXY_TILE': {
169+ const extent = this._getZXYTileCrsExtent(baseLayer);
170+ crs.extent = extent;
171+ break;
172+ }
168173 default:
169174 crs = null;
170175 break;
@@ -240,14 +245,20 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa
240245 let zoomBase = 0;
241246 let { bounds, minZoom, maxZoom } = this.mapOptions;
242247 const interactive = this.mapOptions.interactive;
248+ const tileSize = mapInfo.baseLayer.tileSize;
249+
250+ if (mapInfo.baseLayer.layerType === 'ZXY_TILE') {
251+ const {leftBottom, rightTop} = mapInfo.extent;
252+ mapInfo.visibleExtent = [leftBottom.x, leftBottom.y, rightTop.x, rightTop.y];
253+ }
243254 if (isNaN(minZoom)) {
244255 minZoom = mapInfo.minScale
245- ? this._transformScaleToZoom(mapInfo.minScale, mapRepo.CRS.get(this.baseProjection))
256+ ? this._transformScaleToZoom(mapInfo.minScale, mapRepo.CRS.get(this.baseProjection), tileSize )
246257 : 0;
247258 }
248259 if (isNaN(maxZoom)) {
249260 maxZoom = mapInfo.maxScale
250- ? this._transformScaleToZoom(mapInfo.maxScale, mapRepo.CRS.get(this.baseProjection))
261+ ? this._transformScaleToZoom(mapInfo.maxScale, mapRepo.CRS.get(this.baseProjection), tileSize )
251262 : 22;
252263 }
253264 if (mapInfo.visibleExtent && mapInfo.visibleExtent.length === 4 && !bounds) {
@@ -262,8 +273,8 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa
262273 if (!bounds) {
263274 if (mapInfo.minScale && mapInfo.maxScale) {
264275 zoomBase = Math.min(
265- this._transformScaleToZoom(mapInfo.minScale, mapRepo.CRS.get(this.baseProjection)),
266- this._transformScaleToZoom(mapInfo.maxScale, mapRepo.CRS.get(this.baseProjection))
276+ this._transformScaleToZoom(mapInfo.minScale, mapRepo.CRS.get(this.baseProjection), tileSize ),
277+ this._transformScaleToZoom(mapInfo.maxScale, mapRepo.CRS.get(this.baseProjection), tileSize )
267278 );
268279 } else {
269280 zoomBase = +Math.log2(
@@ -433,8 +444,8 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa
433444 if (layer.visibleScale) {
434445 const { minScale, maxScale } = layer.visibleScale;
435446 const crs = this.map.getCRS();
436- layer.minzoom = Math.max(this._transformScaleToZoom(minScale, crs), 0);
437- layer.maxzoom = Math.min(24, this._transformScaleToZoom(maxScale, crs) + 0.0000001);
447+ layer.minzoom = Math.max(this._transformScaleToZoom(minScale, crs, layer.tileSize ), 0);
448+ layer.maxzoom = Math.min(24, this._transformScaleToZoom(maxScale, crs, layer.tileSize ) + 0.0000001);
438449 }
439450
440451 if (type === 'tile') {
@@ -701,17 +712,26 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa
701712 }
702713
703714 _createZXYLayer(layerInfo, addedCallback) {
704- const { url, subdomains, layerID, name, visible, tileSize, resolutions, origin, minZoom: minzoom, maxZoom: maxzoom } = layerInfo;
715+ const { url, subdomains, layerID, name, visible, tileSize, resolutions, origin, minZoom: minzoom, maxZoom: maxzoom, mapBounds } = layerInfo;
705716 const urls = (subdomains && subdomains.length) ? subdomains.map(item => url.replace('{s}', item)) : [url];
706717 const layerId = layerID || name;
707718 const isSupport = this._isSupportZXYTileLayer({ resolutions, tileSize, origin });
708719 if (isSupport) {
709- this._addBaselayer({ url: urls, layerID: layerId, visibility: visible, minzoom, maxzoom, isIserver: false, tileSize });
720+ const bounds = this._getSourceBounds(mapBounds);
721+ this._addBaselayer({ url: urls, layerID: layerId, visibility: visible, minzoom, maxzoom, bounds, isIserver: false, tileSize });
710722 } else {
711723 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});
712724 }
713725 addedCallback && addedCallback();
714726 }
727+ _getSourceBounds(mapBounds) {
728+ if(!mapBounds) {
729+ return;
730+ }
731+ const lb = this._unproject([mapBounds[0], mapBounds[1]]);
732+ const rt = this._unproject([mapBounds[2], mapBounds[3]]);
733+ return [...lb, ...rt];
734+ }
715735 _isSupportZXYTileLayer({ resolutions, tileSize, origin }) {
716736 const isOldWebMecartor = origin === undefined && resolutions === undefined;
717737 if (isOldWebMecartor) {
@@ -745,6 +765,18 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa
745765 }
746766 return resolutions;
747767 }
768+ _getZXYTileCrsExtent(layerInfo) {
769+ const { tileSize = 256, resolutions, origin } = layerInfo;
770+ if (resolutions) {
771+ const maxResolution = resolutions.sort((a, b) => b - a)[0];
772+ const size = maxResolution * tileSize;
773+ return [origin[0], origin[1] - size, origin[0] + size, origin[1]];
774+ }
775+ // 兼容之前的3857全球剖分
776+ if (this.baseProjection == 'EPSG:3857') {
777+ return [-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892];
778+ }
779+ }
748780
749781 _createDynamicTiledLayer(layerInfo, addedCallback) {
750782 const url = layerInfo.url;
@@ -2969,10 +3001,11 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, crsMa
29693001 return Math.max(bounds[2] - bounds[0], bounds[3] - bounds[1]) / tileSize;
29703002 }
29713003
2972- _transformScaleToZoom(scale, crs) {
3004+ _transformScaleToZoom(scale, crs, tileSize) {
3005+ tileSize = tileSize || 512
29733006 const extent = crs.getExtent();
29743007 const unit = crs.unit;
2975- const scaleBase = 1.0 / Util.getScaleFromResolutionDpi((extent[2] - extent[0]) / 512 , 96, unit);
3008+ const scaleBase = 1.0 / Util.getScaleFromResolutionDpi((extent[2] - extent[0]) / tileSize , 96, unit);
29763009 const scaleDenominator = scale.split(':')[1];
29773010 return Math.min(24, +Math.log2(scaleBase / +scaleDenominator).toFixed(2));
29783011 }
0 commit comments