From d4b162266794982ebae2417a3b5f4d5bf219d7e4 Mon Sep 17 00:00:00 2001 From: Thomas Hervey Date: Sat, 14 Jul 2018 19:15:25 -0400 Subject: [PATCH 1/4] moved getTiles and filtering to utils --- dist/locales/en.json | 4 +- modules/lib/d3.geo.tile.js | 93 ----------------- modules/lib/index.js | 1 - modules/renderer/tile_layer.js | 5 +- modules/services/mapillary.js | 46 +-------- modules/services/openstreetcam.js | 65 +++--------- modules/services/osm.js | 30 +----- modules/services/streetside.js | 50 +-------- modules/util/index.js | 1 + modules/util/tile.js | 165 ++++++++++++++++++++++++++++++ package.json | 2 +- 11 files changed, 199 insertions(+), 263 deletions(-) delete mode 100644 modules/lib/d3.geo.tile.js create mode 100644 modules/util/tile.js diff --git a/dist/locales/en.json b/dist/locales/en.json index 8e9018bfb..3931424de 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -6681,7 +6681,7 @@ "attribution": { "text": "Terms & Feedback" }, - "description": "DigitalGlobe-Premium is a mosaic composed of DigitalGlobe basemap with select regions filled with +Vivid or custom area of interest imagery, 50cm resolution or better, and refreshed more frequently with ongoing updates.", + "description": "Premium DigitalGlobe satellite imagery.", "name": "DigitalGlobe Premium Imagery" }, "DigitalGlobe-Premium-vintage": { @@ -6695,7 +6695,7 @@ "attribution": { "text": "Terms & Feedback" }, - "description": "DigitalGlobe-Standard is a curated set of imagery covering 86% of the earth’s landmass, with 30-60cm resolution where available, backfilled by Landsat. Average age is 2.31 years, with some areas updated 2x per year.", + "description": "Standard DigitalGlobe satellite imagery.", "name": "DigitalGlobe Standard Imagery" }, "DigitalGlobe-Standard-vintage": { diff --git a/modules/lib/d3.geo.tile.js b/modules/lib/d3.geo.tile.js deleted file mode 100644 index 3b0f718ef..000000000 --- a/modules/lib/d3.geo.tile.js +++ /dev/null @@ -1,93 +0,0 @@ -import { range as d3_range } from 'd3-array'; - - -export function d3geoTile() { - 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(val) { - return Math.min(_scaleExtent[1], Math.max(_scaleExtent[0], val)); - } - - 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 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) - ); - - var tiles = []; - for (var i = 0; i < rows.length; i++) { - var y = rows[i]; - for (var j = 0; j < cols.length; j++) { - var x = cols[j]; - - if (i >= _margin && i <= rows.length - _margin && - j >= _margin && j <= cols.length - _margin) { - tiles.unshift([x, y, z0]); // tiles in view at beginning - } else { - tiles.push([x, y, z0]); // tiles in margin at the end - } - } - } - - 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; - }; - - return tile; -} diff --git a/modules/lib/index.js b/modules/lib/index.js index b6ddad54a..bee98416c 100644 --- a/modules/lib/index.js +++ b/modules/lib/index.js @@ -1,3 +1,2 @@ export { d3combobox } from './d3.combobox'; -export { d3geoTile } from './d3.geo.tile'; export { d3keybinding } from './d3.keybinding'; diff --git a/modules/renderer/tile_layer.js b/modules/renderer/tile_layer.js index 475147e43..d5c59e9b9 100644 --- a/modules/renderer/tile_layer.js +++ b/modules/renderer/tile_layer.js @@ -1,15 +1,14 @@ import { select as d3_select } from 'd3-selection'; import { t } from '../util/locale'; -import { d3geoTile as d3_geoTile } from '../lib/d3.geo.tile'; import { geoScaleToZoom, geoVecLength } from '../geo'; -import { utilPrefixCSSProperty } from '../util'; +import { utilPrefixCSSProperty, utilTile } from '../util'; export function rendererTileLayer(context) { var tileSize = 256; var transformProp = utilPrefixCSSProperty('Transform'); - var geotile = d3_geoTile(); + var geotile = utilTile(); var _projection; var _cache = {}; diff --git a/modules/services/mapillary.js b/modules/services/mapillary.js index baed207b8..84395e20c 100644 --- a/modules/services/mapillary.js +++ b/modules/services/mapillary.js @@ -18,11 +18,12 @@ import { import rbush from 'rbush'; -import { d3geoTile as d3_geoTile } from '../lib/d3.geo.tile'; import { geoExtent } from '../geo'; import { svgDefs } from '../svg'; import { utilDetect } from '../util/detect'; -import { utilQsString, utilRebind } from '../util'; +import { utilQsString, utilRebind, utilTile } from '../util'; + +var geoTile = utilTile(); var apibase = 'https://a.mapillary.com/v3/'; var viewercss = 'mapillary-js/mapillary.min.css'; @@ -79,49 +80,12 @@ function localeTimestamp(s) { } -function getTiles(projection) { - 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); - var origin = [ - s / 2 - projection.translate()[0], - s / 2 - projection.translate()[1] - ]; - - return d3_geoTile() - .scaleExtent([tileZoom, tileZoom]) - .scale(s) - .size(projection.clipExtent()[1]) - .translate(projection.translate())() - .map(function(tile) { - var x = tile[0] * ts - origin[0]; - var y = tile[1] * ts - origin[1]; - - return { - id: tile.toString(), - xyz: tile, - extent: geoExtent( - projection.invert([x, y + ts]), - projection.invert([x + ts, y]) - ) - }; - }); -} - - 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 tiles = getTiles(projection).filter(function(t) { - return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]); - }); - - _filter(which.inflight, function(v, k) { - var wanted = _find(tiles, function(tile) { return k === (tile.id + ',0'); }); - if (!wanted) delete which.inflight[k]; - return !wanted; - }).map(abortRequest); + var tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection)); + geoTile.removeInflightRequests(which, tiles, abortRequest, ',0'); tiles.forEach(function(tile) { loadNextTilePage(which, currZoom, url, tile); diff --git a/modules/services/openstreetcam.js b/modules/services/openstreetcam.js index 14ded2d6b..848ea1fce 100644 --- a/modules/services/openstreetcam.js +++ b/modules/services/openstreetcam.js @@ -22,9 +22,9 @@ import { import rbush from 'rbush'; -import { d3geoTile as d3_geoTile } from '../lib/d3.geo.tile'; import { geoExtent } from '../geo'; +import { utilTile } from '../util'; import { utilDetect } from '../util/detect'; import { @@ -33,18 +33,19 @@ import { utilSetTransform } from '../util'; +var geoTile = utilTile(); -var apibase = 'https://openstreetcam.org', - maxResults = 1000, - tileZoom = 14, - dispatch = d3_dispatch('loadedImages'), - imgZoom = d3_zoom() - .extent([[0, 0], [320, 240]]) - .translateExtent([[0, 0], [320, 240]]) - .scaleExtent([1, 15]) - .on('zoom', zoomPan), - _oscCache, - _oscSelectedImage; +var apibase = 'https://openstreetcam.org'; +var maxResults = 1000; +var tileZoom = 14; +var dispatch = d3_dispatch('loadedImages'); +var imgZoom = d3_zoom() + .extent([[0, 0], [320, 240]]) + .translateExtent([[0, 0], [320, 240]]) + .scaleExtent([1, 15]) + .on('zoom', zoomPan); +var _oscCache; +var _oscSelectedImage; function abortRequest(i) { @@ -74,48 +75,12 @@ function maxPageAtZoom(z) { } -function getTiles(projection) { - var s = projection.scale() * 2 * Math.PI, - z = Math.max(Math.log(s) / Math.log(2) - 8, 0), - ts = 256 * Math.pow(2, z - tileZoom), - origin = [ - s / 2 - projection.translate()[0], - s / 2 - projection.translate()[1]]; - - return d3_geoTile() - .scaleExtent([tileZoom, tileZoom]) - .scale(s) - .size(projection.clipExtent()[1]) - .translate(projection.translate())() - .map(function(tile) { - var x = tile[0] * ts - origin[0], - y = tile[1] * ts - origin[1]; - - return { - id: tile.toString(), - xyz: tile, - extent: geoExtent( - projection.invert([x, y + ts]), - projection.invert([x + ts, y]) - ) - }; - }); -} - - 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 tiles = getTiles(projection).filter(function(t) { - return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]); - }); - - _filter(which.inflight, function(v, k) { - var wanted = _find(tiles, function(tile) { return k === (tile.id + ',0'); }); - if (!wanted) delete which.inflight[k]; - return !wanted; - }).map(abortRequest); + var tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection)); + geoTile.removeInflightRequests(which, tiles, abortRequest, ',0'); tiles.forEach(function(tile) { loadNextTilePage(which, currZoom, url, tile); diff --git a/modules/services/osm.js b/modules/services/osm.js index 9ead1f5b0..8f73006ee 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -13,7 +13,6 @@ import { xml as d3_xml } from 'd3-request'; import osmAuth from 'osm-auth'; import { JXON } from '../util/jxon'; -import { d3geoTile as d3_geoTile } from '../lib/d3.geo.tile'; import { geoExtent } from '../geo'; import { osmEntity, @@ -22,8 +21,9 @@ import { osmWay } from '../osm'; -import { utilRebind, utilIdleWorker } from '../util'; +import { utilRebind, utilIdleWorker, utilTile } from '../util'; +var geoTile = utilTile(); var dispatch = d3_dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded'); var urlroot = 'https://www.openstreetmap.org'; @@ -581,30 +581,8 @@ export default { s / 2 - projection.translate()[1] ]; - var tiles = d3_geoTile() - .scaleExtent([_tileZoom, _tileZoom]) - .scale(s) - .size(dimensions) - .translate(projection.translate())() - .map(function(tile) { - var x = tile[0] * ts - origin[0]; - var y = tile[1] * ts - origin[1]; - - return { - id: tile.toString(), - extent: geoExtent( - projection.invert([x, y + ts]), - projection.invert([x + ts, y])) - }; - }); - - _filter(_tiles.inflight, function(v, i) { - var wanted = _find(tiles, function(tile) { - return i === tile.id; - }); - if (!wanted) delete _tiles.inflight[i]; - return !wanted; - }).map(abortRequest); + var tiles = geoTile.filterNullIsland(geoTile.getTiles(_tileZoom, projection)); + geoTile.removeInflightRequests(_tiles, tiles, abortRequest); tiles.forEach(function(tile) { var id = tile.id; diff --git a/modules/services/streetside.js b/modules/services/streetside.js index f13470b6c..944221543 100644 --- a/modules/services/streetside.js +++ b/modules/services/streetside.js @@ -17,7 +17,6 @@ import { import rbush from 'rbush'; import { t } from '../util/locale'; import { jsonpRequest } from '../util/jsonp_request'; -import { d3geoTile as d3_geoTile } from '../lib/d3.geo.tile'; import { geoExtent, @@ -29,10 +28,12 @@ import { } from '../geo'; import { utilDetect } from '../util/detect'; -import { utilQsString, utilRebind } from '../util'; +import { utilQsString, utilRebind, utilTile } from '../util'; import Q from 'q'; +var geoTile = utilTile(); + var bubbleApi = 'https://dev.virtualearth.net/mapcontrol/HumanScaleServices/GetBubbles.ashx?'; var streetsideImagesApi = 'https://t.ssl.ak.tiles.virtualearth.net/tiles/'; var bubbleAppKey = 'AuftgJsO0Xs8Ts4M1xZUQJQXJNsvmh3IV8DkNieCiy3tCwCUMq76-WpkrBtNAuEm'; @@ -85,46 +86,6 @@ function localeTimestamp(s) { return d.toLocaleString(detected.locale, options); } -/** - * getTiles() returns array of d3 geo tiles. - * 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. - */ -function getTiles(projection, 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). - 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); - var origin = [ - s / 2 - projection.translate()[0], - s / 2 - projection.translate()[1] - ]; - - var tiler = d3_geoTile() - .scaleExtent([tileZoom, tileZoom]) - .scale(s) - .size(projection.clipExtent()[1]) - .translate(projection.translate()) - .margin(margin || 0); // 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 { - id: tile.toString(), - xyz: tile, - extent: geoExtent( - projection.invert([x, y + ts]), - projection.invert([x + ts, y]) - ) - }; - }); -} /** * loadTiles() wraps the process of generating tiles and then fetching image points for each tile. @@ -133,10 +94,7 @@ function loadTiles(which, url, projection, margin) { var s = projection.scale() * 2 * Math.PI; var currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0)); - // breakup the map view into tiles - var tiles = getTiles(projection, margin).filter(function (t) { - return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]); - }); + var tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection, margin)); tiles.forEach(function (tile) { loadNextTilePage(which, currZoom, url, tile); diff --git a/modules/util/index.js b/modules/util/index.js index f64856de8..9673bfef5 100644 --- a/modules/util/index.js +++ b/modules/util/index.js @@ -23,5 +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 { utilTriggerEvent } from './trigger_event'; export { utilWrap } from './util'; diff --git a/modules/util/tile.js b/modules/util/tile.js new file mode 100644 index 000000000..78d9a6423 --- /dev/null +++ b/modules/util/tile.js @@ -0,0 +1,165 @@ +import _filter from 'lodash-es/filter'; +import _find from 'lodash-es/find'; +import { range as d3_range } from 'd3-array'; +import { geoExtent } from '../geo'; + + +export function utilTile() { + 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(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); + 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 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 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) + ); + + var tiles = []; + for (var i = 0; i < rows.length; i++) { + var y = rows[i]; + for (var j = 0; j < cols.length; j++) { + var x = cols[j]; + + if (i >= _margin && i <= rows.length - _margin && + j >= _margin && j <= cols.length - _margin) { + tiles.unshift([x, y, z0]); // tiles in view at beginning + } else { + tiles.push([x, y, z0]); // tiles in margin at the end + } + } + } + + tiles.translate = origin; + tiles.scale = k; + + return tiles; + } + + /** + * getTiles() returns array of d3 geo tiles. + * 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(tileZoom, projection, 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). + 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); + var origin = [ + s / 2 - projection.translate()[0], + s / 2 - projection.translate()[1] + ]; + + var tiler = this + .scaleExtent([tileZoom, tileZoom]) + .scale(s) + .size(projection.clipExtent()[1]) + .translate(projection.translate()) + .margin(margin || 0); // 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 { + id: tile.toString(), + xyz: tile, + extent: geoExtent( + projection.invert([x, y + ts]), + projection.invert([x + ts, y]) + ) + }; + }); + }; + + tile.filterNullIsland = function(tiles) { + return tiles.filter(function(t) { + return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]); + }); + }; + + // remove inflight requests that no longer cover the view.. + tile.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 + }; + + 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; + }; + + return tile; +} diff --git a/package.json b/package.json index 3f2f448fc..a920390d4 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "json-stringify-pretty-compact": "^1.1.0", "jsonschema": "^1.1.0", "mapillary-js": "2.12.1", - "mapillary_sprite_source": "^1.4.0", + "mapillary_sprite_source": "^1.5.0", "minimist": "^1.2.0", "mocha": "^5.0.0", "mocha-phantomjs-core": "^2.1.0", From 60f66b73e983e184703aab56885f3c82fc5a3ae3 Mon Sep 17 00:00:00 2001 From: Thomas Hervey Date: Wed, 18 Jul 2018 15:16:52 -0400 Subject: [PATCH 2/4] fixed missing declarations. TODO: fix tests --- dist/locales/en.json | 4 ++-- modules/services/osm.js | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dist/locales/en.json b/dist/locales/en.json index f243cb992..e4b2ccb4d 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -6706,7 +6706,7 @@ "attribution": { "text": "Terms & Feedback" }, - "description": "Premium DigitalGlobe satellite imagery.", + "description": "DigitalGlobe-Premium is a mosaic composed of DigitalGlobe basemap with select regions filled with +Vivid or custom area of interest imagery, 50cm resolution or better, and refreshed more frequently with ongoing updates.", "name": "DigitalGlobe Premium Imagery" }, "DigitalGlobe-Premium-vintage": { @@ -6720,7 +6720,7 @@ "attribution": { "text": "Terms & Feedback" }, - "description": "Standard DigitalGlobe satellite imagery.", + "description": "DigitalGlobe-Standard is a curated set of imagery covering 86% of the earth’s landmass, with 30-60cm resolution where available, backfilled by Landsat. Average age is 2.31 years, with some areas updated 2x per year.", "name": "DigitalGlobe Standard Imagery" }, "DigitalGlobe-Standard-vintage": { diff --git a/modules/services/osm.js b/modules/services/osm.js index 128fe88d9..71f71562f 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -787,7 +787,10 @@ export default { ]; var tiles = geoTile.filterNullIsland(geoTile.getTiles(_tileZoom, projection)); - geoTile.removeInflightRequests(_tiles, tiles, abortRequest); + + // remove inflight requests that no longer cover the view.. + var hadRequests = !_isEmpty(cache.inflight); + geoTile.removeInflightRequests(cache, tiles, abortRequest); if (hadRequests && !loadingNotes && _isEmpty(cache.inflight)) { dispatch.call('loaded'); // stop the spinner From c563abaf7a46953199301ef9933a4491f4dc1562 Mon Sep 17 00:00:00 2001 From: Thomas Hervey Date: Wed, 18 Jul 2018 15:49:04 -0400 Subject: [PATCH 3/4] pass dimensions to tile --- modules/services/mapillary.js | 2 +- modules/services/openstreetcam.js | 2 +- modules/services/osm.js | 9 +-------- modules/services/streetside.js | 2 +- modules/util/tile.js | 4 ++-- 5 files changed, 6 insertions(+), 13 deletions(-) diff --git a/modules/services/mapillary.js b/modules/services/mapillary.js index 93870f94b..db387fd1f 100644 --- a/modules/services/mapillary.js +++ b/modules/services/mapillary.js @@ -84,7 +84,7 @@ 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 tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection)); + var tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection, projection.clipExtent()[1], 0)); geoTile.removeInflightRequests(which, tiles, abortRequest, ',0'); tiles.forEach(function(tile) { diff --git a/modules/services/openstreetcam.js b/modules/services/openstreetcam.js index 98b857670..be2953f16 100644 --- a/modules/services/openstreetcam.js +++ b/modules/services/openstreetcam.js @@ -79,7 +79,7 @@ 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 tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection)); + var tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection, projection.clipExtent()[1], 0)); geoTile.removeInflightRequests(which, tiles, abortRequest, ',0'); tiles.forEach(function(tile) { diff --git a/modules/services/osm.js b/modules/services/osm.js index 71f71562f..67a2e29f2 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -778,15 +778,8 @@ export default { tilezoom = _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); - var origin = [ - s / 2 - projection.translate()[0], - s / 2 - projection.translate()[1] - ]; - var tiles = geoTile.filterNullIsland(geoTile.getTiles(_tileZoom, projection)); + var tiles = geoTile.filterNullIsland(geoTile.getTiles(_tileZoom, projection, dimensions, 0)); // 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 591a21172..4252c05a8 100644 --- a/modules/services/streetside.js +++ b/modules/services/streetside.js @@ -94,7 +94,7 @@ function loadTiles(which, url, projection, margin) { var s = projection.scale() * 2 * Math.PI; var currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0)); - var tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection, margin)); + var tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection, projection.clipExtent()[1], margin)); tiles.forEach(function (tile) { loadNextTilePage(which, currZoom, url, tile); diff --git a/modules/util/tile.js b/modules/util/tile.js index 78d9a6423..546b4f10a 100644 --- a/modules/util/tile.js +++ b/modules/util/tile.js @@ -71,7 +71,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(tileZoom, projection, margin) { + tile.getTiles = function(tileZoom, projection, dimensions, 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. @@ -88,7 +88,7 @@ export function utilTile() { var tiler = this .scaleExtent([tileZoom, tileZoom]) .scale(s) - .size(projection.clipExtent()[1]) + .size(dimensions) .translate(projection.translate()) .margin(margin || 0); // request nearby tiles so we can connect sequences. From 386d375b7a80cc55c77001900c44c9b58dd51398 Mon Sep 17 00:00:00 2001 From: Thomas Hervey Date: Thu, 19 Jul 2018 10:51:39 -0400 Subject: [PATCH 4/4] fix excessive note tiling and network request --- modules/services/mapillary.js | 5 ++++- modules/services/openstreetcam.js | 5 ++++- modules/services/osm.js | 6 +++--- modules/services/streetside.js | 4 +++- modules/util/tile.js | 22 ++++++++++++++++++---- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/modules/services/mapillary.js b/modules/services/mapillary.js index db387fd1f..cdf04aa3b 100644 --- a/modules/services/mapillary.js +++ b/modules/services/mapillary.js @@ -84,7 +84,10 @@ 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 tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection, projection.clipExtent()[1], 0)); + var dimension = projection.clipExtent()[1]; + var tiles = geoTile.getTiles(projection, dimension, tileZoom, 0); + tiles = geoTile.filterNullIsland(tiles); + geoTile.removeInflightRequests(which, tiles, abortRequest, ',0'); tiles.forEach(function(tile) { diff --git a/modules/services/openstreetcam.js b/modules/services/openstreetcam.js index be2953f16..73483dddc 100644 --- a/modules/services/openstreetcam.js +++ b/modules/services/openstreetcam.js @@ -79,7 +79,10 @@ 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 tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection, projection.clipExtent()[1], 0)); + var dimension = projection.clipExtent()[1]; + var tiles = geoTile.getTiles(projection, dimension, tileZoom, 0); + tiles = geoTile.filterNullIsland(tiles); + geoTile.removeInflightRequests(which, tiles, abortRequest, ',0'); tiles.forEach(function(tile) { diff --git a/modules/services/osm.js b/modules/services/osm.js index 67a2e29f2..4263662e2 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -778,13 +778,13 @@ export default { tilezoom = _tileZoom; } - - var tiles = geoTile.filterNullIsland(geoTile.getTiles(_tileZoom, projection, dimensions, 0)); + // 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); geoTile.removeInflightRequests(cache, tiles, abortRequest); - 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 4252c05a8..52ee2c14f 100644 --- a/modules/services/streetside.js +++ b/modules/services/streetside.js @@ -94,7 +94,9 @@ function loadTiles(which, url, projection, margin) { var s = projection.scale() * 2 * Math.PI; var currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0)); - var tiles = geoTile.filterNullIsland(geoTile.getTiles(tileZoom, projection, projection.clipExtent()[1], margin)); + var dimension = projection.clipExtent()[1]; + var tiles = geoTile.getTiles(projection, dimension, tileZoom, margin); + tiles = geoTile.filterNullIsland(tiles); tiles.forEach(function (tile) { loadNextTilePage(which, currZoom, url, tile); diff --git a/modules/util/tile.js b/modules/util/tile.js index 546b4f10a..2179525f7 100644 --- a/modules/util/tile.js +++ b/modules/util/tile.js @@ -66,12 +66,14 @@ export function utilTile() { return tiles; } + /** * getTiles() returns array of d3 geo tiles. * 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(tileZoom, projection, dimensions, margin) { + 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. @@ -79,23 +81,24 @@ export function utilTile() { // 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). 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); + var ts = 256 * Math.pow(2, z - tilezoom); var origin = [ s / 2 - projection.translate()[0], s / 2 - projection.translate()[1] ]; var tiler = this - .scaleExtent([tileZoom, tileZoom]) + .scaleExtent([tilezoom, tilezoom]) .scale(s) .size(dimensions) .translate(projection.translate()) .margin(margin || 0); // request nearby tiles so we can connect sequences. - return tiler() + var tiles = tiler() .map(function(tile) { var x = tile[0] * ts - origin[0]; var y = tile[1] * ts - origin[1]; + return { id: tile.toString(), xyz: tile, @@ -105,14 +108,18 @@ export function utilTile() { ) }; }); + + return tiles; }; + tile.filterNullIsland = function(tiles) { return tiles.filter(function(t) { return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]); }); }; + // remove inflight requests that no longer cover the view.. tile.removeInflightRequests = function(cache, tiles, callback, modifier) { return _filter(cache.inflight, function(v, i) { @@ -124,36 +131,42 @@ export function utilTile() { }).map(callback); // abort request }; + 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; @@ -161,5 +174,6 @@ export function utilTile() { return tile; }; + return tile; }