diff --git a/src/GlobalConfig.ts b/src/GlobalConfig.ts index bfd34253e9..3bea86d599 100644 --- a/src/GlobalConfig.ts +++ b/src/GlobalConfig.ts @@ -17,6 +17,8 @@ const GlobalConfig = { //每个Worker Message中封装的task message数量 messagePostRatioPerWorker: 0.3, //当前运行环境的最大FPS,用户可以手动配置,否则将自动检测并赋值,为地图锁帧渲染准备 - maxFPS: 0 + maxFPS: 0, + //投影最大层级,即地图最大能放大到多大层级 + crsMaxNativeZoom: 22 }; export default GlobalConfig; diff --git a/src/map/spatial-reference/SpatialReference.ts b/src/map/spatial-reference/SpatialReference.ts index 44daf71243..5ab311f218 100644 --- a/src/map/spatial-reference/SpatialReference.ts +++ b/src/map/spatial-reference/SpatialReference.ts @@ -7,7 +7,7 @@ import Transformation from '../../geo/transformation/Transformation'; import { Measurer, DEFAULT } from '../../geo/measurer'; import loadWMTS from './SpatialReference.WMTS' import loadArcgis from './SpatialReference.Arc' -const MAX_ZOOM = 23; +import GlobalConfig from '../../GlobalConfig'; export type FullExtent = { top: number @@ -22,118 +22,127 @@ export type SpatialReferenceType = { fullExtent?: FullExtent | JsonExtent; } -const DefaultSpatialReference: Record = { - 'EPSG:3857': { - 'projection': 'EPSG:3857', - 'resolutions': (function () { - const resolutions = []; - const d = 2 * 6378137 * Math.PI; - for (let i = 0; i < MAX_ZOOM; i++) { - resolutions[i] = d / (256 * Math.pow(2, i)); - } - return resolutions; - })(), - 'fullExtent': { - 'top': 6378137 * Math.PI, - 'left': -6378137 * Math.PI, - 'bottom': -6378137 * Math.PI, - 'right': 6378137 * Math.PI - } - }, - 'EPSG:4326': { - 'projection': 'EPSG:4326', - 'fullExtent': { - 'top': 90, - 'left': -180, - 'bottom': -90, - 'right': 180 - }, - 'resolutions': (function () { - const resolutions = []; - for (let i = 0; i < MAX_ZOOM; i++) { - resolutions[i] = 180 / (Math.pow(2, i) * 128); - } - return resolutions; - })() - }, - 'BAIDU': { - 'projection': 'baidu', - 'resolutions': (function () { - let res = Math.pow(2, 18); - const resolutions = []; - for (let i = 0; i < MAX_ZOOM; i++) { - resolutions[i] = res; - res *= 0.5; - } - return resolutions; - })(), - 'fullExtent': { - 'top': 33554432, - 'left': -33554432, - 'bottom': -33554432, - 'right': 33554432 - } - }, - 'IDENTITY': { - 'projection': 'identity', - 'resolutions': (function () { - let res = Math.pow(2, 8); - const resolutions = []; - for (let i = 0; i < MAX_ZOOM; i++) { - resolutions[i] = res; - res *= 0.5; - } - return resolutions; - })(), - 'fullExtent': { - 'top': 200000, - 'left': -200000, - 'bottom': -200000, - 'right': 200000 - } - }, - - // TileSystem: [1, -1, -6378137 * Math.PI, 6378137 * Math.PI] - 'PRESET-VT-3857': { - 'projection': 'EPSG:3857', - 'resolutions': (function () { - const resolutions = []; - const d = 6378137 * Math.PI; - for (let i = 0; i < MAX_ZOOM; i++) { - resolutions[i] = d / (256 * Math.pow(2, i)); - } - return resolutions; - })(), - 'fullExtent': { - 'top': 6378137 * Math.PI, - 'left': -6378137 * Math.PI, - 'bottom': -6378137 * Math.PI, - 'right': 6378137 * Math.PI - } - }, - - 'PRESET-VT-4326': { - 'projection': 'EPSG:4326', - 'fullExtent': { - 'top': 90, - 'left': -180, - 'bottom': -90, - 'right': 180 - }, - 'resolutions': (function () { - const resolutions = []; - for (let i = 0; i < MAX_ZOOM; i++) { - resolutions[i] = 180 / 4 / (Math.pow(2, i) * 128); +let DEFAULT_CRS: Record; + + + +function _getDefaultSpatialReference(): Record { + if (!DEFAULT_CRS) { + const crsMaxNativeZoom = Math.round(GlobalConfig.crsMaxNativeZoom || 22); + DEFAULT_CRS = { + 'EPSG:3857': { + 'projection': 'EPSG:3857', + 'resolutions': (function () { + const resolutions = []; + const d = 2 * 6378137 * Math.PI; + for (let i = 0; i <= crsMaxNativeZoom; i++) { + resolutions[i] = d / (256 * Math.pow(2, i)); + } + return resolutions; + })(), + 'fullExtent': { + 'top': 6378137 * Math.PI, + 'left': -6378137 * Math.PI, + 'bottom': -6378137 * Math.PI, + 'right': 6378137 * Math.PI + } + }, + 'EPSG:4326': { + 'projection': 'EPSG:4326', + 'fullExtent': { + 'top': 90, + 'left': -180, + 'bottom': -90, + 'right': 180 + }, + 'resolutions': (function () { + const resolutions = []; + for (let i = 0; i <= crsMaxNativeZoom; i++) { + resolutions[i] = 180 / (Math.pow(2, i) * 128); + } + return resolutions; + })() + }, + 'BAIDU': { + 'projection': 'baidu', + 'resolutions': (function () { + let res = Math.pow(2, 18); + const resolutions = []; + for (let i = 0; i <= crsMaxNativeZoom; i++) { + resolutions[i] = res; + res *= 0.5; + } + return resolutions; + })(), + 'fullExtent': { + 'top': 33554432, + 'left': -33554432, + 'bottom': -33554432, + 'right': 33554432 + } + }, + 'IDENTITY': { + 'projection': 'identity', + 'resolutions': (function () { + let res = Math.pow(2, 8); + const resolutions = []; + for (let i = 0; i <= crsMaxNativeZoom; i++) { + resolutions[i] = res; + res *= 0.5; + } + return resolutions; + })(), + 'fullExtent': { + 'top': 200000, + 'left': -200000, + 'bottom': -200000, + 'right': 200000 + } + }, + + // TileSystem: [1, -1, -6378137 * Math.PI, 6378137 * Math.PI] + 'PRESET-VT-3857': { + 'projection': 'EPSG:3857', + 'resolutions': (function () { + const resolutions = []; + const d = 6378137 * Math.PI; + for (let i = 0; i <= crsMaxNativeZoom; i++) { + resolutions[i] = d / (256 * Math.pow(2, i)); + } + return resolutions; + })(), + 'fullExtent': { + 'top': 6378137 * Math.PI, + 'left': -6378137 * Math.PI, + 'bottom': -6378137 * Math.PI, + 'right': 6378137 * Math.PI + } + }, + + 'PRESET-VT-4326': { + 'projection': 'EPSG:4326', + 'fullExtent': { + 'top': 90, + 'left': -180, + 'bottom': -90, + 'right': 180 + }, + 'resolutions': (function () { + const resolutions = []; + for (let i = 0; i <= crsMaxNativeZoom; i++) { + resolutions[i] = 180 / 4 / (Math.pow(2, i) * 128); + } + return resolutions; + })() } - return resolutions; - })() + }; + DEFAULT_CRS['EPSG:4490'] = DEFAULT_CRS['EPSG:4326']; + DEFAULT_CRS['PRESET-3857-512'] = DEFAULT_CRS['PRESET-VT-3857']; + DEFAULT_CRS['PRESET-4326-512'] = DEFAULT_CRS['PRESET-VT-4326']; + DEFAULT_CRS['PRESET-4490-512'] = DEFAULT_CRS['PRESET-VT-4326']; } -}; - -DefaultSpatialReference['EPSG:4490'] = DefaultSpatialReference['EPSG:4326']; -DefaultSpatialReference['PRESET-3857-512'] = DefaultSpatialReference['PRESET-VT-3857']; -DefaultSpatialReference['PRESET-4326-512'] = DefaultSpatialReference['PRESET-VT-4326']; -DefaultSpatialReference['PRESET-4490-512'] = DefaultSpatialReference['PRESET-VT-4326']; + return DEFAULT_CRS; +} /** * 空间参考类 @@ -162,18 +171,18 @@ export default class SpatialReference { static registerPreset(name: string, value: SpatialReferenceType) { name = name && name.toUpperCase(); - if (DefaultSpatialReference[name]) { + if (_getDefaultSpatialReference()[name]) { console.warn(`Spatial reference ${name} already registered.`); } - DefaultSpatialReference[name] = value; + _getDefaultSpatialReference()[name] = value; } static getPreset(preset: string) { - return DefaultSpatialReference[preset.toUpperCase()]; + return _getDefaultSpatialReference()[preset.toUpperCase()]; } static getAllPresets() { - return Object.keys(DefaultSpatialReference); + return Object.keys(_getDefaultSpatialReference()); } static loadArcgis(url: string, cb: (_, spatialRef?) => void, options: any) { @@ -306,7 +315,7 @@ export default class SpatialReference { resolutions = this.options['resolutions']; if (!resolutions) { if (projection['code']) { - defaultSpatialRef = DefaultSpatialReference[projection['code'].toUpperCase()]; + defaultSpatialRef = _getDefaultSpatialReference()[projection['code'].toUpperCase()]; if (defaultSpatialRef) { resolutions = defaultSpatialRef['resolutions']; this.isEPSG = projection['code'] !== 'IDENTITY'; @@ -332,7 +341,7 @@ export default class SpatialReference { let fullExtent = this.options['fullExtent']; if (!fullExtent) { if (projection['code']) { - defaultSpatialRef = DefaultSpatialReference[projection['code'].toUpperCase()]; + defaultSpatialRef = _getDefaultSpatialReference()[projection['code'].toUpperCase()]; if (defaultSpatialRef) { fullExtent = defaultSpatialRef['fullExtent']; } @@ -444,5 +453,5 @@ export default class SpatialReference { export function getDefaultSpatialReference(): Record { - return JSON.parse(JSON.stringify(DefaultSpatialReference)); + return JSON.parse(JSON.stringify(_getDefaultSpatialReference())); } diff --git a/test/SpecCommon.js b/test/SpecCommon.js index 6fd2ceb742..72e9a2a647 100644 --- a/test/SpecCommon.js +++ b/test/SpecCommon.js @@ -7,6 +7,7 @@ if (maptalks.Browser.ie) { 'markerHeight': 20 }; } +maptalks.GlobalConfig.crsMaxNativeZoom = 25; /*eslint-disable no-unused-vars */ diff --git a/test/map/MapSpec.js b/test/map/MapSpec.js index 2a8f3c76ea..021783e8d4 100644 --- a/test/map/MapSpec.js +++ b/test/map/MapSpec.js @@ -7,6 +7,7 @@ describe('Map.Spec', function () { var center = new maptalks.Coordinate(118.846825, 32.046534); beforeEach(function () { + container = document.createElement('div'); container.style.width = '4px'; container.style.height = '3px'; @@ -27,6 +28,16 @@ describe('Map.Spec', function () { map.remove(); REMOVE_CONTAINER(container); }); + it('custom crsMaxNativeZoom', function (done) { + const maxZoom = map.getMaxZoom(); + expect(maxZoom).to.be.eql(maptalks.GlobalConfig.crsMaxNativeZoom); + const crs = maptalks.getDefaultSpatialReference(); + for (const epsg in crs) { + const resolutions = crs[epsg].resolutions; + expect(resolutions.length).to.be.eql(maptalks.GlobalConfig.crsMaxNativeZoom + 1); + } + done(); + }); describe('status', function () { it('has id and is readonly', function () { @@ -913,14 +924,14 @@ describe('Map.Spec', function () { it('#2128 clear glRes cache when SpatialReference change', function (done) { //clear all layers const glRes = map.getGLRes(); - map.setSpatialReference({ projection:'EPSG:4326' }); + map.setSpatialReference({ projection: 'EPSG:4326' }); setTimeout(() => { expect(map.getGLRes()).not.to.be(glRes); done(); }, 100); }); - it('map\'s center has altitude', function() { + it('map\'s center has altitude', function () { const center = map.getCenter(); center.z = 100; map.setCenter(center); diff --git a/test/map/spatial-reference/SpatialRefUpdateSpec.js b/test/map/spatial-reference/SpatialRefUpdateSpec.js index c92c18c6b1..a8c1825327 100644 --- a/test/map/spatial-reference/SpatialRefUpdateSpec.js +++ b/test/map/spatial-reference/SpatialRefUpdateSpec.js @@ -29,7 +29,7 @@ describe('SpatialReference.Update', function () { projection: 'baidu', resolutions: resolutions }; - expect(map.getMaxZoom()).to.be.eql(22); + expect(map.getMaxZoom()).to.be.eql(25); map.setSpatialReference(spatialReference); expect(map.getMaxZoom()).to.be.eql(24); });