summaryrefslogtreecommitdiffstats
path: root/debian/missing-sources/leaflet.js/layer/tile
diff options
context:
space:
mode:
Diffstat (limited to 'debian/missing-sources/leaflet.js/layer/tile')
-rwxr-xr-xdebian/missing-sources/leaflet.js/layer/tile/GridLayer.js930
-rw-r--r--debian/missing-sources/leaflet.js/layer/tile/TileLayer.WMS.js137
-rw-r--r--debian/missing-sources/leaflet.js/layer/tile/TileLayer.js245
-rw-r--r--debian/missing-sources/leaflet.js/layer/tile/index.js6
4 files changed, 1318 insertions, 0 deletions
diff --git a/debian/missing-sources/leaflet.js/layer/tile/GridLayer.js b/debian/missing-sources/leaflet.js/layer/tile/GridLayer.js
new file mode 100755
index 0000000..5716820
--- /dev/null
+++ b/debian/missing-sources/leaflet.js/layer/tile/GridLayer.js
@@ -0,0 +1,930 @@
+import {Layer} from '../Layer';
+import * as Browser from '../../core/Browser';
+import * as Util from '../../core/Util';
+import * as DomUtil from '../../dom/DomUtil';
+import {Point} from '../../geometry/Point';
+import {Bounds} from '../../geometry/Bounds';
+import {LatLngBounds, toLatLngBounds as latLngBounds} from '../../geo/LatLngBounds';
+
+/*
+ * @class GridLayer
+ * @inherits Layer
+ * @aka L.GridLayer
+ *
+ * Generic class for handling a tiled grid of HTML elements. This is the base class for all tile layers and replaces `TileLayer.Canvas`.
+ * GridLayer can be extended to create a tiled grid of HTML elements like `<canvas>`, `<img>` or `<div>`. GridLayer will handle creating and animating these DOM elements for you.
+ *
+ *
+ * @section Synchronous usage
+ * @example
+ *
+ * To create a custom layer, extend GridLayer and implement the `createTile()` method, which will be passed a `Point` object with the `x`, `y`, and `z` (zoom level) coordinates to draw your tile.
+ *
+ * ```js
+ * var CanvasLayer = L.GridLayer.extend({
+ * createTile: function(coords){
+ * // create a <canvas> element for drawing
+ * var tile = L.DomUtil.create('canvas', 'leaflet-tile');
+ *
+ * // setup tile width and height according to the options
+ * var size = this.getTileSize();
+ * tile.width = size.x;
+ * tile.height = size.y;
+ *
+ * // get a canvas context and draw something on it using coords.x, coords.y and coords.z
+ * var ctx = tile.getContext('2d');
+ *
+ * // return the tile so it can be rendered on screen
+ * return tile;
+ * }
+ * });
+ * ```
+ *
+ * @section Asynchronous usage
+ * @example
+ *
+ * Tile creation can also be asynchronous, this is useful when using a third-party drawing library. Once the tile is finished drawing it can be passed to the `done()` callback.
+ *
+ * ```js
+ * var CanvasLayer = L.GridLayer.extend({
+ * createTile: function(coords, done){
+ * var error;
+ *
+ * // create a <canvas> element for drawing
+ * var tile = L.DomUtil.create('canvas', 'leaflet-tile');
+ *
+ * // setup tile width and height according to the options
+ * var size = this.getTileSize();
+ * tile.width = size.x;
+ * tile.height = size.y;
+ *
+ * // draw something asynchronously and pass the tile to the done() callback
+ * setTimeout(function() {
+ * done(error, tile);
+ * }, 1000);
+ *
+ * return tile;
+ * }
+ * });
+ * ```
+ *
+ * @section
+ */
+
+
+export var GridLayer = Layer.extend({
+
+ // @section
+ // @aka GridLayer options
+ options: {
+ // @option tileSize: Number|Point = 256
+ // Width and height of tiles in the grid. Use a number if width and height are equal, or `L.point(width, height)` otherwise.
+ tileSize: 256,
+
+ // @option opacity: Number = 1.0
+ // Opacity of the tiles. Can be used in the `createTile()` function.
+ opacity: 1,
+
+ // @option updateWhenIdle: Boolean = (depends)
+ // Load new tiles only when panning ends.
+ // `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation.
+ // `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the
+ // [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers.
+ updateWhenIdle: Browser.mobile,
+
+ // @option updateWhenZooming: Boolean = true
+ // By default, a smooth zoom animation (during a [touch zoom](#map-touchzoom) or a [`flyTo()`](#map-flyto)) will update grid layers every integer zoom level. Setting this option to `false` will update the grid layer only when the smooth animation ends.
+ updateWhenZooming: true,
+
+ // @option updateInterval: Number = 200
+ // Tiles will not update more than once every `updateInterval` milliseconds when panning.
+ updateInterval: 200,
+
+ // @option zIndex: Number = 1
+ // The explicit zIndex of the tile layer.
+ zIndex: 1,
+
+ // @option bounds: LatLngBounds = undefined
+ // If set, tiles will only be loaded inside the set `LatLngBounds`.
+ bounds: null,
+
+ // @option minZoom: Number = 0
+ // The minimum zoom level down to which this layer will be displayed (inclusive).
+ minZoom: 0,
+
+ // @option maxZoom: Number = undefined
+ // The maximum zoom level up to which this layer will be displayed (inclusive).
+ maxZoom: undefined,
+
+ // @option maxNativeZoom: Number = undefined
+ // Maximum zoom number the tile source has available. If it is specified,
+ // the tiles on all zoom levels higher than `maxNativeZoom` will be loaded
+ // from `maxNativeZoom` level and auto-scaled.
+ maxNativeZoom: undefined,
+
+ // @option minNativeZoom: Number = undefined
+ // Minimum zoom number the tile source has available. If it is specified,
+ // the tiles on all zoom levels lower than `minNativeZoom` will be loaded
+ // from `minNativeZoom` level and auto-scaled.
+ minNativeZoom: undefined,
+
+ // @option noWrap: Boolean = false
+ // Whether the layer is wrapped around the antimeridian. If `true`, the
+ // GridLayer will only be displayed once at low zoom levels. Has no
+ // effect when the [map CRS](#map-crs) doesn't wrap around. Can be used
+ // in combination with [`bounds`](#gridlayer-bounds) to prevent requesting
+ // tiles outside the CRS limits.
+ noWrap: false,
+
+ // @option pane: String = 'tilePane'
+ // `Map pane` where the grid layer will be added.
+ pane: 'tilePane',
+
+ // @option className: String = ''
+ // A custom class name to assign to the tile layer. Empty by default.
+ className: '',
+
+ // @option keepBuffer: Number = 2
+ // When panning the map, keep this many rows and columns of tiles before unloading them.
+ keepBuffer: 2
+ },
+
+ initialize: function (options) {
+ Util.setOptions(this, options);
+ },
+
+ onAdd: function () {
+ this._initContainer();
+
+ this._levels = {};
+ this._tiles = {};
+
+ this._resetView();
+ this._update();
+ },
+
+ beforeAdd: function (map) {
+ map._addZoomLimit(this);
+ },
+
+ onRemove: function (map) {
+ this._removeAllTiles();
+ DomUtil.remove(this._container);
+ map._removeZoomLimit(this);
+ this._container = null;
+ this._tileZoom = undefined;
+ },
+
+ // @method bringToFront: this
+ // Brings the tile layer to the top of all tile layers.
+ bringToFront: function () {
+ if (this._map) {
+ DomUtil.toFront(this._container);
+ this._setAutoZIndex(Math.max);
+ }
+ return this;
+ },
+
+ // @method bringToBack: this
+ // Brings the tile layer to the bottom of all tile layers.
+ bringToBack: function () {
+ if (this._map) {
+ DomUtil.toBack(this._container);
+ this._setAutoZIndex(Math.min);
+ }
+ return this;
+ },
+
+ // @method getContainer: HTMLElement
+ // Returns the HTML element that contains the tiles for this layer.
+ getContainer: function () {
+ return this._container;
+ },
+
+ // @method setOpacity(opacity: Number): this
+ // Changes the [opacity](#gridlayer-opacity) of the grid layer.
+ setOpacity: function (opacity) {
+ this.options.opacity = opacity;
+ this._updateOpacity();
+ return this;
+ },
+
+ // @method setZIndex(zIndex: Number): this
+ // Changes the [zIndex](#gridlayer-zindex) of the grid layer.
+ setZIndex: function (zIndex) {
+ this.options.zIndex = zIndex;
+ this._updateZIndex();
+
+ return this;
+ },
+
+ // @method isLoading: Boolean
+ // Returns `true` if any tile in the grid layer has not finished loading.
+ isLoading: function () {
+ return this._loading;
+ },
+
+ // @method redraw: this
+ // Causes the layer to clear all the tiles and request them again.
+ redraw: function () {
+ if (this._map) {
+ this._removeAllTiles();
+ this._update();
+ }
+ return this;
+ },
+
+ getEvents: function () {
+ var events = {
+ viewprereset: this._invalidateAll,
+ viewreset: this._resetView,
+ zoom: this._resetView,
+ moveend: this._onMoveEnd
+ };
+
+ if (!this.options.updateWhenIdle) {
+ // update tiles on move, but not more often than once per given interval
+ if (!this._onMove) {
+ this._onMove = Util.throttle(this._onMoveEnd, this.options.updateInterval, this);
+ }
+
+ events.move = this._onMove;
+ }
+
+ if (this._zoomAnimated) {
+ events.zoomanim = this._animateZoom;
+ }
+
+ return events;
+ },
+
+ // @section Extension methods
+ // Layers extending `GridLayer` shall reimplement the following method.
+ // @method createTile(coords: Object, done?: Function): HTMLElement
+ // Called only internally, must be overridden by classes extending `GridLayer`.
+ // Returns the `HTMLElement` corresponding to the given `coords`. If the `done` callback
+ // is specified, it must be called when the tile has finished loading and drawing.
+ createTile: function () {
+ return document.createElement('div');
+ },
+
+ // @section
+ // @method getTileSize: Point
+ // Normalizes the [tileSize option](#gridlayer-tilesize) into a point. Used by the `createTile()` method.
+ getTileSize: function () {
+ var s = this.options.tileSize;
+ return s instanceof Point ? s : new Point(s, s);
+ },
+
+ _updateZIndex: function () {
+ if (this._container && this.options.zIndex !== undefined && this.options.zIndex !== null) {
+ this._container.style.zIndex = this.options.zIndex;
+ }
+ },
+
+ _setAutoZIndex: function (compare) {
+ // go through all other layers of the same pane, set zIndex to max + 1 (front) or min - 1 (back)
+
+ var layers = this.getPane().children,
+ edgeZIndex = -compare(-Infinity, Infinity); // -Infinity for max, Infinity for min
+
+ for (var i = 0, len = layers.length, zIndex; i < len; i++) {
+
+ zIndex = layers[i].style.zIndex;
+
+ if (layers[i] !== this._container && zIndex) {
+ edgeZIndex = compare(edgeZIndex, +zIndex);
+ }
+ }
+
+ if (isFinite(edgeZIndex)) {
+ this.options.zIndex = edgeZIndex + compare(-1, 1);
+ this._updateZIndex();
+ }
+ },
+
+ _updateOpacity: function () {
+ if (!this._map) { return; }
+
+ // IE doesn't inherit filter opacity properly, so we're forced to set it on tiles
+ if (Browser.ielt9) { return; }
+
+ DomUtil.setOpacity(this._container, this.options.opacity);
+
+ var now = +new Date(),
+ nextFrame = false,
+ willPrune = false;
+
+ for (var key in this._tiles) {
+ var tile = this._tiles[key];
+ if (!tile.current || !tile.loaded) { continue; }
+
+ var fade = Math.min(1, (now - tile.loaded) / 200);
+
+ DomUtil.setOpacity(tile.el, fade);
+ if (fade < 1) {
+ nextFrame = true;
+ } else {
+ if (tile.active) {
+ willPrune = true;
+ } else {
+ this._onOpaqueTile(tile);
+ }
+ tile.active = true;
+ }
+ }
+
+ if (willPrune && !this._noPrune) { this._pruneTiles(); }
+
+ if (nextFrame) {
+ Util.cancelAnimFrame(this._fadeFrame);
+ this._fadeFrame = Util.requestAnimFrame(this._updateOpacity, this);
+ }
+ },
+
+ _onOpaqueTile: Util.falseFn,
+
+ _initContainer: function () {
+ if (this._container) { return; }
+
+ this._container = DomUtil.create('div', 'leaflet-layer ' + (this.options.className || ''));
+ this._updateZIndex();
+
+ if (this.options.opacity < 1) {
+ this._updateOpacity();
+ }
+
+ this.getPane().appendChild(this._container);
+ },
+
+ _updateLevels: function () {
+
+ var zoom = this._tileZoom,
+ maxZoom = this.options.maxZoom;
+
+ if (zoom === undefined) { return undefined; }
+
+ for (var z in this._levels) {
+ if (this._levels[z].el.children.length || z === zoom) {
+ this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z);
+ this._onUpdateLevel(z);
+ } else {
+ DomUtil.remove(this._levels[z].el);
+ this._removeTilesAtZoom(z);
+ this._onRemoveLevel(z);
+ delete this._levels[z];
+ }
+ }
+
+ var level = this._levels[zoom],
+ map = this._map;
+
+ if (!level) {
+ level = this._levels[zoom] = {};
+
+ level.el = DomUtil.create('div', 'leaflet-tile-container leaflet-zoom-animated', this._container);
+ level.el.style.zIndex = maxZoom;
+
+ level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom).round();
+ level.zoom = zoom;
+
+ this._setZoomTransform(level, map.getCenter(), map.getZoom());
+
+ // force the browser to consider the newly added element for transition
+ Util.falseFn(level.el.offsetWidth);
+
+ this._onCreateLevel(level);
+ }
+
+ this._level = level;
+
+ return level;
+ },
+
+ _onUpdateLevel: Util.falseFn,
+
+ _onRemoveLevel: Util.falseFn,
+
+ _onCreateLevel: Util.falseFn,
+
+ _pruneTiles: function () {
+ if (!this._map) {
+ return;
+ }
+
+ var key, tile;
+
+ var zoom = this._map.getZoom();
+ if (zoom > this.options.maxZoom ||
+ zoom < this.options.minZoom) {
+ this._removeAllTiles();
+ return;
+ }
+
+ for (key in this._tiles) {
+ tile = this._tiles[key];
+ tile.retain = tile.current;
+ }
+
+ for (key in this._tiles) {
+ tile = this._tiles[key];
+ if (tile.current && !tile.active) {
+ var coords = tile.coords;
+ if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) {
+ this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2);
+ }
+ }
+ }
+
+ for (key in this._tiles) {
+ if (!this._tiles[key].retain) {
+ this._removeTile(key);
+ }
+ }
+ },
+
+ _removeTilesAtZoom: function (zoom) {
+ for (var key in this._tiles) {
+ if (this._tiles[key].coords.z !== zoom) {
+ continue;
+ }
+ this._removeTile(key);
+ }
+ },
+
+ _removeAllTiles: function () {
+ for (var key in this._tiles) {
+ this._removeTile(key);
+ }
+ },
+
+ _invalidateAll: function () {
+ for (var z in this._levels) {
+ DomUtil.remove(this._levels[z].el);
+ this._onRemoveLevel(z);
+ delete this._levels[z];
+ }
+ this._removeAllTiles();
+
+ this._tileZoom = undefined;
+ },
+
+ _retainParent: function (x, y, z, minZoom) {
+ var x2 = Math.floor(x / 2),
+ y2 = Math.floor(y / 2),
+ z2 = z - 1,
+ coords2 = new Point(+x2, +y2);
+ coords2.z = +z2;
+
+ var key = this._tileCoordsToKey(coords2),
+ tile = this._tiles[key];
+
+ if (tile && tile.active) {
+ tile.retain = true;
+ return true;
+
+ } else if (tile && tile.loaded) {
+ tile.retain = true;
+ }
+
+ if (z2 > minZoom) {
+ return this._retainParent(x2, y2, z2, minZoom);
+ }
+
+ return false;
+ },
+
+ _retainChildren: function (x, y, z, maxZoom) {
+
+ for (var i = 2 * x; i < 2 * x + 2; i++) {
+ for (var j = 2 * y; j < 2 * y + 2; j++) {
+
+ var coords = new Point(i, j);
+ coords.z = z + 1;
+
+ var key = this._tileCoordsToKey(coords),
+ tile = this._tiles[key];
+
+ if (tile && tile.active) {
+ tile.retain = true;
+ continue;
+
+ } else if (tile && tile.loaded) {
+ tile.retain = true;
+ }
+
+ if (z + 1 < maxZoom) {
+ this._retainChildren(i, j, z + 1, maxZoom);
+ }
+ }
+ }
+ },
+
+ _resetView: function (e) {
+ var animating = e && (e.pinch || e.flyTo);
+ this._setView(this._map.getCenter(), this._map.getZoom(), animating, animating);
+ },
+
+ _animateZoom: function (e) {
+ this._setView(e.center, e.zoom, true, e.noUpdate);
+ },
+
+ _clampZoom: function (zoom) {
+ var options = this.options;
+
+ if (undefined !== options.minNativeZoom && zoom < options.minNativeZoom) {
+ return options.minNativeZoom;
+ }
+
+ if (undefined !== options.maxNativeZoom && options.maxNativeZoom < zoom) {
+ return options.maxNativeZoom;
+ }
+
+ return zoom;
+ },
+
+ _setView: function (center, zoom, noPrune, noUpdate) {
+ var tileZoom = this._clampZoom(Math.round(zoom));
+ if ((this.options.maxZoom !== undefined && tileZoom > this.options.maxZoom) ||
+ (this.options.minZoom !== undefined && tileZoom < this.options.minZoom)) {
+ tileZoom = undefined;
+ }
+
+ var tileZoomChanged = this.options.updateWhenZooming && (tileZoom !== this._tileZoom);
+
+ if (!noUpdate || tileZoomChanged) {
+
+ this._tileZoom = tileZoom;
+
+ if (this._abortLoading) {
+ this._abortLoading();
+ }
+
+ this._updateLevels();
+ this._resetGrid();
+
+ if (tileZoom !== undefined) {
+ this._update(center);
+ }
+
+ if (!noPrune) {
+ this._pruneTiles();
+ }
+
+ // Flag to prevent _updateOpacity from pruning tiles during
+ // a zoom anim or a pinch gesture
+ this._noPrune = !!noPrune;
+ }
+
+ this._setZoomTransforms(center, zoom);
+ },
+
+ _setZoomTransforms: function (center, zoom) {
+ for (var i in this._levels) {
+ this._setZoomTransform(this._levels[i], center, zoom);
+ }
+ },
+
+ _setZoomTransform: function (level, center, zoom) {
+ var scale = this._map.getZoomScale(zoom, level.zoom),
+ translate = level.origin.multiplyBy(scale)
+ .subtract(this._map._getNewPixelOrigin(center, zoom)).round();
+
+ if (Browser.any3d) {
+ DomUtil.setTransform(level.el, translate, scale);
+ } else {
+ DomUtil.setPosition(level.el, translate);
+ }
+ },
+
+ _resetGrid: function () {
+ var map = this._map,
+ crs = map.options.crs,
+ tileSize = this._tileSize = this.getTileSize(),
+ tileZoom = this._tileZoom;
+
+ var bounds = this._map.getPixelWorldBounds(this._tileZoom);
+ if (bounds) {
+ this._globalTileRange = this._pxBoundsToTileRange(bounds);
+ }
+
+ this._wrapX = crs.wrapLng && !this.options.noWrap && [
+ Math.floor(map.project([0, crs.wrapLng[0]], tileZoom).x / tileSize.x),
+ Math.ceil(map.project([0, crs.wrapLng[1]], tileZoom).x / tileSize.y)
+ ];
+ this._wrapY = crs.wrapLat && !this.options.noWrap && [
+ Math.floor(map.project([crs.wrapLat[0], 0], tileZoom).y / tileSize.x),
+ Math.ceil(map.project([crs.wrapLat[1], 0], tileZoom).y / tileSize.y)
+ ];
+ },
+
+ _onMoveEnd: function () {
+ if (!this._map || this._map._animatingZoom) { return; }
+
+ this._update();
+ },
+
+ _getTiledPixelBounds: function (center) {
+ var map = this._map,
+ mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(),
+ scale = map.getZoomScale(mapZoom, this._tileZoom),
+ pixelCenter = map.project(center, this._tileZoom).floor(),
+ halfSize = map.getSize().divideBy(scale * 2);
+
+ return new Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
+ },
+
+ // Private method to load tiles in the grid's active zoom level according to map bounds
+ _update: function (center) {
+ var map = this._map;
+ if (!map) { return; }
+ var zoom = this._clampZoom(map.getZoom());
+
+ if (center === undefined) { center = map.getCenter(); }
+ if (this._tileZoom === undefined) { return; } // if out of minzoom/maxzoom
+
+ var pixelBounds = this._getTiledPixelBounds(center),
+ tileRange = this._pxBoundsToTileRange(pixelBounds),
+ tileCenter = tileRange.getCenter(),
+ queue = [],
+ margin = this.options.keepBuffer,
+ noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([margin, -margin]),
+ tileRange.getTopRight().add([margin, -margin]));
+
+ // Sanity check: panic if the tile range contains Infinity somewhere.
+ if (!(isFinite(tileRange.min.x) &&
+ isFinite(tileRange.min.y) &&
+ isFinite(tileRange.max.x) &&
+ isFinite(tileRange.max.y))) { throw new Error('Attempted to load an infinite number of tiles'); }
+
+ for (var key in this._tiles) {
+ var c = this._tiles[key].coords;
+ if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x, c.y))) {
+ this._tiles[key].current = false;
+ }
+ }
+
+ // _update just loads more tiles. If the tile zoom level differs too much
+ // from the map's, let _setView reset levels and prune old tiles.
+ if (Math.abs(zoom - this._tileZoom) > 1) { this._setView(center, zoom); return; }
+
+ // create a queue of coordinates to load tiles from
+ for (var j = tileRange.min.y; j <= tileRange.max.y; j++) {
+ for (var i = tileRange.min.x; i <= tileRange.max.x; i++) {
+ var coords = new Point(i, j);
+ coords.z = this._tileZoom;
+
+ if (!this._isValidTile(coords)) { continue; }
+
+ var tile = this._tiles[this._tileCoordsToKey(coords)];
+ if (tile) {
+ tile.current = true;
+ } else {
+ queue.push(coords);
+ }
+ }
+ }
+
+ // sort tile queue to load tiles in order of their distance to center
+ queue.sort(function (a, b) {
+ return a.distanceTo(tileCenter) - b.distanceTo(tileCenter);
+ });
+
+ if (queue.length !== 0) {
+ // if it's the first batch of tiles to load
+ if (!this._loading) {
+ this._loading = true;
+ // @event loading: Event
+ // Fired when the grid layer starts loading tiles.
+ this.fire('loading');
+ }
+
+ // create DOM fragment to append tiles in one batch
+ var fragment = document.createDocumentFragment();
+
+ for (i = 0; i < queue.length; i++) {
+ this._addTile(queue[i], fragment);
+ }
+
+ this._level.el.appendChild(fragment);
+ }
+ },
+
+ _isValidTile: function (coords) {
+ var crs = this._map.options.crs;
+
+ if (!crs.infinite) {
+ // don't load tile if it's out of bounds and not wrapped
+ var bounds = this._globalTileRange;
+ if ((!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) ||
+ (!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))) { return false; }
+ }
+
+ if (!this.options.bounds) { return true; }
+
+ // don't load tile if it doesn't intersect the bounds in options
+ var tileBounds = this._tileCoordsToBounds(coords);
+ return latLngBounds(this.options.bounds).overlaps(tileBounds);
+ },
+
+ _keyToBounds: function (key) {
+ return this._tileCoordsToBounds(this._keyToTileCoords(key));
+ },
+
+ _tileCoordsToNwSe: function (coords) {
+ var map = this._map,
+ tileSize = this.getTileSize(),
+ nwPoint = coords.scaleBy(tileSize),
+ sePoint = nwPoint.add(tileSize),
+ nw = map.unproject(nwPoint, coords.z),
+ se = map.unproject(sePoint, coords.z);
+ return [nw, se];
+ },
+
+ // converts tile coordinates to its geographical bounds
+ _tileCoordsToBounds: function (coords) {
+ var bp = this._tileCoordsToNwSe(coords),
+ bounds = new LatLngBounds(bp[0], bp[1]);
+
+ if (!this.options.noWrap) {
+ bounds = this._map.wrapLatLngBounds(bounds);
+ }
+ return bounds;
+ },
+ // converts tile coordinates to key for the tile cache
+ _tileCoordsToKey: function (coords) {
+ return coords.x + ':' + coords.y + ':' + coords.z;
+ },
+
+ // converts tile cache key to coordinates
+ _keyToTileCoords: function (key) {
+ var k = key.split(':'),
+ coords = new Point(+k[0], +k[1]);
+ coords.z = +k[2];
+ return coords;
+ },
+
+ _removeTile: function (key) {
+ var tile = this._tiles[key];
+ if (!tile) { return; }
+
+ // Cancels any pending http requests associated with the tile
+ // unless we're on Android's stock browser,
+ // see https://github.com/Leaflet/Leaflet/issues/137
+ if (!Browser.androidStock) {
+ tile.el.setAttribute('src', Util.emptyImageUrl);
+ }
+ DomUtil.remove(tile.el);
+
+ delete this._tiles[key];
+
+ // @event tileunload: TileEvent
+ // Fired when a tile is removed (e.g. when a tile goes off the screen).
+ this.fire('tileunload', {
+ tile: tile.el,
+ coords: this._keyToTileCoords(key)
+ });
+ },
+
+ _initTile: function (tile) {
+ DomUtil.addClass(tile, 'leaflet-tile');
+
+ var tileSize = this.getTileSize();
+ tile.style.width = tileSize.x + 'px';
+ tile.style.height = tileSize.y + 'px';
+
+ tile.onselectstart = Util.falseFn;
+ tile.onmousemove = Util.falseFn;
+
+ // update opacity on tiles in IE7-8 because of filter inheritance problems
+ if (Browser.ielt9 && this.options.opacity < 1) {
+ DomUtil.setOpacity(tile, this.options.opacity);
+ }
+
+ // without this hack, tiles disappear after zoom on Chrome for Android
+ // https://github.com/Leaflet/Leaflet/issues/2078
+ if (Browser.android && !Browser.android23) {
+ tile.style.WebkitBackfaceVisibility = 'hidden';
+ }
+ },
+
+ _addTile: function (coords, container) {
+ var tilePos = this._getTilePos(coords),
+ key = this._tileCoordsToKey(coords);
+
+ var tile = this.createTile(this._wrapCoords(coords), Util.bind(this._tileReady, this, coords));
+
+ this._initTile(tile);
+
+ // if createTile is defined with a second argument ("done" callback),
+ // we know that tile is async and will be ready later; otherwise
+ if (this.createTile.length < 2) {
+ // mark tile as ready, but delay one frame for opacity animation to happen
+ Util.requestAnimFrame(Util.bind(this._tileReady, this, coords, null, tile));
+ }
+
+ DomUtil.setPosition(tile, tilePos);
+
+ // save tile in cache
+ this._tiles[key] = {
+ el: tile,
+ coords: coords,
+ current: true
+ };
+
+ container.appendChild(tile);
+ // @event tileloadstart: TileEvent
+ // Fired when a tile is requested and starts loading.
+ this.fire('tileloadstart', {
+ tile: tile,
+ coords: coords
+ });
+ },
+
+ _tileReady: function (coords, err, tile) {
+ if (!this._map) { return; }
+
+ if (err) {
+ // @event tileerror: TileErrorEvent
+ // Fired when there is an error loading a tile.
+ this.fire('tileerror', {
+ error: err,
+ tile: tile,
+ coords: coords
+ });
+ }
+
+ var key = this._tileCoordsToKey(coords);
+
+ tile = this._tiles[key];
+ if (!tile) { return; }
+
+ tile.loaded = +new Date();
+ if (this._map._fadeAnimated) {
+ DomUtil.setOpacity(tile.el, 0);
+ Util.cancelAnimFrame(this._fadeFrame);
+ this._fadeFrame = Util.requestAnimFrame(this._updateOpacity, this);
+ } else {
+ tile.active = true;
+ this._pruneTiles();
+ }
+
+ if (!err) {
+ DomUtil.addClass(tile.el, 'leaflet-tile-loaded');
+
+ // @event tileload: TileEvent
+ // Fired when a tile loads.
+ this.fire('tileload', {
+ tile: tile.el,
+ coords: coords
+ });
+ }
+
+ if (this._noTilesToLoad()) {
+ this._loading = false;
+ // @event load: Event
+ // Fired when the grid layer loaded all visible tiles.
+ this.fire('load');
+
+ if (Browser.ielt9 || !this._map._fadeAnimated) {
+ Util.requestAnimFrame(this._pruneTiles, this);
+ } else {
+ // Wait a bit more than 0.2 secs (the duration of the tile fade-in)
+ // to trigger a pruning.
+ setTimeout(Util.bind(this._pruneTiles, this), 250);
+ }
+ }
+ },
+
+ _getTilePos: function (coords) {
+ return coords.scaleBy(this.getTileSize()).subtract(this._level.origin);
+ },
+
+ _wrapCoords: function (coords) {
+ var newCoords = new Point(
+ this._wrapX ? Util.wrapNum(coords.x, this._wrapX) : coords.x,
+ this._wrapY ? Util.wrapNum(coords.y, this._wrapY) : coords.y);
+ newCoords.z = coords.z;
+ return newCoords;
+ },
+
+ _pxBoundsToTileRange: function (bounds) {
+ var tileSize = this.getTileSize();
+ return new Bounds(
+ bounds.min.unscaleBy(tileSize).floor(),
+ bounds.max.unscaleBy(tileSize).ceil().subtract([1, 1]));
+ },
+
+ _noTilesToLoad: function () {
+ for (var key in this._tiles) {
+ if (!this._tiles[key].loaded) { return false; }
+ }
+ return true;
+ }
+});
+
+// @factory L.gridLayer(options?: GridLayer options)
+// Creates a new instance of GridLayer with the supplied options.
+export function gridLayer(options) {
+ return new GridLayer(options);
+}
diff --git a/debian/missing-sources/leaflet.js/layer/tile/TileLayer.WMS.js b/debian/missing-sources/leaflet.js/layer/tile/TileLayer.WMS.js
new file mode 100644
index 0000000..378fbf3
--- /dev/null
+++ b/debian/missing-sources/leaflet.js/layer/tile/TileLayer.WMS.js
@@ -0,0 +1,137 @@
+import {TileLayer} from './TileLayer';
+import {extend, setOptions, getParamString} from '../../core/Util';
+import {retina} from '../../core/Browser';
+import {EPSG4326} from '../../geo/crs/CRS.EPSG4326';
+import {toBounds} from '../../geometry/Bounds';
+
+/*
+ * @class TileLayer.WMS
+ * @inherits TileLayer
+ * @aka L.TileLayer.WMS
+ * Used to display [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services as tile layers on the map. Extends `TileLayer`.
+ *
+ * @example
+ *
+ * ```js
+ * var nexrad = L.tileLayer.wms("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", {
+ * layers: 'nexrad-n0r-900913',
+ * format: 'image/png',
+ * transparent: true,
+ * attribution: "Weather data © 2012 IEM Nexrad"
+ * });
+ * ```
+ */
+
+export var TileLayerWMS = TileLayer.extend({
+
+ // @section
+ // @aka TileLayer.WMS options
+ // If any custom options not documented here are used, they will be sent to the
+ // WMS server as extra parameters in each request URL. This can be useful for
+ // [non-standard vendor WMS parameters](http://docs.geoserver.org/stable/en/user/services/wms/vendor.html).
+ defaultWmsParams: {
+ service: 'WMS',
+ request: 'GetMap',
+
+ // @option layers: String = ''
+ // **(required)** Comma-separated list of WMS layers to show.
+ layers: '',
+
+ // @option styles: String = ''
+ // Comma-separated list of WMS styles.
+ styles: '',
+
+ // @option format: String = 'image/jpeg'
+ // WMS image format (use `'image/png'` for layers with transparency).
+ format: 'image/jpeg',
+
+ // @option transparent: Boolean = false
+ // If `true`, the WMS service will return images with transparency.
+ transparent: false,
+
+ // @option version: String = '1.1.1'
+ // Version of the WMS service to use
+ version: '1.1.1'
+ },
+
+ options: {
+ // @option crs: CRS = null
+ // Coordinate Reference System to use for the WMS requests, defaults to
+ // map CRS. Don't change this if you're not sure what it means.
+ crs: null,
+
+ // @option uppercase: Boolean = false
+ // If `true`, WMS request parameter keys will be uppercase.
+ uppercase: false
+ },
+
+ initialize: function (url, options) {
+
+ this._url = url;
+
+ var wmsParams = extend({}, this.defaultWmsParams);
+
+ // all keys that are not TileLayer options go to WMS params
+ for (var i in options) {
+ if (!(i in this.options)) {
+ wmsParams[i] = options[i];
+ }
+ }
+
+ options = setOptions(this, options);
+
+ var realRetina = options.detectRetina && retina ? 2 : 1;
+ var tileSize = this.getTileSize();
+ wmsParams.width = tileSize.x * realRetina;
+ wmsParams.height = tileSize.y * realRetina;
+
+ this.wmsParams = wmsParams;
+ },
+
+ onAdd: function (map) {
+
+ this._crs = this.options.crs || map.options.crs;
+ this._wmsVersion = parseFloat(this.wmsParams.version);
+
+ var projectionKey = this._wmsVersion >= 1.3 ? 'crs' : 'srs';
+ this.wmsParams[projectionKey] = this._crs.code;
+
+ TileLayer.prototype.onAdd.call(this, map);
+ },
+
+ getTileUrl: function (coords) {
+
+ var tileBounds = this._tileCoordsToNwSe(coords),
+ crs = this._crs,
+ bounds = toBounds(crs.project(tileBounds[0]), crs.project(tileBounds[1])),
+ min = bounds.min,
+ max = bounds.max,
+ bbox = (this._wmsVersion >= 1.3 && this._crs === EPSG4326 ?
+ [min.y, min.x, max.y, max.x] :
+ [min.x, min.y, max.x, max.y]).join(','),
+ url = L.TileLayer.prototype.getTileUrl.call(this, coords);
+ return url +
+ getParamString(this.wmsParams, url, this.options.uppercase) +
+ (this.options.uppercase ? '&BBOX=' : '&bbox=') + bbox;
+ },
+
+ // @method setParams(params: Object, noRedraw?: Boolean): this
+ // Merges an object with the new parameters and re-requests tiles on the current screen (unless `noRedraw` was set to true).
+ setParams: function (params, noRedraw) {
+
+ extend(this.wmsParams, params);
+
+ if (!noRedraw) {
+ this.redraw();
+ }
+
+ return this;
+ }
+});
+
+
+// @factory L.tileLayer.wms(baseUrl: String, options: TileLayer.WMS options)
+// Instantiates a WMS tile layer object given a base URL of the WMS service and a WMS parameters/options object.
+export function tileLayerWMS(url, options) {
+ return new TileLayerWMS(url, options);
+}
diff --git a/debian/missing-sources/leaflet.js/layer/tile/TileLayer.js b/debian/missing-sources/leaflet.js/layer/tile/TileLayer.js
new file mode 100644
index 0000000..9caf6de
--- /dev/null
+++ b/debian/missing-sources/leaflet.js/layer/tile/TileLayer.js
@@ -0,0 +1,245 @@
+import {GridLayer} from './GridLayer';
+import * as Browser from '../../core/Browser';
+import * as Util from '../../core/Util';
+import * as DomEvent from '../../dom/DomEvent';
+import * as DomUtil from '../../dom/DomUtil';
+
+
+/*
+ * @class TileLayer
+ * @inherits GridLayer
+ * @aka L.TileLayer
+ * Used to load and display tile layers on the map. Extends `GridLayer`.
+ *
+ * @example
+ *
+ * ```js
+ * L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar'}).addTo(map);
+ * ```
+ *
+ * @section URL template
+ * @example
+ *
+ * A string of the following form:
+ *
+ * ```
+ * 'http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png'
+ * ```
+ *
+ * `{s}` means one of the available subdomains (used sequentially to help with browser parallel requests per domain limitation; subdomain values are specified in options; `a`, `b` or `c` by default, can be omitted), `{z}` — zoom level, `{x}` and `{y}` — tile coordinates. `{r}` can be used to add "&commat;2x" to the URL to load retina tiles.
+ *
+ * You can use custom keys in the template, which will be [evaluated](#util-template) from TileLayer options, like this:
+ *
+ * ```
+ * L.tileLayer('http://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png', {foo: 'bar'});
+ * ```
+ */
+
+
+export var TileLayer = GridLayer.extend({
+
+ // @section
+ // @aka TileLayer options
+ options: {
+ // @option minZoom: Number = 0
+ // The minimum zoom level down to which this layer will be displayed (inclusive).
+ minZoom: 0,
+
+ // @option maxZoom: Number = 18
+ // The maximum zoom level up to which this layer will be displayed (inclusive).
+ maxZoom: 18,
+
+ // @option subdomains: String|String[] = 'abc'
+ // Subdomains of the tile service. Can be passed in the form of one string (where each letter is a subdomain name) or an array of strings.
+ subdomains: 'abc',
+
+ // @option errorTileUrl: String = ''
+ // URL to the tile image to show in place of the tile that failed to load.
+ errorTileUrl: '',
+
+ // @option zoomOffset: Number = 0
+ // The zoom number used in tile URLs will be offset with this value.
+ zoomOffset: 0,
+
+ // @option tms: Boolean = false
+ // If `true`, inverses Y axis numbering for tiles (turn this on for [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) services).
+ tms: false,
+
+ // @option zoomReverse: Boolean = false
+ // If set to true, the zoom number used in tile URLs will be reversed (`maxZoom - zoom` instead of `zoom`)
+ zoomReverse: false,
+
+ // @option detectRetina: Boolean = false
+ // If `true` and user is on a retina display, it will request four tiles of half the specified size and a bigger zoom level in place of one to utilize the high resolution.
+ detectRetina: false,
+
+ // @option crossOrigin: Boolean = false
+ // If true, all tiles will have their crossOrigin attribute set to ''. This is needed if you want to access tile pixel data.
+ crossOrigin: false
+ },
+
+ initialize: function (url, options) {
+
+ this._url = url;
+
+ options = Util.setOptions(this, options);
+
+ // detecting retina displays, adjusting tileSize and zoom levels
+ if (options.detectRetina && Browser.retina && options.maxZoom > 0) {
+
+ options.tileSize = Math.floor(options.tileSize / 2);
+
+ if (!options.zoomReverse) {
+ options.zoomOffset++;
+ options.maxZoom--;
+ } else {
+ options.zoomOffset--;
+ options.minZoom++;
+ }
+
+ options.minZoom = Math.max(0, options.minZoom);
+ }
+
+ if (typeof options.subdomains === 'string') {
+ options.subdomains = options.subdomains.split('');
+ }
+
+ // for https://github.com/Leaflet/Leaflet/issues/137
+ if (!Browser.android) {
+ this.on('tileunload', this._onTileRemove);
+ }
+ },
+
+ // @method setUrl(url: String, noRedraw?: Boolean): this
+ // Updates the layer's URL template and redraws it (unless `noRedraw` is set to `true`).
+ setUrl: function (url, noRedraw) {
+ this._url = url;
+
+ if (!noRedraw) {
+ this.redraw();
+ }
+ return this;
+ },
+
+ // @method createTile(coords: Object, done?: Function): HTMLElement
+ // Called only internally, overrides GridLayer's [`createTile()`](#gridlayer-createtile)
+ // to return an `<img>` HTML element with the appropriate image URL given `coords`. The `done`
+ // callback is called when the tile has been loaded.
+ createTile: function (coords, done) {
+ var tile = document.createElement('img');
+
+ DomEvent.on(tile, 'load', Util.bind(this._tileOnLoad, this, done, tile));
+ DomEvent.on(tile, 'error', Util.bind(this._tileOnError, this, done, tile));
+
+ if (this.options.crossOrigin) {
+ tile.crossOrigin = '';
+ }
+
+ /*
+ Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons
+ http://www.w3.org/TR/WCAG20-TECHS/H67
+ */
+ tile.alt = '';
+
+ /*
+ Set role="presentation" to force screen readers to ignore this
+ https://www.w3.org/TR/wai-aria/roles#textalternativecomputation
+ */
+ tile.setAttribute('role', 'presentation');
+
+ tile.src = this.getTileUrl(coords);
+
+ return tile;
+ },
+
+ // @section Extension methods
+ // @uninheritable
+ // Layers extending `TileLayer` might reimplement the following method.
+ // @method getTileUrl(coords: Object): String
+ // Called only internally, returns the URL for a tile given its coordinates.
+ // Classes extending `TileLayer` can override this function to provide custom tile URL naming schemes.
+ getTileUrl: function (coords) {
+ var data = {
+ r: Browser.retina ? '@2x' : '',
+ s: this._getSubdomain(coords),
+ x: coords.x,
+ y: coords.y,
+ z: this._getZoomForUrl()
+ };
+ if (this._map && !this._map.options.crs.infinite) {
+ var invertedY = this._globalTileRange.max.y - coords.y;
+ if (this.options.tms) {
+ data['y'] = invertedY;
+ }
+ data['-y'] = invertedY;
+ }
+
+ return Util.template(this._url, Util.extend(data, this.options));
+ },
+
+ _tileOnLoad: function (done, tile) {
+ // For https://github.com/Leaflet/Leaflet/issues/3332
+ if (Browser.ielt9) {
+ setTimeout(Util.bind(done, this, null, tile), 0);
+ } else {
+ done(null, tile);
+ }
+ },
+
+ _tileOnError: function (done, tile, e) {
+ var errorUrl = this.options.errorTileUrl;
+ if (errorUrl && tile.getAttribute('src') !== errorUrl) {
+ tile.src = errorUrl;
+ }
+ done(e, tile);
+ },
+
+ _onTileRemove: function (e) {
+ e.tile.onload = null;
+ },
+
+ _getZoomForUrl: function () {
+ var zoom = this._tileZoom,
+ maxZoom = this.options.maxZoom,
+ zoomReverse = this.options.zoomReverse,
+ zoomOffset = this.options.zoomOffset;
+
+ if (zoomReverse) {
+ zoom = maxZoom - zoom;
+ }
+
+ return zoom + zoomOffset;
+ },
+
+ _getSubdomain: function (tilePoint) {
+ var index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length;
+ return this.options.subdomains[index];
+ },
+
+ // stops loading all tiles in the background layer
+ _abortLoading: function () {
+ var i, tile;
+ for (i in this._tiles) {
+ if (this._tiles[i].coords.z !== this._tileZoom) {
+ tile = this._tiles[i].el;
+
+ tile.onload = Util.falseFn;
+ tile.onerror = Util.falseFn;
+
+ if (!tile.complete) {
+ tile.src = Util.emptyImageUrl;
+ DomUtil.remove(tile);
+ delete this._tiles[i];
+ }
+ }
+ }
+ }
+});
+
+
+// @factory L.tilelayer(urlTemplate: String, options?: TileLayer options)
+// Instantiates a tile layer object given a `URL template` and optionally an options object.
+
+export function tileLayer(url, options) {
+ return new TileLayer(url, options);
+}
diff --git a/debian/missing-sources/leaflet.js/layer/tile/index.js b/debian/missing-sources/leaflet.js/layer/tile/index.js
new file mode 100644
index 0000000..da98979
--- /dev/null
+++ b/debian/missing-sources/leaflet.js/layer/tile/index.js
@@ -0,0 +1,6 @@
+export {GridLayer, gridLayer} from './GridLayer';
+import {TileLayer, tileLayer} from './TileLayer';
+import {TileLayerWMS, tileLayerWMS} from './TileLayer.WMS';
+TileLayer.WMS = TileLayerWMS;
+tileLayer.wms = tileLayerWMS;
+export {TileLayer, tileLayer};