From 4eba3a0973f7b2b8e3b48a87ad969f446bf88533 Mon Sep 17 00:00:00 2001 From: Julio Garcia Date: Tue, 8 Nov 2016 10:02:41 -0800 Subject: [PATCH 1/4] Adding support for minNativeZoom in TileLayer.js --- src/layer/tile/TileLayer.js | 50 ++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/src/layer/tile/TileLayer.js b/src/layer/tile/TileLayer.js index a3848092..080f833e 100644 --- a/src/layer/tile/TileLayer.js +++ b/src/layer/tile/TileLayer.js @@ -48,6 +48,12 @@ L.TileLayer = L.GridLayer.extend({ // from `maxNativeZoom` level and auto-scaled. maxNativeZoom: null, + // @option minNativeZoom: Number = null + // Minimum zoom number the tile source has available. If it is specified, + // the tiles on all zoom levels lower than `minNativeZoom` will be loaded + // from `minNativeZoom` level and auto-scaled. + minNativeZoom: null, + // @option subdomains: String|String[] = 'abc' // Subdomains of the tile service. Can be passed in the form of one string (where each letter is a subdomain name) or an array of strings. subdomains: 'abc', @@ -197,12 +203,20 @@ L.TileLayer = L.GridLayer.extend({ var map = this._map, tileSize = L.GridLayer.prototype.getTileSize.call(this), zoom = this._tileZoom + this.options.zoomOffset, - zoomN = this.options.maxNativeZoom; + minNativeZoom = this.options.minNativeZoom, + maxNativeZoom = this.options.maxNativeZoom; - // increase tile size when overscaling - return zoomN !== null && zoom > zoomN ? - tileSize.divideBy(map.getZoomScale(zoomN, zoom)).round() : - tileSize; + // decrease tile size when scaling below minNativeZoom + if (minNativeZoom !== null && zoom < minNativeZoom) { + return tileSize.divideBy(map.getZoomScale(minNativeZoom, zoom)).round(); + } + + // increase tile size when scaling above maxNativeZoom + if(maxNativeZoom !== null && zoom > maxNativeZoom){ + return tileSize.divideBy(map.getZoomScale(maxNativeZoom, zoom)).round(); + } + + return tileSize; }, _onTileRemove: function (e) { @@ -210,17 +224,29 @@ L.TileLayer = L.GridLayer.extend({ }, _getZoomForUrl: function () { + var zoom = this._tileZoom, + maxZoom = this.options.maxZoom, + zoomReverse = this.options.zoomReverse, + zoomOffset = this.options.zoomOffset, + minNativeZoom = this.options.minNativeZoom, + maxNativeZoom = this.options.maxNativeZoom; - var options = this.options, - zoom = this._tileZoom; - - if (options.zoomReverse) { - zoom = options.maxZoom - zoom; + if (zoomReverse) { + zoom = maxZoom - zoom; } - zoom += options.zoomOffset; + zoom += zoomOffset; - return options.maxNativeZoom !== null ? Math.min(zoom, options.maxNativeZoom) : zoom; + if (minNativeZoom !== null && zoom < minNativeZoom) { + return minNativeZoom; + } + + // increase tile size when scaling above maxNativeZoom + if(maxNativeZoom !== null && zoom > maxNativeZoom) { + return maxNativeZoom; + } + + return zoom; }, _getSubdomain: function (tilePoint) { From 243daa90efd5c2addde1e3e1e7cabeb0066ca883 Mon Sep 17 00:00:00 2001 From: Julio Garcia Date: Tue, 8 Nov 2016 16:52:07 -0800 Subject: [PATCH 2/4] Fixing linting errors --- src/layer/tile/TileLayer.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/layer/tile/TileLayer.js b/src/layer/tile/TileLayer.js index 080f833e..eab4cd6d 100644 --- a/src/layer/tile/TileLayer.js +++ b/src/layer/tile/TileLayer.js @@ -201,10 +201,10 @@ L.TileLayer = L.GridLayer.extend({ getTileSize: function () { var map = this._map, - tileSize = L.GridLayer.prototype.getTileSize.call(this), - zoom = this._tileZoom + this.options.zoomOffset, - minNativeZoom = this.options.minNativeZoom, - maxNativeZoom = this.options.maxNativeZoom; + tileSize = L.GridLayer.prototype.getTileSize.call(this), + zoom = this._tileZoom + this.options.zoomOffset, + minNativeZoom = this.options.minNativeZoom, + maxNativeZoom = this.options.maxNativeZoom; // decrease tile size when scaling below minNativeZoom if (minNativeZoom !== null && zoom < minNativeZoom) { @@ -212,7 +212,7 @@ L.TileLayer = L.GridLayer.extend({ } // increase tile size when scaling above maxNativeZoom - if(maxNativeZoom !== null && zoom > maxNativeZoom){ + if (maxNativeZoom !== null && zoom > maxNativeZoom) { return tileSize.divideBy(map.getZoomScale(maxNativeZoom, zoom)).round(); } @@ -225,11 +225,11 @@ L.TileLayer = L.GridLayer.extend({ _getZoomForUrl: function () { var zoom = this._tileZoom, - maxZoom = this.options.maxZoom, - zoomReverse = this.options.zoomReverse, - zoomOffset = this.options.zoomOffset, - minNativeZoom = this.options.minNativeZoom, - maxNativeZoom = this.options.maxNativeZoom; + maxZoom = this.options.maxZoom, + zoomReverse = this.options.zoomReverse, + zoomOffset = this.options.zoomOffset, + minNativeZoom = this.options.minNativeZoom, + maxNativeZoom = this.options.maxNativeZoom; if (zoomReverse) { zoom = maxZoom - zoom; @@ -242,7 +242,7 @@ L.TileLayer = L.GridLayer.extend({ } // increase tile size when scaling above maxNativeZoom - if(maxNativeZoom !== null && zoom > maxNativeZoom) { + if (maxNativeZoom !== null && zoom > maxNativeZoom) { return maxNativeZoom; } From d303a7b6812d6944c6c76038b3af8783ada18884 Mon Sep 17 00:00:00 2001 From: Julio Garcia Date: Thu, 10 Nov 2016 13:11:11 -0800 Subject: [PATCH 3/4] Adding Unit Tests for minNativeZoom and maxNativeZoom --- spec/suites/layer/tile/TileLayerSpec.js | 89 +++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/spec/suites/layer/tile/TileLayerSpec.js b/spec/suites/layer/tile/TileLayerSpec.js index 2b814719..4f03a0c1 100644 --- a/spec/suites/layer/tile/TileLayerSpec.js +++ b/spec/suites/layer/tile/TileLayerSpec.js @@ -378,4 +378,93 @@ describe('TileLayer', function () { }); }); }); + + describe('minNativeZoom', function () { + before(function () { + div = document.createElement('div'); + div.style.width = '400px'; + div.style.height = '400px'; + div.style.visibility = 'hidden'; + + document.body.appendChild(div); + + map = L.map(div).setView([0, 0], 0); + }); + + it('returns downscaled tileSize when zoom is lower than minNativeZoom (zoom = 0, minNativeZoom = 1)', function () { + var layer = L.tileLayer('http://{s}.example.com/{z}/{-y}/{x}.png', { + minNativeZoom: 1, + tileSize: 256 + }).addTo(map); + map.setView([0, 0], 0); + expect(map.getZoom()).to.equal(0); + expect(layer.getTileSize().x).to.equal(128); + expect(layer.getTileSize().y).to.equal(128); + }); + + it('returns regular tileSize when zoom is equal to minNativeZoom (zoom = 1, minNativeZoom = 1)', function () { + var layer = L.tileLayer('http://{s}.example.com/{z}/{-y}/{x}.png', { + minNativeZoom: 1, + tileSize: 256 + }).addTo(map); + map.setView([0, 0], 1); + expect(map.getZoom()).to.equal(1); + expect(layer.getTileSize().x).to.equal(256); + expect(layer.getTileSize().y).to.equal(256); + }); + + it('returns regular tileSize when zoom is greater than minNativeZoom (zoom = 2, minNativeZoom = 1)', function () { + var layer = L.tileLayer('http://{s}.example.com/{z}/{-y}/{x}.png', { + minNativeZoom: 1, + tileSize: 256 + }).addTo(map); + map.setView([0, 0], 2); + expect(map.getZoom()).to.equal(2); + expect(layer.getTileSize().x).to.equal(256); + expect(layer.getTileSize().y).to.equal(256); + }); + }); + + describe('maxNativeZoom', function () { + before(function () { + div = document.createElement('div'); + div.style.width = '400px'; + div.style.height = '400px'; + div.style.visibility = 'hidden'; + + document.body.appendChild(div); + + map = L.map(div).setView([0, 0], 0); + }); + + it('returns upscaled tileSize when zoom is higher than maxNativeZoom (zoom = 2, maxNativeZoom = 1)', function () { + var layer = L.tileLayer('http://{s}.example.com/{z}/{-y}/{x}.png', { + maxNativeZoom: 1, + tileSize: 256 + }).addTo(map); + map.setView([0, 0], 2); + expect(layer.getTileSize().x).to.equal(512); + expect(layer.getTileSize().y).to.equal(512); + }); + + it('returns regular tileSize when zoom is equal to minNativeZoom (zoom = 1, maxNativeZoom = 1)', function () { + var layer = L.tileLayer('http://{s}.example.com/{z}/{-y}/{x}.png', { + maxNativeZoom: 1, + tileSize: 256 + }).addTo(map); + map.setView([0, 0], 1); + expect(layer.getTileSize().x).to.equal(256); + expect(layer.getTileSize().y).to.equal(256); + }); + + it('returns regular tileSize when zoom is lower than minNativeZoom (zoom = 0, maxNativeZoom = 1)', function () { + var layer = L.tileLayer('http://{s}.example.com/{z}/{-y}/{x}.png', { + maxNativeZoom: 1, + tileSize: 256 + }).addTo(map); + map.setView([0, 0], 0); + expect(layer.getTileSize().x).to.equal(256); + expect(layer.getTileSize().y).to.equal(256); + }); + }); }); From 3875722edf85222f04ed055a98e114dbfc46bab1 Mon Sep 17 00:00:00 2001 From: Julio Garcia Date: Thu, 10 Nov 2016 14:05:45 -0800 Subject: [PATCH 4/4] Removing unneeded comment --- src/layer/tile/TileLayer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/layer/tile/TileLayer.js b/src/layer/tile/TileLayer.js index eab4cd6d..e32ba739 100644 --- a/src/layer/tile/TileLayer.js +++ b/src/layer/tile/TileLayer.js @@ -241,7 +241,6 @@ L.TileLayer = L.GridLayer.extend({ return minNativeZoom; } - // increase tile size when scaling above maxNativeZoom if (maxNativeZoom !== null && zoom > maxNativeZoom) { return maxNativeZoom; }