Skip to content

Commit

Permalink
use zoom level 22 as default maxZoom for World Imagery
Browse files Browse the repository at this point in the history
instead of artificially capping the zoom for World Imagery at 19,
interrogate the esri tilemap when zooming begins to see whether all tiles
in an 8x8 grid at the next zoom level are present.

if they aren't, use leaflet's new built in option to downsample the existing tiles.
  • Loading branch information
jgravois committed Oct 6, 2017
1 parent d316a20 commit 5fdefc0
Showing 1 changed file with 52 additions and 1 deletion.
53 changes: 52 additions & 1 deletion src/Layers/BasemapLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ export var BasemapLayer = TileLayer.extend({
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
options: {
minZoom: 1,
maxZoom: 19,
maxZoom: 22,
maxNativeZoom: 22,
downsampled: false,
subdomains: ['server', 'services'],
attribution: 'DigitalGlobe, GeoEye, i-cubed, USDA, USGS, AEX, Getmapping, Aerogrid, IGN, IGP, swisstopo, and the GIS User Community'
}
Expand Down Expand Up @@ -215,6 +217,11 @@ export var BasemapLayer = TileLayer.extend({

map.on('moveend', _updateMapAttribution);

// Esri World Imagery is cached all the way to zoom 22 in select regions
if (this._url.indexOf('World_Imagery') !== -1) {
map.on('zoomanim', _fetchTilemap, this);
}

TileLayer.prototype.onAdd.call(this, map);
},

Expand All @@ -239,6 +246,50 @@ export var BasemapLayer = TileLayer.extend({
}
});

function _fetchTilemap (evt) {
var map = evt.target;
if (!map) { return; }

var oldZoom = map.getZoom();
var newZoom = evt.zoom;
var newCenter = map.wrapLatLng(evt.center);

if (newZoom > oldZoom && newZoom > 13 && !this.options.downsampled) {
// convert wrapped lat/long into tile coordinates and use them to generate the tilemap url
var tilePoint = map.project(newCenter, newZoom).divideBy(256).floor();

// use new coords to determine the tilemap url
var tileUrl = Util.template(this._url, Util.extend({
s: this._getSubdomain(tilePoint),
x: tilePoint.x,
y: tilePoint.y,
z: newZoom
}, this.options));

// 8x8 grids are cached
var tilemapUrl = tileUrl.replace(/tile/, 'tilemap') + '/8/8';

// an array of booleans in the response indicate missing tiles
L.esri.request(tilemapUrl, {}, function (err, response) {
if (!err) {
for (var i = 0; i < response.data.length; i++) {
if (!response.data[i]) {
// if necessary, resample a lower zoom
this.options.maxNativeZoom = newZoom - 1;
this.options.downsampled = true;
break;
}
// if no tiles are missing, reset the original maxZoom
this.options.maxNativeZoom = 22;
}
}
}, this);
} else if (newZoom < 13) {
// if the user moves to a new region, time for a fresh test
this.options.downsampled = false;
}
}

export function basemapLayer (key, options) {
return new BasemapLayer(key, options);
}
Expand Down

0 comments on commit 5fdefc0

Please sign in to comment.