-
-
Notifications
You must be signed in to change notification settings - Fork 6k
TileLayer maxNativeZoom option for scaling tiles on unsupported zoom levels #1802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@tmcw @jfirebaugh thoughts on the API? |
|
I've been calling this "overscaling" -- if that's a legitimate term, maybe use it in one of the option names? |
|
@jfirebaugh The trick is that we want to retain the semantics of maxZoom — it defines on what max zoom level you will still see the tile layer, we just need one more option to define after what level tiles start to be scaled. What would be a better name for it? |
|
"overscaling", well I always have been fascinating by techniques that magically pull more information out an image than you would think. For example, sub-pixel imaging, pan-sharpening, and now we have compressive sensing with their 1-pixel cameras! |
|
Any idea how I would merge this into the FunctionalTileLayer leaflet plug-in https://github.com/ismyrnow/Leaflet.functionaltilelayer by Ishmael Schmorrow? His initialize uses L.Util.setOptions() so I am hoping that will work: initialize: function (tileFunction, options) {
this._tileFunction = tileFunction;
L.Util.setOptions(this, options);
},
L.tileLayer.functional = function (tileFunction, options) {
return new L.TileLayer.Functional(tileFunction, options);
}; |
|
His ( @ismyrnow ) code is short, let me post it instead of you having to find it: L.TileLayer.Functional = L.TileLayer.extend({
_tileFunction: null,
initialize: function (tileFunction, options) {
this._tileFunction = tileFunction;
L.Util.setOptions(this, options);
},
getTileUrl: function (tilePoint) {
// Note: bbox code untested; pulled from TileLayer.WMS
var map = this._map,
crs = map.options.crs,
tileSize = this.options.tileSize,
zoom = this._map.getZoom(),
nwPoint = tilePoint.multiplyBy(tileSize),
sePoint = nwPoint.add(new L.Point(tileSize, tileSize)),
nw = crs.project(map.unproject(nwPoint, zoom)),
se = crs.project(map.unproject(sePoint, zoom)),
bbox = [nw.x, se.y, se.x, nw.y].join(','),
view = {
bbox: bbox,
width: tileSize,
height: tileSize,
zoom: zoom,
tile: {
row: tilePoint.y,
column: tilePoint.x
},
subdomain: this._getSubdomain(tilePoint)
};
return this._tileFunction(view);
},
_loadTile: function (tile, tilePoint) {
var tileUrl = this.getTileUrl(tilePoint);
tile._layer = this;
tile.onload = this._tileOnLoad;
tile.onerror = this._tileOnError;
if (typeof tileUrl === "string") {
tile.src = tileUrl;
} else if (tileUrl) {
// assume jQuery.Deferred
tileUrl.done(function (tileUrl) {
tile.src = tileUrl;
});
}
}
});
L.tileLayer.functional = function (tileFunction, options) {
return new L.TileLayer.Functional(tileFunction, options);
}; |
|
You should (theoretically) be able to add in those new settings when you initialize the functional tile layer. Since the plugin extends the existing L.TileLayer, it should apply any native settings to the underlying layer. I don't know how L.TileLayer does the scaling under the hood, but it may work, since the only function I'm overriding is getTileUrl(). |
|
It should work, as this pull doesn't affect |
|
OK, merging the pull. |
TileLayer maxNativeZoom option for scaling tiles on unsupported zoom levels
|
Hey mourner, I have found an issue when you zoom to the Maxnative zoom level and then add another maxnativezoom enabled layer it will not load the maxzoom level tiles and scale them up to the current level zoom. |
|
I was very pleased with this fix, and it worked fine for tiles that I have in the local file system. But when I tried the same code for my variant of @ismyrnow FunctionalTiles (where the tiles are stored in an IDB), then it is ignoring the scaling beyond the naturalZoom. I.e. it just shows gray tiles. I am not seeing errors so I am not sure what is going on. In case I am doing something obviously stupid, I am attaching snaphots of the state of the TileLayer just after it is created (Chrome). First for the simple case (local files) and then for the Functional Tile extension. It is going to take me few days to create a CodePen to show the issue. Here is what it looks like as a functional tile layer, realize that the tiles are all fetched with the _tileFunction(), so it is the options that are things to look at. |
- See issue #3 - and issue Leaflet/Leaflet#1802
|
Sorry if off-topic, but seems related: Is there a 'tweening' option for tile services that do not provide tiles at each zoom level? (Perhaps using the scaling that is visible when animating the zoom). (For example, on offline mobile devices with local tile servers where space is at a premium and may only store tiles at every other zoom level). See related SO question: http://stackoverflow.com/questions/28904160/how-to-use-chunky-coarse-grained-zoom-levels-with-leaflet-maps |


Implements #1798. Suppose you have a tile layer with maxZoom 18, but you need it up to 20 and OK with scaling of tiles. Then you would do this:
Tested and seems to work well for both simple tile layers and WMS layers.