163 lines
3.9 KiB
TypeScript
163 lines
3.9 KiB
TypeScript
|
import L, {Coords, DoneCallback, TileLayerOptions} from 'leaflet';
|
||
|
import {DynmapProjection} from "@/leaflet/projection/DynmapProjection";
|
||
|
import {Coordinate, DynmapMap} from "@/dynmap";
|
||
|
|
||
|
export interface DynmapTileLayerOptions extends TileLayerOptions {
|
||
|
mapSettings: DynmapMap;
|
||
|
errorTileUrl: string;
|
||
|
}
|
||
|
|
||
|
export interface DynmapTileLayer extends L.TileLayer {
|
||
|
options: DynmapTileLayerOptions;
|
||
|
_projection: any;
|
||
|
_mapSettings: any;
|
||
|
_cachedTileUrls: any;
|
||
|
_namedTiles: any;
|
||
|
|
||
|
locationToLatLng(location: Coordinate): L.LatLng;
|
||
|
|
||
|
latLngToLocation(latLng: L.LatLng): Coordinate;
|
||
|
}
|
||
|
|
||
|
export interface DynmapTile extends HTMLImageElement {
|
||
|
tileName: string;
|
||
|
}
|
||
|
|
||
|
export interface TileInfo {
|
||
|
prefix: string;
|
||
|
nightday: string;
|
||
|
scaledx: number;
|
||
|
scaledy: number;
|
||
|
zoom: string;
|
||
|
zoomprefix: string;
|
||
|
x: number;
|
||
|
y: number;
|
||
|
fmt: string;
|
||
|
}
|
||
|
|
||
|
export class DynmapTileLayer extends L.TileLayer {
|
||
|
constructor(options: DynmapTileLayerOptions) {
|
||
|
super('', options);
|
||
|
|
||
|
if (options.mapSettings === null) {
|
||
|
throw new TypeError("mapSettings missing");
|
||
|
}
|
||
|
|
||
|
this._projection = new DynmapProjection({});
|
||
|
this._mapSettings = options.mapSettings;
|
||
|
this._cachedTileUrls = {};
|
||
|
this._namedTiles = {};
|
||
|
L.Util.setOptions(this, options);
|
||
|
}
|
||
|
|
||
|
getTileName(coords: Coordinate): string {
|
||
|
throw "getTileName not implemented";
|
||
|
}
|
||
|
|
||
|
getTileUrl(coords: Coordinate) {
|
||
|
const tileName = this.getTileName(coords);
|
||
|
let url = this._cachedTileUrls[tileName];
|
||
|
|
||
|
if (!url) {
|
||
|
const path = escape(`${this._mapSettings.world.name}/${tileName}`);
|
||
|
url = `${window.config.url.tiles}${path}`;
|
||
|
this._cachedTileUrls[tileName] = url;
|
||
|
}
|
||
|
|
||
|
return url;
|
||
|
}
|
||
|
|
||
|
updateNamedTile(name: string) {
|
||
|
const tile = this._namedTiles[name];
|
||
|
delete this._cachedTileUrls[name];
|
||
|
|
||
|
if (tile) {
|
||
|
//tile.src = this._cachedTileUrls[name] = this.getTileUrl(name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
createTile(coords: Coords, done: DoneCallback) {
|
||
|
const tile = super.createTile.call(this, coords, done) as DynmapTile,
|
||
|
name = this.getTileName(coords);
|
||
|
|
||
|
tile.tileName = name;
|
||
|
|
||
|
// console.log("Adding " + tile.tileName);
|
||
|
this._namedTiles[name] = tile;
|
||
|
|
||
|
return tile;
|
||
|
}
|
||
|
|
||
|
// stops loading all tiles in the background layer
|
||
|
_abortLoading() {
|
||
|
let tile;
|
||
|
for (const i in this._tiles) {
|
||
|
if (!Object.prototype.hasOwnProperty.call(this._tiles, i)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
tile = this._tiles[i];
|
||
|
|
||
|
if (tile.coords.z !== this._tileZoom) {
|
||
|
if (tile.loaded && tile.el && (tile.el as DynmapTile).tileName) {
|
||
|
// console.log("Aborting " + (tile.el as DynmapTile).tileName);
|
||
|
delete this._namedTiles[(tile.el as DynmapTile).tileName];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
super._abortLoading.call(this);
|
||
|
}
|
||
|
|
||
|
_removeTile(key: string) {
|
||
|
const tile = this._tiles[key];
|
||
|
|
||
|
if (!tile) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const tileName = (tile.el as DynmapTile).tileName;
|
||
|
|
||
|
if (tileName) {
|
||
|
// console.log("Removing " + tileName);
|
||
|
delete this._namedTiles[tileName];
|
||
|
delete this._cachedTileUrls[tileName];
|
||
|
}
|
||
|
|
||
|
// @ts-ignore
|
||
|
super._removeTile.call(this, key);
|
||
|
}
|
||
|
|
||
|
// Some helper functions.
|
||
|
zoomprefix(amount: number) {
|
||
|
return 'z'.repeat(amount);
|
||
|
}
|
||
|
|
||
|
getTileInfo(coords: Coordinate): TileInfo {
|
||
|
// zoom: max zoomed in = this.options.maxZoom, max zoomed out = 0
|
||
|
// izoom: max zoomed in = 0, max zoomed out = this.options.maxZoom
|
||
|
// zoomoutlevel: izoom < mapzoomin -> 0, else -> izoom - mapzoomin (which ranges from 0 till mapzoomout)
|
||
|
const izoom = this._getZoomForUrl(),
|
||
|
zoomoutlevel = Math.max(0, izoom - this._mapSettings.extraZoomLevels),
|
||
|
scale = 1 << zoomoutlevel,
|
||
|
x = scale * coords.x,
|
||
|
y = scale * coords.y;
|
||
|
|
||
|
return {
|
||
|
prefix: this._mapSettings.prefix,
|
||
|
nightday: /*(this._mapSettings.nightAndDay && this.options.dynmap.serverday) ? '_day' :*/ '',
|
||
|
scaledx: x >> 5,
|
||
|
scaledy: y >> 5,
|
||
|
zoom: this.zoomprefix(zoomoutlevel),
|
||
|
zoomprefix: (zoomoutlevel == 0) ? "" : (this.zoomprefix(zoomoutlevel) + "_"),
|
||
|
x: x,
|
||
|
y: y,
|
||
|
fmt: this._mapSettings.imageFormat || 'png'
|
||
|
};
|
||
|
}
|
||
|
|
||
|
getProjection(): DynmapProjection {
|
||
|
return this._projection;
|
||
|
}
|
||
|
}
|