diff --git a/types/leaflet/index.d.ts b/types/leaflet/index.d.ts index eabb98c710..41b4fbd84c 100644 --- a/types/leaflet/index.d.ts +++ b/types/leaflet/index.d.ts @@ -182,6 +182,10 @@ export class Point { y: number; } +export interface Coords extends Point { + z: number; +} + export type PointExpression = Point | PointTuple; export function point(x: number, y: number, round?: boolean): Point; @@ -420,6 +424,8 @@ export class Layer extends Evented { getEvents?(): {[name: string]: (event: LeafletEvent) => void}; getAttribution?(): string | null; beforeAdd?(map: Map): this; + + protected _map: Map; } export interface GridLayerOptions { @@ -439,6 +445,19 @@ export interface GridLayerOptions { keepBuffer?: number; } +export type DoneCallback = (error?: Error, tile?: HTMLElement) => void; + +export interface InternalTiles { + [key: string]: { + active?: boolean, + coords: Coords, + current: boolean, + el: HTMLElement, + loaded?: Date, + retain?: boolean, + }; +} + export class GridLayer extends Layer { constructor(options?: GridLayerOptions); bringToFront(): this; @@ -449,6 +468,12 @@ export class GridLayer extends Layer { isLoading(): boolean; redraw(): this; getTileSize(): Point; + + protected createTile(coords: Coords, done: DoneCallback): HTMLElement; + protected _tileCoordsToKey(coords: Coords): string; + + protected _tiles: InternalTiles; + protected _tileZoom?: number; } export function gridLayer(options?: GridLayerOptions): GridLayer; @@ -472,6 +497,9 @@ export class TileLayer extends GridLayer { constructor(urlTemplate: string, options?: TileLayerOptions); setUrl(url: string, noRedraw?: boolean): this; + protected _abortLoading(): void; + protected _getZoomForUrl(): number; + options: TileLayerOptions; } diff --git a/types/leaflet/leaflet-tests.ts b/types/leaflet/leaflet-tests.ts index c4f73e5b84..a22ab91248 100644 --- a/types/leaflet/leaflet-tests.ts +++ b/types/leaflet/leaflet-tests.ts @@ -510,3 +510,50 @@ lg = new L.LayerGroup([new L.Layer(), new L.Layer()], { pane: 'overlayPane', attribution: 'test' }); + +// adapted from GridLayer documentation +const CanvasLayer = L.GridLayer.extend({ + createTile(coords: L.Coords, done: L.DoneCallback) { + const tile = (L.DomUtil.create('canvas', 'leaflet-tile') as HTMLCanvasElement); + const size = this.getTileSize(); + tile.width = size.x; + tile.height = size.y; + return tile; + } +}); + +// adapted from GridLayer documentation +const AsyncCanvasLayer = L.GridLayer.extend({ + createTile(coords: L.Coords, done: L.DoneCallback) { + const tile = (L.DomUtil.create('canvas', 'leaflet-tile') as HTMLCanvasElement); + const size = this.getTileSize(); + tile.width = size.x; + tile.height = size.y; + setTimeout(() => done(undefined, tile), 1000); + return tile; + } +}); + +export class ExtendedTileLayer extends L.TileLayer { + options: L.TileLayerOptions; + createTile(coords: L.Coords, done: L.DoneCallback) { + const newCoords: L.Coords = (new L.Point(coords.x, coords.y) as L.Coords); + newCoords.z = coords.z; + return super.createTile(newCoords, done); + } + _abortLoading() { + // adapted from TileLayer's implementation + for (const i in this._tiles) { + if (this._tiles[i].coords.z !== this._tileZoom) { + const tile = this._tiles[i].el; + tile.onload = L.Util.falseFn; + tile.onerror = L.Util.falseFn; + if (tile instanceof HTMLImageElement && !tile.complete) { + tile.src = L.Util.emptyImageUrl; + L.DomUtil.remove(tile); + this._tiles[i] = undefined; + } + } + } + } +}