TileLayer refactoring, add loading event, update changelog, closes #177
This commit is contained in:
parent
55c35828a8
commit
c50aaabd6d
@ -60,6 +60,7 @@ Icon API was improved to be more flexible, but one of the changes is backwards-i
|
||||
#### Other breaking API changes
|
||||
|
||||
* Improved `TileLayer` constructor to interpolate URL template values from options (removed third `urlParams` argument).
|
||||
* Changed `TileLayer` `scheme: 'tms'` option to `tms: true`.
|
||||
* Replaced ugly control position constants (e.g. `L.Control.Position.TOP_LEFT`) with light strings (`'topleft'`, `'bottomright'`, etc.)
|
||||
* Removed `Map` `locateAndSetView` method (use `locate` with `setView: true` option)
|
||||
* Changed popup `minWidth` and `maxWidth` options to be applied to content element, not the whole popup.
|
||||
@ -73,6 +74,7 @@ Icon API was improved to be more flexible, but one of the changes is backwards-i
|
||||
* Added `TileLayer` `redraw` method for re-requesting tiles (by [@greeninfo](https://github.com/greeninfo)). [#719](https://github.com/CloudMade/Leaflet/issues/719)
|
||||
* Added `TileLayer` `setUrl` method for dynamically changing the tile URL template.
|
||||
* Added `bringToFront` and `bringToBack` methods to `TileLayer` and vector layers. [#185](https://github.com/CloudMade/Leaflet/issues/185) [#505](https://github.com/CloudMade/Leaflet/issues/505)
|
||||
* Added `TileLayer` `loading` event that fires when its tiles start to load (thanks to [@lapinos03](https://github.com/lapinos03)). [#177](https://github.com/CloudMade/Leaflet/issues/177)
|
||||
* Added `TileLayer.WMS` `setParams` method for setting WMS parameters at runtime (by [@greeninfo](https://github.com/greeninfo)). [#719](https://github.com/CloudMade/Leaflet/issues/719)
|
||||
* Added `TileLayer.WMS` subdomain support (`{s}` in the url) (by [@greeninfo](https://github.com/greeninfo)). [#735](https://github.com/CloudMade/Leaflet/issues/735)
|
||||
* Added `originalEvent` property to `MouseEvent` (by [@k4](https://github.com/k4)). [#521](https://github.com/CloudMade/Leaflet/pull/521)
|
||||
@ -118,7 +120,7 @@ Icon API was improved to be more flexible, but one of the changes is backwards-i
|
||||
* Fixed a bug where `TileLayer` `setOpacity` wouldn't work when setting it back to 1.
|
||||
* Fixed a bug where vector layer `setStyle({stroke: false})` wouldn't remove stroke and the same for fill. [#441](https://github.com/CloudMade/Leaflet/issues/441)
|
||||
* Fixed a bug where `Marker` `bindPopup` method wouldn't take `offset` option into account.
|
||||
* Fixed a bug where `TileLayer` `load` event wasn't fired if some tile didn't load (by [@cfis](https://github.com/cfis)) [#682](https://github.com/CloudMade/Leaflet/pull/682)
|
||||
* Fixed a bug where `TileLayer` `load` event wasn't fired if some tile didn't load (by [@lapinos03](https://github.com/lapinos03) and [@cfis](https://github.com/cfis)) [#682](https://github.com/CloudMade/Leaflet/pull/682)
|
||||
* Fixed error when removing `GeoJSON` layer. [#685](https://github.com/CloudMade/Leaflet/issues/685)
|
||||
* Fixed error when calling `GeoJSON` `clearLayer` (by [@runderwood](https://github.com/runderwood)). [#617](https://github.com/CloudMade/Leaflet/pull/617)
|
||||
* Fixed a bug where polygons/polylines sometimes throwed an error when making them editable manually (by [@cfis](https://github.com/cfis)). [#669](https://github.com/CloudMade/Leaflet/pull/669)
|
||||
|
@ -13,7 +13,7 @@ L.TileLayer = L.Class.extend({
|
||||
errorTileUrl: '',
|
||||
attribution: '',
|
||||
opacity: 1,
|
||||
scheme: 'xyz',
|
||||
tms: false,
|
||||
continuousWorld: false,
|
||||
noWrap: false,
|
||||
zoomOffset: 0,
|
||||
@ -192,6 +192,7 @@ L.TileLayer = L.Class.extend({
|
||||
}
|
||||
|
||||
this._tiles = {};
|
||||
this._tilesToLoad = 0;
|
||||
|
||||
if (this.options.reuseTiles) {
|
||||
this._unusedTiles = [];
|
||||
@ -234,16 +235,21 @@ L.TileLayer = L.Class.extend({
|
||||
var queue = [],
|
||||
center = bounds.getCenter();
|
||||
|
||||
var j, i;
|
||||
var j, i, point;
|
||||
|
||||
for (j = bounds.min.y; j <= bounds.max.y; j++) {
|
||||
for (i = bounds.min.x; i <= bounds.max.x; i++) {
|
||||
if (!((i + ':' + j) in this._tiles)) {
|
||||
queue.push(new L.Point(i, j));
|
||||
point = new L.Point(i, j);
|
||||
|
||||
if (this._tileShouldBeLoaded(point)) {
|
||||
queue.push(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (queue.length === 0) { return; }
|
||||
var tilesToLoad = queue.length;
|
||||
|
||||
if (tilesToLoad === 0) { return; }
|
||||
|
||||
// load tiles in order of their distance to center
|
||||
queue.sort(function (a, b) {
|
||||
@ -252,16 +258,37 @@ L.TileLayer = L.Class.extend({
|
||||
|
||||
var fragment = document.createDocumentFragment();
|
||||
|
||||
this._tilesToLoad = queue.length;
|
||||
// if its the first batch of tiles to load
|
||||
if (!this._tilesToLoad) {
|
||||
this.fire('loading');
|
||||
}
|
||||
|
||||
var k, len;
|
||||
for (k = 0, len = this._tilesToLoad; k < len; k++) {
|
||||
this._addTile(queue[k], fragment);
|
||||
this._tilesToLoad += tilesToLoad;
|
||||
|
||||
for (i = 0; i < tilesToLoad; i++) {
|
||||
this._addTile(queue[i], fragment);
|
||||
}
|
||||
|
||||
this._container.appendChild(fragment);
|
||||
},
|
||||
|
||||
_tileShouldBeLoaded: function (tilePoint) {
|
||||
if ((tilePoint.x + ':' + tilePoint.y) in this._tiles) {
|
||||
return false; // already loaded
|
||||
}
|
||||
|
||||
if (!this.options.continuousWorld) {
|
||||
var limit = this._getWrapTileNum();
|
||||
|
||||
if (this.options.noWrap && (tilePoint.x < 0 || tilePoint.x >= limit) ||
|
||||
tilePoint.y < 0 || tilePoint.y >= limit) {
|
||||
return false; // exceeds world bounds
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_removeOtherTiles: function (bounds) {
|
||||
var kArr, x, y, key;
|
||||
|
||||
@ -299,25 +326,7 @@ L.TileLayer = L.Class.extend({
|
||||
},
|
||||
|
||||
_addTile: function (tilePoint, container) {
|
||||
var tilePos = this._getTilePos(tilePoint),
|
||||
zoom = this._map.getZoom(),
|
||||
key = tilePoint.x + ':' + tilePoint.y,
|
||||
limit = Math.pow(2, this._getOffsetZoom(zoom));
|
||||
|
||||
// wrap tile coordinates
|
||||
if (!this.options.continuousWorld) {
|
||||
if (!this.options.noWrap) {
|
||||
tilePoint.x = ((tilePoint.x % limit) + limit) % limit;
|
||||
} else if (tilePoint.x < 0 || tilePoint.x >= limit) {
|
||||
this._tilesToLoad--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (tilePoint.y < 0 || tilePoint.y >= limit) {
|
||||
this._tilesToLoad--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
var tilePos = this._getTilePos(tilePoint);
|
||||
|
||||
// get unused tile - or create a new tile
|
||||
var tile = this._getTile();
|
||||
@ -327,22 +336,24 @@ L.TileLayer = L.Class.extend({
|
||||
// (other browsers don't currently care) - see debug/hacks/jitter.html for an example
|
||||
L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome);
|
||||
|
||||
this._tiles[key] = tile;
|
||||
this._tiles[tilePoint.x + ':' + tilePoint.y] = tile;
|
||||
|
||||
if (this.options.scheme === 'tms') {
|
||||
tilePoint.y = limit - tilePoint.y - 1;
|
||||
}
|
||||
|
||||
this._loadTile(tile, tilePoint, zoom);
|
||||
this._loadTile(tile, tilePoint);
|
||||
|
||||
if (tile.parentNode !== this._container) {
|
||||
container.appendChild(tile);
|
||||
}
|
||||
},
|
||||
|
||||
_getOffsetZoom: function (zoom) {
|
||||
var options = this.options;
|
||||
zoom = options.zoomReverse ? options.maxZoom - zoom : zoom;
|
||||
_getZoomForUrl: function () {
|
||||
|
||||
var options = this.options,
|
||||
zoom = this._map.getZoom();
|
||||
|
||||
if (options.zoomReverse) {
|
||||
zoom = options.maxZoom - zoom;
|
||||
}
|
||||
|
||||
return zoom + options.zoomOffset;
|
||||
},
|
||||
|
||||
@ -355,15 +366,34 @@ L.TileLayer = L.Class.extend({
|
||||
|
||||
// image-specific code (override to implement e.g. Canvas or SVG tile layer)
|
||||
|
||||
getTileUrl: function (tilePoint, zoom) {
|
||||
getTileUrl: function (tilePoint) {
|
||||
this._adjustTilePoint(tilePoint);
|
||||
|
||||
return L.Util.template(this._url, L.Util.extend({
|
||||
s: this._getSubdomain(tilePoint),
|
||||
z: this._getOffsetZoom(zoom),
|
||||
z: this._getZoomForUrl(),
|
||||
x: tilePoint.x,
|
||||
y: tilePoint.y
|
||||
}, this.options));
|
||||
},
|
||||
|
||||
_getWrapTileNum: function () {
|
||||
// TODO refactor, limit is not valid for non-standard projections
|
||||
return Math.pow(2, this._getZoomForUrl());
|
||||
},
|
||||
|
||||
_adjustTilePoint: function (tilePoint) {
|
||||
// wrap tile coordinates
|
||||
if (!this.options.continuousWorld && !this.options.noWrap) {
|
||||
var limit = this._getWrapTileNum();
|
||||
tilePoint.x = ((tilePoint.x % limit) + limit) % limit;
|
||||
}
|
||||
|
||||
if (this.options.tms) {
|
||||
tilePoint.y = limit - tilePoint.y - 1;
|
||||
}
|
||||
},
|
||||
|
||||
_getSubdomain: function (tilePoint) {
|
||||
var index = (tilePoint.x + tilePoint.y) % this.options.subdomains.length;
|
||||
return this.options.subdomains[index];
|
||||
@ -397,12 +427,12 @@ L.TileLayer = L.Class.extend({
|
||||
return tile;
|
||||
},
|
||||
|
||||
_loadTile: function (tile, tilePoint, zoom) {
|
||||
_loadTile: function (tile, tilePoint) {
|
||||
tile._layer = this;
|
||||
tile.onload = this._tileOnLoad;
|
||||
tile.onerror = this._tileOnError;
|
||||
|
||||
tile.src = this.getTileUrl(tilePoint, zoom);
|
||||
tile.src = this.getTileUrl(tilePoint);
|
||||
},
|
||||
|
||||
_tileLoaded: function () {
|
||||
|
Loading…
Reference in New Issue
Block a user