From fb324dd86545e3cd1bc498ea331fb89c7c58b4cb Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Fri, 22 Jun 2018 12:24:40 -0400 Subject: [PATCH] Allow d3.geo.tile to fetch margin tiles (beyond viewport covering) --- modules/lib/d3.geo.tile.js | 128 +++++++++++++++++++-------------- modules/services/streetside.js | 9 ++- 2 files changed, 79 insertions(+), 58 deletions(-) diff --git a/modules/lib/d3.geo.tile.js b/modules/lib/d3.geo.tile.js index 2afad11b6..364c1bf05 100644 --- a/modules/lib/d3.geo.tile.js +++ b/modules/lib/d3.geo.tile.js @@ -2,66 +2,84 @@ import { range as d3_range } from 'd3-array'; export function d3geoTile() { - var size = [960, 500], - scale = 256, - scaleExtent = [0, 20], - translate = [size[0] / 2, size[1] / 2], - zoomDelta = 0; + var _size = [960, 500]; + var _scale = 256; + var _scaleExtent = [0, 20]; + var _translate = [_size[0] / 2, _size[1] / 2]; + var _zoomDelta = 0; + var _margin = 0; - function bound(_) { - return Math.min(scaleExtent[1], Math.max(scaleExtent[0], _)); - } + function bound(val) { + return Math.min(_scaleExtent[1], Math.max(_scaleExtent[0], val)); + } - function tile() { - var z = Math.max(Math.log(scale) / Math.LN2 - 8, 0), - z0 = bound(Math.round(z + zoomDelta)), - k = Math.pow(2, z - z0 + 8), - origin = [(translate[0] - scale / 2) / k, (translate[1] - scale / 2) / k], - tiles = [], - cols = d3_range(Math.max(0, Math.floor(-origin[0])), Math.max(0, Math.ceil(size[0] / k - origin[0]))), - rows = d3_range(Math.max(0, Math.floor(-origin[1])), Math.max(0, Math.ceil(size[1] / k - origin[1]))); + function tile() { + var z = Math.max(Math.log(_scale) / Math.LN2 - 8, 0); + var z0 = bound(Math.round(z + _zoomDelta)); + var k = Math.pow(2, z - z0 + 8); + var origin = [ + (_translate[0] - _scale / 2) / k, + (_translate[1] - _scale / 2) / k + ]; + var tiles = []; - rows.forEach(function(y) { - cols.forEach(function(x) { - tiles.push([x, y, z0]); - }); - }); + var cols = d3_range( + Math.max(0, Math.floor(-origin[0]) - _margin), + Math.max(0, Math.ceil(_size[0] / k - origin[0]) + _margin) + ); + var rows = d3_range( + Math.max(0, Math.floor(-origin[1]) - _margin), + Math.max(0, Math.ceil(_size[1] / k - origin[1]) + _margin) + ); - tiles.translate = origin; - tiles.scale = k; + rows.forEach(function(y) { + cols.forEach(function(x) { + tiles.push([x, y, z0]); + }); + }); - return tiles; - } + tiles.translate = origin; + tiles.scale = k; + + return tiles; + } + + tile.scaleExtent = function(val) { + if (!arguments.length) return _scaleExtent; + _scaleExtent = val; + return tile; + }; + + tile.size = function(val) { + if (!arguments.length) return _size; + _size = val; + return tile; + }; + + tile.scale = function(val) { + if (!arguments.length) return _scale; + _scale = val; + return tile; + }; + + tile.translate = function(val) { + if (!arguments.length) return _translate; + _translate = val; + return tile; + }; + + tile.zoomDelta = function(val) { + if (!arguments.length) return _zoomDelta; + _zoomDelta = +val; + return tile; + }; + + // number to extend the rows/columns beyond those covering the viewport + tile.margin = function(val) { + if (!arguments.length) return _margin; + _margin = +val; + return tile; + }; - tile.scaleExtent = function(_) { - if (!arguments.length) return scaleExtent; - scaleExtent = _; return tile; - }; - - tile.size = function(_) { - if (!arguments.length) return size; - size = _; - return tile; - }; - - tile.scale = function(_) { - if (!arguments.length) return scale; - scale = _; - return tile; - }; - - tile.translate = function(_) { - if (!arguments.length) return translate; - translate = _; - return tile; - }; - - tile.zoomDelta = function(_) { - if (!arguments.length) return zoomDelta; - zoomDelta = +_; - return tile; - }; - - return tile; } diff --git a/modules/services/streetside.js b/modules/services/streetside.js index e4e020ae7..869aa4650 100644 --- a/modules/services/streetside.js +++ b/modules/services/streetside.js @@ -89,12 +89,15 @@ function getTiles(projection) { s / 2 - projection.translate()[1] ]; - return d3_geoTile() + var tiler = d3_geoTile() .scaleExtent([tileZoom, tileZoom]) .scale(s) .size(projection.clipExtent()[1]) - .translate(projection.translate())() - .map(function (tile) { + .translate(projection.translate()) + .margin(1); // request nearby tiles so we can connect sequences. + + return tiler() + .map(function(tile) { var x = tile[0] * ts - origin[0]; var y = tile[1] * ts - origin[1]; return {