diff --git a/modules/renderer/tile_layer.js b/modules/renderer/tile_layer.js index 26fa1e6846..70bf450259 100644 --- a/modules/renderer/tile_layer.js +++ b/modules/renderer/tile_layer.js @@ -16,6 +16,7 @@ export function rendererTileLayer(context) { var _zoom; var _source; var _epsilon = 0; + var _allowedUnderZoomAmount = 0; // Workaround to remove visible grid around tile borders on Chrome with dynamic epsilon for specific browser zoom levels // Should be removed when https://issues.chromium.org/issues/40084005 is resolved @@ -82,7 +83,7 @@ export function rendererTileLayer(context) { } - // Update tiles based on current state of `projection`. + // Update tiles based on current state of projection. function background(selection) { _zoom = geoScaleToZoom(_projection.scale(), _tileSize); @@ -115,31 +116,36 @@ export function rendererTileLayer(context) { // Derive the tiles onscreen, remove those offscreen and position them. - // Important that this part not depend on `_projection` because it's + // Important that this part not depend on _projection because it's // rentered when tiles load/error (see #644). function render(selection) { if (!_source) return; var requests = []; var showDebug = context.getDebug('tile') && !_source.overlay; - if (_source.validZoom(_zoom)) { - tiler.skipNullIsland(!!_source.overlay); - - tiler().forEach(function(d) { - addSource(d); - if (d.url === '') return; - if (typeof d.url !== 'string') return; // Workaround for #2295 - requests.push(d); - if (_cache[d.url] === false && lookUp(d)) { - requests.push(addSource(lookUp(d))); - } - }); + var zoomLevel = Math.max(_source.zoomExtent[0], Math.min(_zoom, _source.zoomExtent[1])); + var effectiveZoom = Math.max( + _source.zoomExtent[0] - _allowedUnderZoomAmount, + Math.min(_zoom, _source.zoomExtent[1]) + ); + + tiler.skipNullIsland(!!_source.overlay); + + tiler().forEach(function(d) { + addSource(d); + if (d.url === '') return; + if (typeof d.url !== 'string') return; // Workaround for #2295 + requests.push(d); + if (_cache[d.url] === false && lookUp(d)) { + requests.push(addSource(lookUp(d))); + } + }); + + requests = uniqueBy(requests, 'url').filter(function(r) { + // Don't re-request tiles which have failed in the past + return _cache[r.url] !== false; + }); - requests = uniqueBy(requests, 'url').filter(function(r) { - // don't re-request tiles which have failed in the past - return _cache[r.url] !== false; - }); - } function load(d3_event, d) { _cache[d.url] = true; @@ -159,8 +165,8 @@ export function rendererTileLayer(context) { } function imageTransform(d) { - var ts = d.tileSize * Math.pow(2, _zoom - d[2]); - var scale = tileSizeAtZoom(d, _zoom); + var ts = d.tileSize * Math.pow(2, effectiveZoom - d[2]); + var scale = tileSizeAtZoom(d, effectiveZoom); return 'translate(' + ((d[0] * ts) * _tileSize / d.tileSize - _tileOrigin[0] ) + 'px,' + @@ -307,5 +313,12 @@ export function rendererTileLayer(context) { }; + background.allowedUnderZoomAmount = function(val) { + if (!arguments.length) return _allowedUnderZoomAmount; + _allowedUnderZoomAmount = val; + return background; + }; + + return background; } diff --git a/modules/ui/map_in_map.js b/modules/ui/map_in_map.js index 74c09dab36..d890d43380 100644 --- a/modules/ui/map_in_map.js +++ b/modules/ui/map_in_map.js @@ -13,7 +13,8 @@ import { utilSetTransform } from '../util'; export function uiMapInMap(context) { function mapInMap(selection) { - var backgroundLayer = rendererTileLayer(context); + var backgroundLayer = rendererTileLayer(context) + .allowedUnderZoomAmount(1); var overlayLayers = {}; var projection = geoRawMercator(); var dataLayer = svgData(projection, context).showLabels(false);