From e4d829ec06ccc9d73a8e45b8c627f95ca8fb0395 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sat, 21 Jul 2018 10:03:40 -0400 Subject: [PATCH 1/4] Have the tiler return filtered results - re: skipNullIsland --- modules/services/mapillary.js | 3 +- modules/services/openstreetcam.js | 3 +- modules/services/osm.js | 1 - modules/services/streetside.js | 7 +-- modules/util/tile.js | 72 +++++++++++++++---------------- 5 files changed, 40 insertions(+), 46 deletions(-) diff --git a/modules/services/mapillary.js b/modules/services/mapillary.js index cdf04aa3b..4d19f43af 100644 --- a/modules/services/mapillary.js +++ b/modules/services/mapillary.js @@ -23,7 +23,7 @@ import { svgDefs } from '../svg'; import { utilDetect } from '../util/detect'; import { utilQsString, utilRebind, utilTile } from '../util'; -var geoTile = utilTile(); +var geoTile = utilTile().skipNullIsland(true); var apibase = 'https://a.mapillary.com/v3/'; var viewercss = 'mapillary-js/mapillary.min.css'; @@ -86,7 +86,6 @@ function loadTiles(which, url, projection) { var dimension = projection.clipExtent()[1]; var tiles = geoTile.getTiles(projection, dimension, tileZoom, 0); - tiles = geoTile.filterNullIsland(tiles); geoTile.removeInflightRequests(which, tiles, abortRequest, ',0'); diff --git a/modules/services/openstreetcam.js b/modules/services/openstreetcam.js index 73483dddc..89b391022 100644 --- a/modules/services/openstreetcam.js +++ b/modules/services/openstreetcam.js @@ -33,7 +33,7 @@ import { utilSetTransform } from '../util'; -var geoTile = utilTile(); +var geoTile = utilTile().skipNullIsland(true); var apibase = 'https://openstreetcam.org'; var maxResults = 1000; @@ -81,7 +81,6 @@ function loadTiles(which, url, projection) { var dimension = projection.clipExtent()[1]; var tiles = geoTile.getTiles(projection, dimension, tileZoom, 0); - tiles = geoTile.filterNullIsland(tiles); geoTile.removeInflightRequests(which, tiles, abortRequest, ',0'); diff --git a/modules/services/osm.js b/modules/services/osm.js index 4263662e2..d7686ce34 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -780,7 +780,6 @@ export default { // get tiles var tiles = geoTile.getTiles(projection, dimensions, tilezoom, 0); - tiles = geoTile.filterNullIsland(tiles); // remove inflight requests that no longer cover the view.. var hadRequests = !_isEmpty(cache.inflight); diff --git a/modules/services/streetside.js b/modules/services/streetside.js index 52ee2c14f..435d0c210 100644 --- a/modules/services/streetside.js +++ b/modules/services/streetside.js @@ -32,7 +32,7 @@ import { utilQsString, utilRebind, utilTile } from '../util'; import Q from 'q'; -var geoTile = utilTile(); +var geoTile = utilTile().skipNullIsland(true); var bubbleApi = 'https://dev.virtualearth.net/mapcontrol/HumanScaleServices/GetBubbles.ashx?'; var streetsideImagesApi = 'https://t.ssl.ak.tiles.virtualearth.net/tiles/'; @@ -95,8 +95,9 @@ function loadTiles(which, url, projection, margin) { var currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0)); var dimension = projection.clipExtent()[1]; - var tiles = geoTile.getTiles(projection, dimension, tileZoom, margin); - tiles = geoTile.filterNullIsland(tiles); + var tiles = geoTile + .margin(margin) + .getTiles(projection, dimension, tileZoom); tiles.forEach(function (tile) { loadNextTilePage(which, currZoom, url, tile); diff --git a/modules/util/tile.js b/modules/util/tile.js index 2179525f7..2ed2474e2 100644 --- a/modules/util/tile.js +++ b/modules/util/tile.js @@ -11,11 +11,14 @@ export function utilTile() { var _translate = [_size[0] / 2, _size[1] / 2]; var _zoomDelta = 0; var _margin = 0; + var _skipNullIsland = false; + function bound(val) { return Math.min(_scaleExtent[1], Math.max(_scaleExtent[0], val)); } + function nearNullIsland(x, y, z) { if (z >= 7) { var center = Math.pow(2, z - 1); @@ -27,7 +30,8 @@ export function utilTile() { return false; } - function tile() { + + function tiler() { 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); @@ -72,13 +76,7 @@ export function utilTile() { * Using d3.geo.tiles.js from lib, gets tile extents for each grid tile in a grid created from * an area around (and including) the current map view extents. */ - tile.getTiles = function(projection, dimensions, tilezoom, margin) { - - // s is the current map scale - // z is the 'Level of Detail', or zoom-level, where Level 1 is far from the earth, and Level 23 is close to the ground. - // ts ('tile size') here is the formula for determining the width/height of the map in pixels, but with a modification. - // See 'Ground Resolution and Map Scale': //https://msdn.microsoft.com/en-us/library/bb259689.aspx. - // As used here, by subtracting constant 'tileZoom' from z (the level), you end up with a much smaller value for the tile size (in pixels). + tiler.getTiles = function(projection, dimensions, tilezoom) { var s = projection.scale() * 2 * Math.PI; var z = Math.max(Math.log(s) / Math.log(2) - 8, 0); var ts = 256 * Math.pow(2, z - tilezoom); @@ -87,18 +85,19 @@ export function utilTile() { s / 2 - projection.translate()[1] ]; - var tiler = this + this .scaleExtent([tilezoom, tilezoom]) .scale(s) .size(dimensions) - .translate(projection.translate()) - .margin(margin || 0); // request nearby tiles so we can connect sequences. + .translate(projection.translate()); - var tiles = tiler() + return tiler() .map(function(tile) { + if (_skipNullIsland && nearNullIsland(tile[0], tile[1], tile[2])) { + return false; + } var x = tile[0] * ts - origin[0]; var y = tile[1] * ts - origin[1]; - return { id: tile.toString(), xyz: tile, @@ -107,21 +106,12 @@ export function utilTile() { projection.invert([x + ts, y]) ) }; - }); - - return tiles; - }; - - - tile.filterNullIsland = function(tiles) { - return tiles.filter(function(t) { - return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]); - }); + }).filter(Boolean); }; // remove inflight requests that no longer cover the view.. - tile.removeInflightRequests = function(cache, tiles, callback, modifier) { + tiler.removeInflightRequests = function(cache, tiles, callback, modifier) { return _filter(cache.inflight, function(v, i) { var wanted = _find(tiles, function(tile) { return i === tile.id + modifier; }); if (!wanted) { @@ -132,48 +122,54 @@ export function utilTile() { }; - tile.scaleExtent = function(val) { + tiler.scaleExtent = function(val) { if (!arguments.length) return _scaleExtent; _scaleExtent = val; - return tile; + return tiler; }; - tile.size = function(val) { + tiler.size = function(val) { if (!arguments.length) return _size; _size = val; - return tile; + return tiler; }; - tile.scale = function(val) { + tiler.scale = function(val) { if (!arguments.length) return _scale; _scale = val; - return tile; + return tiler; }; - tile.translate = function(val) { + tiler.translate = function(val) { if (!arguments.length) return _translate; _translate = val; - return tile; + return tiler; }; - tile.zoomDelta = function(val) { + tiler.zoomDelta = function(val) { if (!arguments.length) return _zoomDelta; _zoomDelta = +val; - return tile; + return tiler; }; - // number to extend the rows/columns beyond those covering the viewport - tile.margin = function(val) { + tiler.margin = function(val) { if (!arguments.length) return _margin; _margin = +val; - return tile; + return tiler; }; - return tile; + tiler.skipNullIsland = function(val) { + if (!arguments.length) return _skipNullIsland; + _skipNullIsland = val; + return tiler; + }; + + + return tiler; } From d1fe81b9053d47e85dc0dfd687679f6e59afe95d Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sat, 21 Jul 2018 10:07:56 -0400 Subject: [PATCH 2/4] rename utilTile -> utilTiler --- modules/renderer/tile_layer.js | 4 ++-- modules/services/mapillary.js | 4 ++-- modules/services/openstreetcam.js | 4 ++-- modules/services/osm.js | 4 ++-- modules/services/streetside.js | 4 ++-- modules/util/index.js | 2 +- modules/util/tile.js | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/renderer/tile_layer.js b/modules/renderer/tile_layer.js index d5c59e9b9..36668553c 100644 --- a/modules/renderer/tile_layer.js +++ b/modules/renderer/tile_layer.js @@ -2,13 +2,13 @@ import { select as d3_select } from 'd3-selection'; import { t } from '../util/locale'; import { geoScaleToZoom, geoVecLength } from '../geo'; -import { utilPrefixCSSProperty, utilTile } from '../util'; +import { utilPrefixCSSProperty, utilTiler } from '../util'; export function rendererTileLayer(context) { var tileSize = 256; var transformProp = utilPrefixCSSProperty('Transform'); - var geotile = utilTile(); + var geotile = utilTiler(); var _projection; var _cache = {}; diff --git a/modules/services/mapillary.js b/modules/services/mapillary.js index 4d19f43af..431b8f1e8 100644 --- a/modules/services/mapillary.js +++ b/modules/services/mapillary.js @@ -21,9 +21,9 @@ import rbush from 'rbush'; import { geoExtent } from '../geo'; import { svgDefs } from '../svg'; import { utilDetect } from '../util/detect'; -import { utilQsString, utilRebind, utilTile } from '../util'; +import { utilQsString, utilRebind, utilTiler } from '../util'; -var geoTile = utilTile().skipNullIsland(true); +var geoTile = utilTiler().skipNullIsland(true); var apibase = 'https://a.mapillary.com/v3/'; var viewercss = 'mapillary-js/mapillary.min.css'; diff --git a/modules/services/openstreetcam.js b/modules/services/openstreetcam.js index 89b391022..dd9693176 100644 --- a/modules/services/openstreetcam.js +++ b/modules/services/openstreetcam.js @@ -24,7 +24,7 @@ import rbush from 'rbush'; import { geoExtent } from '../geo'; -import { utilTile } from '../util'; +import { utilTiler } from '../util'; import { utilDetect } from '../util/detect'; import { @@ -33,7 +33,7 @@ import { utilSetTransform } from '../util'; -var geoTile = utilTile().skipNullIsland(true); +var geoTile = utilTiler().skipNullIsland(true); var apibase = 'https://openstreetcam.org'; var maxResults = 1000; diff --git a/modules/services/osm.js b/modules/services/osm.js index d7686ce34..edf390a93 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -30,11 +30,11 @@ import { import { utilRebind, utilIdleWorker, - utilTile, + utilTiler, utilQsString } from '../util'; -var geoTile = utilTile(); +var geoTile = utilTiler(); var dispatch = d3_dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded', 'loadedNotes'); var urlroot = 'https://www.openstreetmap.org'; diff --git a/modules/services/streetside.js b/modules/services/streetside.js index 435d0c210..3f5c6f1a6 100644 --- a/modules/services/streetside.js +++ b/modules/services/streetside.js @@ -28,11 +28,11 @@ import { } from '../geo'; import { utilDetect } from '../util/detect'; -import { utilQsString, utilRebind, utilTile } from '../util'; +import { utilQsString, utilRebind, utilTiler } from '../util'; import Q from 'q'; -var geoTile = utilTile().skipNullIsland(true); +var geoTile = utilTiler().skipNullIsland(true); var bubbleApi = 'https://dev.virtualearth.net/mapcontrol/HumanScaleServices/GetBubbles.ashx?'; var streetsideImagesApi = 'https://t.ssl.ak.tiles.virtualearth.net/tiles/'; diff --git a/modules/util/index.js b/modules/util/index.js index 9673bfef5..bc5c7c9a6 100644 --- a/modules/util/index.js +++ b/modules/util/index.js @@ -23,6 +23,6 @@ export { utilSessionMutex } from './session_mutex'; export { utilStringQs } from './util'; export { utilSuggestNames } from './suggest_names'; export { utilTagText } from './util'; -export { utilTile } from './tile'; +export { utilTiler } from './tile'; export { utilTriggerEvent } from './trigger_event'; export { utilWrap } from './util'; diff --git a/modules/util/tile.js b/modules/util/tile.js index 2ed2474e2..180f1197d 100644 --- a/modules/util/tile.js +++ b/modules/util/tile.js @@ -4,7 +4,7 @@ import { range as d3_range } from 'd3-array'; import { geoExtent } from '../geo'; -export function utilTile() { +export function utilTiler() { var _size = [960, 500]; var _scale = 256; var _scaleExtent = [0, 20]; From ff64455370b9a49679145d0b3e83c014e5d940c0 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sat, 21 Jul 2018 10:12:11 -0400 Subject: [PATCH 3/4] rename the file too --- modules/util/index.js | 2 +- modules/util/{tile.js => tiler.js} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename modules/util/{tile.js => tiler.js} (100%) diff --git a/modules/util/index.js b/modules/util/index.js index bc5c7c9a6..4d4c53269 100644 --- a/modules/util/index.js +++ b/modules/util/index.js @@ -23,6 +23,6 @@ export { utilSessionMutex } from './session_mutex'; export { utilStringQs } from './util'; export { utilSuggestNames } from './suggest_names'; export { utilTagText } from './util'; -export { utilTiler } from './tile'; +export { utilTiler } from './tiler'; export { utilTriggerEvent } from './trigger_event'; export { utilWrap } from './util'; diff --git a/modules/util/tile.js b/modules/util/tiler.js similarity index 100% rename from modules/util/tile.js rename to modules/util/tiler.js From 02713e48fbeaa95fe3b82e4eae6c5c994f0cc262 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sat, 21 Jul 2018 11:11:39 -0400 Subject: [PATCH 4/4] Move cache management out of tiler, it's responsibilty of service Also remove some unused code and eslint warnings --- modules/services/mapillary.js | 40 +++++++++---------------------- modules/services/openstreetcam.js | 30 ++++++++++------------- modules/services/osm.js | 16 +++++++++---- modules/services/streetside.js | 26 ++++++++++---------- modules/util/tiler.js | 21 ++++------------ 5 files changed, 53 insertions(+), 80 deletions(-) diff --git a/modules/services/mapillary.js b/modules/services/mapillary.js index 431b8f1e8..3338211ab 100644 --- a/modules/services/mapillary.js +++ b/modules/services/mapillary.js @@ -1,5 +1,4 @@ /* global Mapillary:false */ -import _filter from 'lodash-es/filter'; import _find from 'lodash-es/find'; import _flatten from 'lodash-es/flatten'; import _forEach from 'lodash-es/forEach'; @@ -44,18 +43,6 @@ function abortRequest(i) { } -function nearNullIsland(x, y, z) { - if (z >= 7) { - var center = Math.pow(2, z - 1); - var width = Math.pow(2, z - 6); - var min = center - (width / 2); - var max = center + (width / 2) - 1; - return x >= min && x <= max && y >= min && y <= max; - } - return false; -} - - function maxPageAtZoom(z) { if (z < 15) return 2; if (z === 15) return 5; @@ -66,28 +53,23 @@ function maxPageAtZoom(z) { } -function localeTimestamp(s) { - if (!s) return null; - var detected = utilDetect(); - var options = { - day: 'numeric', month: 'short', year: 'numeric', - hour: 'numeric', minute: 'numeric', second: 'numeric', - timeZone: 'UTC' - }; - var d = new Date(s); - if (isNaN(d.getTime())) return null; - return d.toLocaleString(detected.locale, options); -} - - function loadTiles(which, url, projection) { var s = projection.scale() * 2 * Math.PI; var currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0)); var dimension = projection.clipExtent()[1]; - var tiles = geoTile.getTiles(projection, dimension, tileZoom, 0); + var tiles = geoTile.getTiles(projection, dimension, tileZoom); - geoTile.removeInflightRequests(which, tiles, abortRequest, ',0'); + // abort inflight requests that are no longer needed + var cache = _mlyCache[which]; + _forEach(cache.inflight, function(v, k) { + var wanted = _find(tiles, function(tile) { return k.indexOf(tile.id + ',') === 0; }); + + if (!wanted) { + abortRequest(v); + delete cache.inflight[k]; + } + }); tiles.forEach(function(tile) { loadNextTilePage(which, currZoom, url, tile); diff --git a/modules/services/openstreetcam.js b/modules/services/openstreetcam.js index dd9693176..f7577b51d 100644 --- a/modules/services/openstreetcam.js +++ b/modules/services/openstreetcam.js @@ -1,4 +1,3 @@ -import _filter from 'lodash-es/filter'; import _find from 'lodash-es/find'; import _flatten from 'lodash-es/flatten'; import _forEach from 'lodash-es/forEach'; @@ -53,18 +52,6 @@ function abortRequest(i) { } -function nearNullIsland(x, y, z) { - if (z >= 7) { - var center = Math.pow(2, z - 1), - width = Math.pow(2, z - 6), - min = center - (width / 2), - max = center + (width / 2) - 1; - return x >= min && x <= max && y >= min && y <= max; - } - return false; -} - - function maxPageAtZoom(z) { if (z < 15) return 2; if (z === 15) return 5; @@ -76,13 +63,22 @@ function maxPageAtZoom(z) { function loadTiles(which, url, projection) { - var s = projection.scale() * 2 * Math.PI, - currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0)); + var s = projection.scale() * 2 * Math.PI; + var currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0)); var dimension = projection.clipExtent()[1]; - var tiles = geoTile.getTiles(projection, dimension, tileZoom, 0); + var tiles = geoTile.getTiles(projection, dimension, tileZoom); - geoTile.removeInflightRequests(which, tiles, abortRequest, ',0'); + // abort inflight requests that are no longer needed + var cache = _oscCache[which]; + _forEach(cache.inflight, function(v, k) { + var wanted = _find(tiles, function(tile) { return k.indexOf(tile.id + ',') === 0; }); + + if (!wanted) { + abortRequest(v); + delete cache.inflight[k]; + } + }); tiles.forEach(function(tile) { loadNextTilePage(which, currZoom, url, tile); diff --git a/modules/services/osm.js b/modules/services/osm.js index edf390a93..2aecabb6e 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -2,7 +2,6 @@ import _chunk from 'lodash-es/chunk'; import _cloneDeep from 'lodash-es/cloneDeep'; import _extend from 'lodash-es/extend'; import _forEach from 'lodash-es/forEach'; -import _filter from 'lodash-es/filter'; import _find from 'lodash-es/find'; import _groupBy from 'lodash-es/groupBy'; import _isEmpty from 'lodash-es/isEmpty'; @@ -778,12 +777,19 @@ export default { tilezoom = _tileZoom; } - // get tiles - var tiles = geoTile.getTiles(projection, dimensions, tilezoom, 0); + // determine the needed tiles to cover the view + var tiles = geoTile.getTiles(projection, dimensions, tilezoom); - // remove inflight requests that no longer cover the view.. + // abort inflight requests that are no longer needed var hadRequests = !_isEmpty(cache.inflight); - geoTile.removeInflightRequests(cache, tiles, abortRequest); + _forEach(cache.inflight, function(v, k) { + var wanted = _find(tiles, function(tile) { return k === tile.id; }); + if (!wanted) { + abortRequest(v); + delete cache.inflight[k]; + } + }); + if (hadRequests && !loadingNotes && _isEmpty(cache.inflight)) { dispatch.call('loaded'); // stop the spinner } diff --git a/modules/services/streetside.js b/modules/services/streetside.js index 3f5c6f1a6..b7b592cba 100644 --- a/modules/services/streetside.js +++ b/modules/services/streetside.js @@ -1,4 +1,5 @@ import _extend from 'lodash-es/extend'; +import _find from 'lodash-es/find'; import _flatten from 'lodash-es/flatten'; import _forEach from 'lodash-es/forEach'; import _map from 'lodash-es/map'; @@ -53,6 +54,7 @@ var _pannellumViewer; var _sceneOptions; var _dataUrlArray = []; + /** * abortRequest(). */ @@ -60,19 +62,6 @@ function abortRequest(i) { i.abort(); } -/** - * nearNullIsland(). - */ -function nearNullIsland(x, y, z) { - if (z >= 7) { - var center = Math.pow(2, z - 1); - var width = Math.pow(2, z - 6); - var min = center - (width / 2); - var max = center + (width / 2) - 1; - return x >= min && x <= max && y >= min && y <= max; - } - return false; -} /** * localeTimeStamp(). @@ -99,6 +88,17 @@ function loadTiles(which, url, projection, margin) { .margin(margin) .getTiles(projection, dimension, tileZoom); + // abort inflight requests that are no longer needed + var cache = _ssCache[which]; + _forEach(cache.inflight, function(v, k) { + var wanted = _find(tiles, function(tile) { return k.indexOf(tile.id + ',') === 0; }); + + if (!wanted) { + abortRequest(v); + delete cache.inflight[k]; + } + }); + tiles.forEach(function (tile) { loadNextTilePage(which, currZoom, url, tile); }); diff --git a/modules/util/tiler.js b/modules/util/tiler.js index 180f1197d..27bb17759 100644 --- a/modules/util/tiler.js +++ b/modules/util/tiler.js @@ -1,5 +1,3 @@ -import _filter from 'lodash-es/filter'; -import _find from 'lodash-es/find'; import { range as d3_range } from 'd3-array'; import { geoExtent } from '../geo'; @@ -19,7 +17,10 @@ export function utilTiler() { } - function nearNullIsland(x, y, z) { + function nearNullIsland(tile) { + var x = tile[0]; + var y = tile[1]; + var z = tile[2]; if (z >= 7) { var center = Math.pow(2, z - 1); var width = Math.pow(2, z - 6); @@ -93,7 +94,7 @@ export function utilTiler() { return tiler() .map(function(tile) { - if (_skipNullIsland && nearNullIsland(tile[0], tile[1], tile[2])) { + if (_skipNullIsland && nearNullIsland(tile)) { return false; } var x = tile[0] * ts - origin[0]; @@ -110,18 +111,6 @@ export function utilTiler() { }; - // remove inflight requests that no longer cover the view.. - tiler.removeInflightRequests = function(cache, tiles, callback, modifier) { - return _filter(cache.inflight, function(v, i) { - var wanted = _find(tiles, function(tile) { return i === tile.id + modifier; }); - if (!wanted) { - delete cache.inflight[i]; - } - return !wanted; - }).map(callback); // abort request - }; - - tiler.scaleExtent = function(val) { if (!arguments.length) return _scaleExtent; _scaleExtent = val;