Convert some leaflet things to typescript
This commit is contained in:
parent
91c78ecd68
commit
a33b50cb03
@ -1,9 +1,11 @@
|
||||
import L from 'leaflet';
|
||||
import L, {ControlOptions} from 'leaflet';
|
||||
|
||||
const LinkControl = L.Control.extend({
|
||||
options: {position: 'bottomleft'},
|
||||
export interface LinkControlOptions extends ControlOptions {}
|
||||
|
||||
onAdd: function (map) {
|
||||
export class LinkControl extends L.Control {
|
||||
options: LinkControlOptions
|
||||
|
||||
onAdd(map) {
|
||||
this._map = map;
|
||||
this._container = L.DomUtil.create('div', 'dynmap-link');
|
||||
|
||||
@ -12,18 +14,18 @@ const LinkControl = L.Control.extend({
|
||||
|
||||
this._container.appendChild(this._linkButton);
|
||||
return this._container;
|
||||
},
|
||||
}
|
||||
|
||||
getContainer: function () {
|
||||
getContainer() {
|
||||
return this._container;
|
||||
},
|
||||
}
|
||||
|
||||
getPosition: function () {
|
||||
getPosition() {
|
||||
return this.options.position;
|
||||
},
|
||||
}
|
||||
|
||||
_createButton: function (title, className, fn, context) {
|
||||
var link = document.createElement('a');
|
||||
_createButton(title, className, fn, context) {
|
||||
const link = document.createElement('a');
|
||||
link.href = '#';
|
||||
link.title = title;
|
||||
link.className = className;
|
||||
@ -36,16 +38,14 @@ const LinkControl = L.Control.extend({
|
||||
L.DomEvent.addListener(link, 'click', fn, context);
|
||||
|
||||
return link;
|
||||
},
|
||||
}
|
||||
|
||||
_follow: function () {
|
||||
_follow() {
|
||||
// var url = dynmap.getLink();
|
||||
// window.location = url;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// var link = new dynmapLink();
|
||||
// dynmap.map.addControl(link);
|
||||
// }
|
||||
|
||||
export default LinkControl;
|
116
src/leaflet/icon/PlayerIcon.ts
Normal file
116
src/leaflet/icon/PlayerIcon.ts
Normal file
@ -0,0 +1,116 @@
|
||||
import L, {DivIconOptions} from 'leaflet';
|
||||
import {DynmapPlayer} from "@/dynmap";
|
||||
|
||||
export interface PlayerIconOptions extends DivIconOptions {
|
||||
smallFace: boolean,
|
||||
showSkinFace: boolean,
|
||||
showBody: boolean,
|
||||
showHealth: boolean,
|
||||
}
|
||||
|
||||
export class PlayerIcon extends L.DivIcon {
|
||||
private readonly _player: DynmapPlayer;
|
||||
private _container?: HTMLDivElement;
|
||||
private _playerImage?: HTMLImageElement;
|
||||
private _playerName?: HTMLSpanElement;
|
||||
|
||||
private _playerHealth?: HTMLDivElement;
|
||||
private _playerHealthBg?: HTMLDivElement;
|
||||
private _playerHealthBar?: HTMLDivElement;
|
||||
private _playerArmourBg?: HTMLDivElement;
|
||||
private _playerArmourBar?: HTMLDivElement;
|
||||
|
||||
// @ts-ignore
|
||||
options: PlayerIconOptions;
|
||||
|
||||
constructor(player: DynmapPlayer, options: PlayerIconOptions) {
|
||||
super(options);
|
||||
this._player = player;
|
||||
}
|
||||
|
||||
createIcon(oldIcon: HTMLElement) {
|
||||
if (oldIcon) {
|
||||
L.DomUtil.remove(oldIcon);
|
||||
}
|
||||
|
||||
const player = this._player;
|
||||
|
||||
this._container = document.createElement('div');
|
||||
|
||||
// var markerPosition = dynmap.getProjection().fromLocationToLatLng(player.location);
|
||||
// player.marker.setLatLng(markerPosition);
|
||||
|
||||
this._container.classList.add('Marker', 'playerMarker', 'leaflet-marker-icon');
|
||||
|
||||
this._playerImage = document.createElement('img');
|
||||
this._playerImage.classList.add(this.options.smallFace ? 'playerIconSm' : 'playerIcon');
|
||||
this._playerImage.src = 'images/player.png';
|
||||
|
||||
this._playerName = document.createElement('span');
|
||||
this._playerName.classList.add(this.options.smallFace ? 'playerNameSm' : 'playerName');
|
||||
this._playerName.innerText = player.name;
|
||||
|
||||
this._container.insertAdjacentElement('beforeend', this._playerImage);
|
||||
this._container.insertAdjacentElement('beforeend', this._playerName);
|
||||
|
||||
if (this.options.showSkinFace) {
|
||||
|
||||
// if (this.options.smallFace) {
|
||||
// getMinecraftHead(player.account, 16, head => {
|
||||
// this._playerImage!.src = head.src;
|
||||
// });
|
||||
// } else if (this.options.showBody) {
|
||||
// getMinecraftHead(player.account, 'body', head => {
|
||||
// this._playerImage!.src = head.src;
|
||||
// });
|
||||
// } else {
|
||||
// getMinecraftHead(player.account, 32, head => {
|
||||
// this._playerImage!.src = head.src;
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
if (this.options.showHealth) {
|
||||
this._playerHealth = document.createElement('div');
|
||||
|
||||
this._playerHealth.classList.add(this.options.smallFace ? 'healthContainerSm' : 'healthContainer');
|
||||
this._container.insertAdjacentElement('beforeend', this._playerHealth)
|
||||
|
||||
this._playerHealthBar = document.createElement('div');
|
||||
this._playerHealthBar.classList.add('playerHealth');
|
||||
|
||||
this._playerArmourBar = document.createElement('div');
|
||||
this._playerArmourBar.classList.add('playerHealth');
|
||||
|
||||
this._playerHealthBg = document.createElement('div');
|
||||
this._playerArmourBg = document.createElement('div');
|
||||
|
||||
this._playerHealthBg.classList.add('playerHealthBackground');
|
||||
this._playerArmourBar.classList.add('playerArmorBackground');
|
||||
|
||||
this._playerHealthBg.insertAdjacentElement('beforeend', this._playerHealthBar);
|
||||
this._playerArmourBg.insertAdjacentElement('beforeend', this._playerArmourBar);
|
||||
|
||||
this._playerHealth.insertAdjacentElement('beforeend', this._playerHealthBg);
|
||||
this._playerHealth.insertAdjacentElement('beforeend', this._playerArmourBg);
|
||||
|
||||
this._playerHealth.hidden = true;
|
||||
} else {
|
||||
this._playerName.classList.add('playerNameNoHealth');
|
||||
}
|
||||
|
||||
return this._container;
|
||||
}
|
||||
|
||||
update() {
|
||||
this._playerName!.innerText = this._player!.name;
|
||||
|
||||
if (this._player.health !== undefined && this._player.armor !== undefined) {
|
||||
this._playerHealth!.hidden = false;
|
||||
this._playerHealthBar!.style.width = Math.ceil(this._player.health * 2.5) + 'px';
|
||||
this._playerArmourBar!.style.width = Math.ceil(this._player.armor * 2.5) + 'px';
|
||||
} else {
|
||||
this._playerHealth!.hidden = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
import DynmapTileLayer from "@/leaflet/tileLayer/DynmapTileLayer";
|
||||
import HDProjection from "@/leaflet/projection/HDProjection";
|
||||
import L from 'leaflet';
|
||||
|
||||
const HDMapType = DynmapTileLayer.extend({
|
||||
projection: undefined,
|
||||
options: {
|
||||
maxZoom: 1,
|
||||
maxNativeZoom: 1,
|
||||
worldName: '',
|
||||
prefix: '',
|
||||
errorTileUrl: 'images/blank.png',
|
||||
},
|
||||
initialize(options) {
|
||||
DynmapTileLayer.prototype.initialize.call(this, options);
|
||||
options.zoomReverse = true;
|
||||
options.tileSize = 128;
|
||||
options.minZoom = 0;
|
||||
L.Util.setOptions(this, options);
|
||||
this.projection = new HDProjection(Object.assign(options, {map: this}));
|
||||
},
|
||||
|
||||
getTileName: function(coords) {
|
||||
let info = this.getTileInfo(coords);
|
||||
// Y is inverted for HD-map.
|
||||
info.y = -info.y;
|
||||
info.scaledy = info.y >> 5;
|
||||
return `${info.prefix}${info.nightday}/${info.scaledx}_${info.scaledy}/${info.zoom}${info.x}_${info.y}.${info.fmt}`;
|
||||
},
|
||||
zoomprefix: function(amount) {
|
||||
// amount == 0 -> ''
|
||||
// amount == 1 -> 'z_'
|
||||
// amount == 2 -> 'zz_'
|
||||
return 'zzzzzzzzzzzzzzzzzzzzzz'.substr(0, amount) + (amount === 0 ? '' : '_');
|
||||
}
|
||||
});
|
||||
|
||||
// maptypes.HDMapType = function(options) { return new HDMapType(options); };
|
||||
|
||||
const hdMapType = (options) => {
|
||||
return new HDMapType(options);
|
||||
}
|
||||
|
||||
export {
|
||||
HDMapType,
|
||||
hdMapType
|
||||
};
|
43
src/leaflet/mapType/HDMapType.ts
Normal file
43
src/leaflet/mapType/HDMapType.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import L from 'leaflet';
|
||||
import HDProjection from "@/leaflet/projection/HDProjection";
|
||||
import {Coordinate} from "@/dynmap";
|
||||
import {DynmapTileLayer, DynmapTileLayerOptions} from "@/leaflet/tileLayer/DynmapTileLayer";
|
||||
|
||||
export interface HDMapTypeOptions extends DynmapTileLayerOptions {}
|
||||
|
||||
export interface HDMapType extends DynmapTileLayer {
|
||||
}
|
||||
|
||||
export class HDMapType extends DynmapTileLayer {
|
||||
constructor(options: DynmapTileLayerOptions) {
|
||||
super(options);
|
||||
|
||||
options.maxZoom = this._mapSettings.nativeZoomLevels + this._mapSettings.extraZoomLevels;
|
||||
options.maxNativeZoom = this._mapSettings.nativeZoomLevels;
|
||||
options.zoomReverse = true;
|
||||
options.tileSize = 128;
|
||||
options.minZoom = 0;
|
||||
|
||||
L.Util.setOptions(this, options);
|
||||
this._projection = new HDProjection({
|
||||
mapToWorld: this._mapSettings.mapToWorld,
|
||||
worldToMap: this._mapSettings.worldToMap,
|
||||
nativeZoomLevels: this._mapSettings.nativeZoomLevels,
|
||||
});
|
||||
}
|
||||
|
||||
getTileName(coords: Coordinate) {
|
||||
const info = super.getTileInfo(coords);
|
||||
// Y is inverted for HD-map.
|
||||
info.y = -info.y;
|
||||
info.scaledy = info.y >> 5;
|
||||
return `${info.prefix}${info.nightday}/${info.scaledx}_${info.scaledy}/${info.zoom}${info.x}_${info.y}.${info.fmt}`;
|
||||
}
|
||||
|
||||
zoomprefix(amount: number) {
|
||||
// amount == 0 -> ''
|
||||
// amount == 1 -> 'z_'
|
||||
// amount == 2 -> 'zz_'
|
||||
return 'z'.repeat(amount) + (amount === 0 ? '' : '_');
|
||||
}
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
import L from 'leaflet';
|
||||
|
||||
const PlayerMarker = L.Marker.extend({
|
||||
options: {
|
||||
smallFace: true,
|
||||
showSkinFace: false,
|
||||
showBody: false,
|
||||
showHealth: false,
|
||||
},
|
||||
|
||||
initialize: function (player, options) {
|
||||
this._player = player;
|
||||
options.draggable = false;
|
||||
options.icon = new PlayerIcon(player, {
|
||||
smallFace: options.smallFace,
|
||||
showSkinFace: options.showSkinFace,
|
||||
showBody: options.showBody,
|
||||
showHealth: options.showHealth,
|
||||
});
|
||||
|
||||
L.Util.setOptions(this, options);
|
||||
//this._latlng = toLatLng(latlng); //TODO
|
||||
},
|
||||
});
|
||||
|
||||
var PlayerIcon = L.DivIcon.extend({
|
||||
_player: null,
|
||||
_container: null,
|
||||
_playerImage: null,
|
||||
_playerName: null,
|
||||
|
||||
_playerHealth: null,
|
||||
_playerHealthBg: null,
|
||||
_playerHealthBar: null,
|
||||
_playerArmourBg: null,
|
||||
_playerArmourBar: null,
|
||||
|
||||
options: {
|
||||
smallFace: true,
|
||||
showSkinFace: false,
|
||||
showBody: false,
|
||||
showHealth: false,
|
||||
},
|
||||
|
||||
initialize: function (player, options) {
|
||||
this._player = player;
|
||||
L.Util.setOptions(this, options);
|
||||
},
|
||||
|
||||
createIcon: function (oldIcon) {
|
||||
if (oldIcon) {
|
||||
L.DomUtil.remove(oldIcon);
|
||||
}
|
||||
|
||||
var player = this._player;
|
||||
|
||||
this._container = document.createElement('div');
|
||||
|
||||
// var markerPosition = dynmap.getProjection().fromLocationToLatLng(player.location);
|
||||
// player.marker.setLatLng(markerPosition);
|
||||
|
||||
this._container.classList.add('Marker', 'playerMarker', 'leaflet-marker-icon');
|
||||
|
||||
this._playerImage = document.createElement('img');
|
||||
this._playerImage.classList.add(this.options.smallFace ? 'playerIconSm' : 'playerIcon');
|
||||
this._playerImage.src = 'images/player.png';
|
||||
|
||||
this._playerName = document.createElement('span');
|
||||
this._playerName.classList.add(this.options.smallFace ? 'playerNameSm' : 'playerName');
|
||||
this._playerName.innerText = player.name;
|
||||
|
||||
this._container.insertAdjacentElement('beforeend', this._playerImage);
|
||||
this._container.insertAdjacentElement('beforeend', this._playerName);
|
||||
|
||||
if (this.options.showSkinFace) {
|
||||
var that = this;
|
||||
|
||||
if (this.options.smallFace) {
|
||||
getMinecraftHead(player.account, 16, function (head) {
|
||||
that._playerImage.src = head.src;
|
||||
});
|
||||
} else if (this.options.showBody) {
|
||||
getMinecraftHead(player.account, 'body', function (head) {
|
||||
that._playerImage.src = head.src;
|
||||
});
|
||||
} else {
|
||||
getMinecraftHead(player.account, 32, function (head) {
|
||||
that._playerImage.src = head.src;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.showHealth) {
|
||||
this._playerHealth = document.createElement('div');
|
||||
|
||||
this._playerHealth.classList.add(this.options.smallFace ? 'healthContainerSm' : 'healthContainer');
|
||||
this._container.insertAdjacentElement('beforeend', this._playerHealth)
|
||||
|
||||
this._playerHealthBar = document.createElement('div');
|
||||
this._playerHealthBar.classList.add('playerHealth');
|
||||
|
||||
this._playerArmourBar = document.createElement('div');
|
||||
this._playerArmourBar.classList.add('playerHealth');
|
||||
|
||||
this._playerHealthBg = document.createElement('div');
|
||||
this._playerArmourBg = document.createElement('div');
|
||||
|
||||
this._playerHealthBg.classList.add('playerHealthBackground');
|
||||
this._playerArmourBar.classList.add('playerArmorBackground');
|
||||
|
||||
this._playerHealthBg.insertAdjacentElement('beforeend', this._playerHealthBar);
|
||||
this._playerArmourBg.insertAdjacentElement('beforeend', this._playerArmourBar);
|
||||
|
||||
this._playerHealth.insertAdjacentElement('beforeend', this._playerHealthBg);
|
||||
this._playerHealth.insertAdjacentElement('beforeend', this._playerArmourBg);
|
||||
|
||||
this._playerHealth.hidden = true;
|
||||
} else {
|
||||
this._playerName.classList.add('playerNameNoHealth');
|
||||
}
|
||||
|
||||
return this._container;
|
||||
|
||||
// var div = (oldIcon && oldIcon.tagName === 'DIV') ? oldIcon : document.createElement('div'),
|
||||
// options = this.options;
|
||||
//
|
||||
// if (options.html instanceof Element) {
|
||||
// empty(div);
|
||||
// div.appendChild(options.html);
|
||||
// } else {
|
||||
// div.innerHTML = options.html !== false ? options.html : '';
|
||||
// }
|
||||
//
|
||||
// if (options.bgPos) {
|
||||
// var bgPos = toPoint(options.bgPos);
|
||||
// div.style.backgroundPosition = (-bgPos.x) + 'px ' + (-bgPos.y) + 'px';
|
||||
// }
|
||||
// this._setIconStyles(div, 'icon');
|
||||
//
|
||||
// return div;
|
||||
},
|
||||
|
||||
update() {
|
||||
this._playerName.innerText = this.player.name;
|
||||
|
||||
if (this.options.player.health !== undefined && this.options.player.armor !== undefined) {
|
||||
this.options.player.healthContainer.hidden = false;
|
||||
this._this.options.playerHealthBar.style.width = Math.ceil(this.options.player.health * 2.5) + 'px';
|
||||
this._this.options.playerArmourBar.style.width = Math.ceil(this.options.player.armor * 2.5) + 'px';
|
||||
} else {
|
||||
this.options.player.healthContainer.hidden = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default PlayerMarker;
|
29
src/leaflet/marker/PlayerMarker.ts
Normal file
29
src/leaflet/marker/PlayerMarker.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import L, {LatLng, MarkerOptions} from 'leaflet';
|
||||
import {DynmapPlayer} from "@/dynmap";
|
||||
import {PlayerIcon} from "@/leaflet/icon/PlayerIcon";
|
||||
|
||||
export interface PlayerMarkerOptions extends MarkerOptions {
|
||||
smallFace: boolean,
|
||||
showSkinFace: boolean,
|
||||
showBody: boolean,
|
||||
showHealth: boolean,
|
||||
}
|
||||
|
||||
export class PlayerMarker extends L.Marker {
|
||||
private _player: DynmapPlayer;
|
||||
|
||||
constructor(player: DynmapPlayer, options: PlayerMarkerOptions) {
|
||||
super(new LatLng(0,0), options);
|
||||
this._player = player;
|
||||
options.draggable = false;
|
||||
options.icon = new PlayerIcon(player, {
|
||||
smallFace: options.smallFace,
|
||||
showSkinFace: options.showSkinFace,
|
||||
showBody: options.showBody,
|
||||
showHealth: options.showHealth,
|
||||
});
|
||||
|
||||
L.Util.setOptions(this, options);
|
||||
//this._latlng = toLatLng(latlng); //TODO
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import L from 'leaflet';
|
||||
|
||||
const DynmapProjection = L.Class.extend({
|
||||
initialize: function (options) {
|
||||
L.Util.setOptions(this, options);
|
||||
},
|
||||
fromLocationToLatLng: function () {
|
||||
throw "fromLocationToLatLng not implemented";
|
||||
},
|
||||
fromLatLngToLocation: function () {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
export default DynmapProjection;
|
25
src/leaflet/projection/DynmapProjection.ts
Normal file
25
src/leaflet/projection/DynmapProjection.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import L from 'leaflet';
|
||||
import {Coordinate} from "@/dynmap";
|
||||
|
||||
export interface DynmapProjectionOptions {}
|
||||
|
||||
export interface DynmapProjection {
|
||||
locationToLatLng(location: Coordinate): L.LatLng;
|
||||
latLngToLocation(latLng: L.LatLng, y: number): Coordinate;
|
||||
}
|
||||
|
||||
export class DynmapProjection extends L.Class {
|
||||
|
||||
constructor(options: DynmapProjectionOptions) {
|
||||
super();
|
||||
L.Util.setOptions(this, options);
|
||||
}
|
||||
|
||||
locationToLatLng(location: Coordinate): L.LatLng {
|
||||
throw new Error("fromLocationToLatLng not implemented");
|
||||
}
|
||||
|
||||
latLngToLocation(latLng: L.LatLng, y: number): Coordinate {
|
||||
throw new Error("fromLatLngToLocation not implemented");
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import DynmapProjection from "@/leaflet/projection/DynmapProjection";
|
||||
import L from 'leaflet';
|
||||
|
||||
const HDProjection = DynmapProjection.extend({
|
||||
fromLocationToLatLng: function (location) {
|
||||
var wtp = this.options.worldtomap;
|
||||
var lat = wtp[3] * location.x + wtp[4] * location.y + wtp[5] * location.z;
|
||||
var lng = wtp[0] * location.x + wtp[1] * location.y + wtp[2] * location.z;
|
||||
|
||||
return new L.LatLng(
|
||||
-((128 - lat) / (1 << this.options.mapzoomout)),
|
||||
lng / (1 << this.options.mapzoomout),
|
||||
true);
|
||||
},
|
||||
fromLatLngToLocation: function (latlon, y) {
|
||||
var ptw = this.options.maptoworld;
|
||||
var lat = latlon.lng * (1 << this.options.mapzoomout);
|
||||
var lon = 128 + latlon.lat * (1 << this.options.mapzoomout);
|
||||
var x = ptw[0] * lat + ptw[1] * lon + ptw[2] * y;
|
||||
var z = ptw[6] * lat + ptw[7] * lon + ptw[8] * y;
|
||||
return {x: x, y: y, z: z};
|
||||
}
|
||||
});
|
||||
|
||||
export default HDProjection;
|
42
src/leaflet/projection/HDProjection.ts
Normal file
42
src/leaflet/projection/HDProjection.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import {DynmapProjection} from "@/leaflet/projection/DynmapProjection";
|
||||
import L from 'leaflet';
|
||||
import {Coordinate} from "@/dynmap";
|
||||
|
||||
export interface HDProjectionOptions {
|
||||
mapToWorld: [number, number, number, number, number, number, number, number, number],
|
||||
worldToMap: [number, number, number, number, number, number, number, number, number],
|
||||
nativeZoomLevels: number
|
||||
}
|
||||
|
||||
export interface HDProjection extends DynmapProjection {
|
||||
options: HDProjectionOptions
|
||||
}
|
||||
|
||||
export class HDProjection extends DynmapProjection {
|
||||
constructor(options: HDProjectionOptions) {
|
||||
super(options);
|
||||
L.Util.setOptions(this, options);
|
||||
}
|
||||
|
||||
locationToLatLng(location: Coordinate): L.LatLng {
|
||||
const wtp = this.options.worldToMap,
|
||||
lat = wtp[3] * location.x + wtp[4] * location.y + wtp[5] * location.z,
|
||||
lng = wtp[0] * location.x + wtp[1] * location.y + wtp[2] * location.z;
|
||||
|
||||
return new L.LatLng(
|
||||
-((128 - lat) / (1 << this.options.nativeZoomLevels)),
|
||||
lng / (1 << this.options.nativeZoomLevels));
|
||||
}
|
||||
|
||||
latLngToLocation(latLng: L.LatLng, y: number): Coordinate {
|
||||
const ptw = this.options.mapToWorld,
|
||||
lat = latLng.lng * (1 << this.options.nativeZoomLevels),
|
||||
lon = 128 + latLng.lat * (1 << this.options.nativeZoomLevels),
|
||||
x = ptw[0] * lat + ptw[1] * lon + ptw[2] * y,
|
||||
z = ptw[6] * lat + ptw[7] * lon + ptw[8] * y;
|
||||
|
||||
return {x: x, y: y, z: z};
|
||||
}
|
||||
}
|
||||
|
||||
export default HDProjection;
|
@ -1,128 +0,0 @@
|
||||
import L from 'leaflet';
|
||||
|
||||
const DynmapTileLayer = L.TileLayer.extend({
|
||||
options: {
|
||||
worldName: '',
|
||||
prefix: '',
|
||||
},
|
||||
|
||||
_cachedTileUrls: null,
|
||||
_namedTiles: null,
|
||||
|
||||
initialize(options) {
|
||||
L.TileLayer.prototype.initialize.call(this, options);
|
||||
this._cachedTileUrls = {};
|
||||
this._namedTiles = {};
|
||||
L.Util.setOptions(this, options);
|
||||
},
|
||||
|
||||
getProjection: function () {
|
||||
return this.projection;
|
||||
},
|
||||
|
||||
getTileName: function() {
|
||||
throw "getTileName not implemented";
|
||||
},
|
||||
|
||||
getTileUrl: function (coords) {
|
||||
var tileName = this.getTileName(coords, coords.z),
|
||||
url = this._cachedTileUrls[tileName];
|
||||
|
||||
if (!url) {
|
||||
let path = escape(`${this.options.worldName}/${tileName}`);
|
||||
url = `${window.config.url.tiles}${path}`;
|
||||
this._cachedTileUrls[tileName] = url;
|
||||
}
|
||||
|
||||
return url;
|
||||
},
|
||||
|
||||
updateNamedTile: function (name) {
|
||||
var tile = this._namedTiles[name];
|
||||
delete this._cachedTileUrls[name];
|
||||
|
||||
if (tile) {
|
||||
tile.src = this._cachedTileUrls[name] = this.options.dynmap.getTileUrl(name);
|
||||
}
|
||||
},
|
||||
|
||||
createTile(coords, done) {
|
||||
var tile = L.TileLayer.prototype.createTile.call(this, coords, done),
|
||||
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: function () {
|
||||
var i, tile;
|
||||
for (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.complete && tile.el && tile.el.tileName) {
|
||||
// console.log("Aborting " + tile.el.tileName);
|
||||
delete this._namedTiles[tile.el.tileName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
L.TileLayer.prototype._abortLoading.call(this);
|
||||
},
|
||||
|
||||
_removeTile: function (key) {
|
||||
var tile = this._tiles[key];
|
||||
|
||||
if (!tile) {
|
||||
return;
|
||||
}
|
||||
|
||||
var tileName = tile.el.tileName;
|
||||
|
||||
if (tileName) {
|
||||
// console.log("Removing " + tileName);
|
||||
delete this._namedTiles[tileName];
|
||||
delete this._cachedTileUrls[tileName];
|
||||
}
|
||||
|
||||
L.TileLayer.prototype._removeTile.call(this, key);
|
||||
},
|
||||
|
||||
// Some helper functions.
|
||||
zoomprefix: function (amount) {
|
||||
return 'zzzzzzzzzzzzzzzzzzzzzz'.substr(0, amount);
|
||||
},
|
||||
|
||||
getTileInfo: function (coords) {
|
||||
// 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)
|
||||
var izoom = this._getZoomForUrl();
|
||||
var zoomoutlevel = Math.max(0, izoom - (this.options.maxZoom - this.options.maxNativeZoom));
|
||||
var scale = 1 << zoomoutlevel;
|
||||
var x = scale * coords.x;
|
||||
var y = scale * coords.y;
|
||||
return {
|
||||
prefix: this.options.prefix,
|
||||
nightday: (this.options.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.options['image-format'] || 'png'
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
export default DynmapTileLayer;
|
162
src/leaflet/tileLayer/DynmapTileLayer.ts
Normal file
162
src/leaflet/tileLayer/DynmapTileLayer.ts
Normal file
@ -0,0 +1,162 @@
|
||||
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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user