Refactor redundant HDMapType into DynmapTileLayer.ts

This commit is contained in:
James Lyne 2021-05-20 00:29:17 +01:00
parent 2ab569c18f
commit 6095647b82
7 changed files with 49 additions and 137 deletions

View File

@ -141,7 +141,7 @@ export default defineComponent({
window.history.replaceState({}, '', newServer.id); window.history.replaceState({}, '', newServer.id);
loadConfiguration(); loadConfiguration();
}); }, {deep: true});
watch(configurationHash, (newHash, oldHash) => { watch(configurationHash, (newHash, oldHash) => {
if(newHash && oldHash) { if(newHash && oldHash) {
window.showSplash(); window.showSplash();

View File

@ -19,10 +19,10 @@ import {defineComponent, onUnmounted, computed, watch} from "@vue/runtime-core";
import {DynmapWorldMap} from "@/dynmap"; import {DynmapWorldMap} from "@/dynmap";
import {Map} from 'leaflet'; import {Map} from 'leaflet';
import {useStore} from "@/store"; import {useStore} from "@/store";
import {HDMapType} from "@/leaflet/mapType/HDMapType";
import {MutationTypes} from "@/store/mutation-types"; import {MutationTypes} from "@/store/mutation-types";
import {ActionTypes} from "@/store/action-types"; import {ActionTypes} from "@/store/action-types";
import {getMinecraftTime} from "@/util"; import {getMinecraftTime} from "@/util";
import {DynmapTileLayer} from "@/leaflet/tileLayer/DynmapTileLayer";
export default defineComponent({ export default defineComponent({
props: { props: {
@ -46,7 +46,7 @@ export default defineComponent({
const store = useStore(), const store = useStore(),
night = computed(() => getMinecraftTime(store.state.currentWorldState.timeOfDay).night), night = computed(() => getMinecraftTime(store.state.currentWorldState.timeOfDay).night),
layer = new HDMapType({ layer = new DynmapTileLayer({
errorTileUrl: 'images/blank.png', errorTileUrl: 'images/blank.png',
mapSettings: Object.freeze(JSON.parse(JSON.stringify(props.map))), mapSettings: Object.freeze(JSON.parse(JSON.stringify(props.map))),
night: night.value, night: night.value,

View File

@ -1,62 +0,0 @@
/*
* Copyright 2020 James Lyne
*
* Some portions of this file were taken from https://github.com/webbukkit/dynmap.
* These portions are Copyright 2020 Dynmap Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Util} 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;
Util.setOptions(this, options);
this._projection = Object.freeze(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 ? '' : '_');
}
}

View File

@ -20,25 +20,42 @@
import {Util, LatLng, Class} from 'leaflet'; import {Util, LatLng, Class} from 'leaflet';
import {Coordinate} from "@/dynmap"; import {Coordinate} from "@/dynmap";
export interface DynmapProjectionOptions {} export interface DynmapProjectionOptions {
mapToWorld: [number, number, number, number, number, number, number, number, number],
worldToMap: [number, number, number, number, number, number, number, number, number],
nativeZoomLevels: number
}
export interface DynmapProjection { export interface DynmapProjection {
options: DynmapProjectionOptions
locationToLatLng(location: Coordinate): LatLng; locationToLatLng(location: Coordinate): LatLng;
latLngToLocation(latLng: LatLng, y: number): Coordinate; latLngToLocation(latLng: LatLng, y: number): Coordinate;
} }
export class DynmapProjection extends Class { export class DynmapProjection extends Class {
constructor(options?: DynmapProjectionOptions) { constructor(options: DynmapProjectionOptions) {
super(); super();
Util.setOptions(this, options); Util.setOptions(this, options);
} }
locationToLatLng(location: Coordinate): LatLng { locationToLatLng(location: Coordinate): LatLng {
return new LatLng(location.x, location.z); 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 LatLng(
-((128 - lat) / (1 << this.options.nativeZoomLevels)),
lng / (1 << this.options.nativeZoomLevels));
} }
latLngToLocation(latLng: LatLng, y: number): Coordinate { latLngToLocation(latLng: LatLng, y: number): Coordinate {
return {x: latLng.lat, y, z: latLng.lng}; 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};
} }
} }

View File

@ -1,61 +0,0 @@
/*
* Copyright 2020 James Lyne
*
* Some portions of this file were taken from https://github.com/webbukkit/dynmap.
* These portions are Copyright 2020 Dynmap Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {DynmapProjection} from "@/leaflet/projection/DynmapProjection";
import {Util, LatLng} 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);
Util.setOptions(this, options);
}
locationToLatLng(location: Coordinate): 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 LatLng(
-((128 - lat) / (1 << this.options.nativeZoomLevels)),
lng / (1 << this.options.nativeZoomLevels));
}
latLngToLocation(latLng: 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;

View File

@ -69,18 +69,29 @@ export interface TileInfo {
fmt: string; fmt: string;
} }
// noinspection JSUnusedGlobalSymbols
export class DynmapTileLayer extends TileLayer { export class DynmapTileLayer extends TileLayer {
constructor(options: DynmapTileLayerOptions) { constructor(options: DynmapTileLayerOptions) {
super('', options); super('', options);
this._mapSettings = options.mapSettings;
options.maxZoom = this._mapSettings.nativeZoomLevels + this._mapSettings.extraZoomLevels;
options.maxNativeZoom = this._mapSettings.nativeZoomLevels;
options.zoomReverse = true;
options.tileSize = 128;
options.minZoom = 0;
Util.setOptions(this, options); Util.setOptions(this, options);
if (options.mapSettings === null) { if (options.mapSettings === null) {
throw new TypeError("mapSettings missing"); throw new TypeError("mapSettings missing");
} }
this._projection = new DynmapProjection({}); this._projection = new DynmapProjection({
this._mapSettings = options.mapSettings; mapToWorld: this._mapSettings.mapToWorld,
worldToMap: this._mapSettings.worldToMap,
nativeZoomLevels: this._mapSettings.nativeZoomLevels,
});
this._cachedTileUrls = Object.seal(new Map()); this._cachedTileUrls = Object.seal(new Map());
this._namedTiles = Object.seal(new Map()); this._namedTiles = Object.seal(new Map());
this._loadQueue = []; this._loadQueue = [];
@ -99,8 +110,12 @@ export class DynmapTileLayer extends TileLayer {
} }
} }
getTileName(coords: Coordinate): string { getTileName(coords: Coordinate) {
throw "getTileName not implemented"; const 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}`;
} }
getTileUrl(coords: Coordinate) { getTileUrl(coords: Coordinate) {
@ -232,7 +247,10 @@ export class DynmapTileLayer extends TileLayer {
// Some helper functions. // Some helper functions.
zoomprefix(amount: number) { zoomprefix(amount: number) {
return 'z'.repeat(amount); // amount == 0 -> ''
// amount == 1 -> 'z_'
// amount == 2 -> 'zz_'
return 'z'.repeat(amount) + (amount === 0 ? '' : '_');
} }
getTileInfo(coords: Coordinate): TileInfo { getTileInfo(coords: Coordinate): TileInfo {

View File

@ -150,7 +150,7 @@ export const actions: ActionTree<State, State> & Actions = {
return Promise.reject("No current world"); return Promise.reject("No current world");
} }
const update =await getAPI().getUpdate(state.updateRequestId, state.currentWorld.name, state.updateTimestamp.valueOf()); const update = await getAPI().getUpdate(state.updateRequestId, state.currentWorld.name, state.updateTimestamp.valueOf());
commit(MutationTypes.SET_WORLD_STATE, update.worldState); commit(MutationTypes.SET_WORLD_STATE, update.worldState);
commit(MutationTypes.SET_UPDATE_TIMESTAMP, new Date(update.timestamp)); commit(MutationTypes.SET_UPDATE_TIMESTAMP, new Date(update.timestamp));