Some jsdocs
This commit is contained in:
parent
f4481a1d6c
commit
0a1842f77d
@ -21,6 +21,9 @@ import {watch} from "@vue/runtime-core";
|
|||||||
|
|
||||||
import "@/assets/icons/chat.svg";
|
import "@/assets/icons/chat.svg";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leaflet map control providing a chat button which opens the chatbox on click
|
||||||
|
*/
|
||||||
export class ChatControl extends Control {
|
export class ChatControl extends Control {
|
||||||
declare options: ControlOptions
|
declare options: ControlOptions
|
||||||
|
|
||||||
|
@ -37,6 +37,9 @@ export interface ClockControlOptions extends ControlOptions {
|
|||||||
showWeather: boolean;
|
showWeather: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leaflet map control providing a clock which can display the current in-game time of day and weather
|
||||||
|
*/
|
||||||
export class ClockControl extends Control {
|
export class ClockControl extends Control {
|
||||||
declare options: ClockControlOptions;
|
declare options: ClockControlOptions;
|
||||||
declare _container?: HTMLElement;
|
declare _container?: HTMLElement;
|
||||||
|
@ -30,6 +30,9 @@ export interface CoordinatesControlOptions extends ControlOptions {
|
|||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leaflet map control which displays in-game block coordinates when hovering over or tapping the map
|
||||||
|
*/
|
||||||
export class CoordinatesControl extends Control {
|
export class CoordinatesControl extends Control {
|
||||||
declare options: CoordinatesControlOptions;
|
declare options: CoordinatesControlOptions;
|
||||||
declare _map ?: Map;
|
declare _map ?: Map;
|
||||||
|
@ -24,6 +24,9 @@ import { toClipboard } from '@soerenmartius/vue3-clipboard';
|
|||||||
import {notify} from "@kyvg/vue3-notification";
|
import {notify} from "@kyvg/vue3-notification";
|
||||||
import {computed} from "@vue/runtime-core";
|
import {computed} from "@vue/runtime-core";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leaflet map control providing a button for copying a link for the current map view to the clipboard
|
||||||
|
*/
|
||||||
export class LinkControl extends Control {
|
export class LinkControl extends Control {
|
||||||
declare options: ControlOptions
|
declare options: ControlOptions
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@ import LayersOptions = Control.LayersOptions;
|
|||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of leaflet's standard {@link Control.Layers}
|
||||||
|
* Sorts layers by position, adds additional keyboard navigation, adjusts to viewport size and tracks expanded state in vuex
|
||||||
|
*/
|
||||||
export class LiveAtlasLayerControl extends Control.Layers {
|
export class LiveAtlasLayerControl extends Control.Layers {
|
||||||
declare _map ?: LeafletMap;
|
declare _map ?: LeafletMap;
|
||||||
declare _overlaysList?: HTMLElement;
|
declare _overlaysList?: HTMLElement;
|
||||||
|
@ -37,6 +37,9 @@ export interface LoadingControlOptions extends ControlOptions {
|
|||||||
delayIndicator?: number;
|
delayIndicator?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leaflet map control which displays a loading spinner when any tiles are loading
|
||||||
|
*/
|
||||||
export class LoadingControl extends Control {
|
export class LoadingControl extends Control {
|
||||||
declare options: LoadingControlOptions;
|
declare options: LoadingControlOptions;
|
||||||
|
|
||||||
|
@ -26,6 +26,9 @@ import {ActionTypes} from "@/store/action-types";
|
|||||||
import {notify} from "@kyvg/vue3-notification";
|
import {notify} from "@kyvg/vue3-notification";
|
||||||
import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap";
|
import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leaflet map control providing a login/logout button which opens the login modal/logs out on click
|
||||||
|
*/
|
||||||
export class LoginControl extends Control {
|
export class LoginControl extends Control {
|
||||||
declare _map: LiveAtlasLeafletMap;
|
declare _map: LiveAtlasLeafletMap;
|
||||||
declare options: ControlOptions;
|
declare options: ControlOptions;
|
||||||
|
@ -25,6 +25,10 @@ export interface LogoControlOptions extends ControlOptions {
|
|||||||
text: string;
|
text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leaflet map control which displays an arbitrary image or text with an optional link
|
||||||
|
* Intended for use for dynmap logo components
|
||||||
|
*/
|
||||||
export class LogoControl extends Control {
|
export class LogoControl extends Control {
|
||||||
declare options: LogoControlOptions;
|
declare options: LogoControlOptions;
|
||||||
|
|
||||||
|
102
src/util.ts
102
src/util.ts
@ -22,7 +22,7 @@ import {
|
|||||||
LiveAtlasDimension,
|
LiveAtlasDimension,
|
||||||
LiveAtlasGlobalMessageConfig,
|
LiveAtlasGlobalMessageConfig,
|
||||||
LiveAtlasLocation,
|
LiveAtlasLocation,
|
||||||
LiveAtlasMessageConfig,
|
LiveAtlasMessageConfig, LiveAtlasParsedUrl,
|
||||||
} from "@/index";
|
} from "@/index";
|
||||||
import {notify} from "@kyvg/vue3-notification";
|
import {notify} from "@kyvg/vue3-notification";
|
||||||
import {globalMessages, serverMessages} from "../messages";
|
import {globalMessages, serverMessages} from "../messages";
|
||||||
@ -34,6 +34,11 @@ export const titleColoursRegex = /§[0-9a-f]/ig;
|
|||||||
export const netherWorldNameRegex = /[_\s]?nether([\s_]|$)/i;
|
export const netherWorldNameRegex = /[_\s]?nether([\s_]|$)/i;
|
||||||
export const endWorldNameRegex = /(^|[_\s])end([\s_]|$)/i;
|
export const endWorldNameRegex = /(^|[_\s])end([\s_]|$)/i;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates 24 hour time of day and the current day from the given server time
|
||||||
|
* @param {number} serverTime Server time in ticks
|
||||||
|
* @returns The equivalent 24 hour time, current day and whether it is currently day or night
|
||||||
|
*/
|
||||||
export const getMinecraftTime = (serverTime: number) => {
|
export const getMinecraftTime = (serverTime: number) => {
|
||||||
const day = serverTime >= 0 && serverTime < 13700;
|
const day = serverTime >= 0 && serverTime < 13700;
|
||||||
|
|
||||||
@ -51,14 +56,26 @@ export const getMinecraftTime = (serverTime: number) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const parseUrl = (url: URL) => {
|
/**
|
||||||
|
* Parses the given {@link URL} into a {@link LiveAtlasParsedUrl}, if the URL matches any known URL formats
|
||||||
|
* @param {URL} url The URL to parse
|
||||||
|
* @returns {LiveAtlasParsedUrl | null} A LiveAtlasParsedUrl if the provided URL matched any known URL formats,
|
||||||
|
* otherwise null
|
||||||
|
*/
|
||||||
|
export const parseUrl = (url: URL): LiveAtlasParsedUrl | null => {
|
||||||
const query = new URLSearchParams(url.search),
|
const query = new URLSearchParams(url.search),
|
||||||
hash = url.hash.replace('#', '');
|
hash = url.hash.replace('#', '');
|
||||||
|
|
||||||
return hash ? parseMapHash(hash) : parseMapSearchParams(query);
|
return hash ? parseMapHash(hash) : parseMapSearchParams(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const parseMapHash = (hash: string) => {
|
/**
|
||||||
|
* Parses the given hash into a {@link LiveAtlasParsedUrl}, if the hash matches the LiveAtlas URL hash format
|
||||||
|
* @param {string} hash The hash to parse
|
||||||
|
* @returns {LiveAtlasParsedUrl | null} A LiveAtlasParsedUrl if the provided hash matched the LiveAtlas URL
|
||||||
|
* hash format, otherwise null
|
||||||
|
*/
|
||||||
|
export const parseMapHash = (hash: string): LiveAtlasParsedUrl | null => {
|
||||||
const parts = hash.replace('#', '').split(';');
|
const parts = hash.replace('#', '').split(';');
|
||||||
|
|
||||||
const world = parts[0] || undefined,
|
const world = parts[0] || undefined,
|
||||||
@ -81,7 +98,13 @@ export const parseMapHash = (hash: string) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const parseMapSearchParams = (query: URLSearchParams) => {
|
/**
|
||||||
|
* Parses the given {@link URLSearchParams} into a {@link LiveAtlasParsedUrl}, if it matches any known query string formats
|
||||||
|
* @param {URLSearchParams} query The URLSearchParams to parse
|
||||||
|
* @returns {LiveAtlasParsedUrl | null} A LiveAtlasParsedUrl if the provided hash matched the LiveAtlas URL
|
||||||
|
* hash format, otherwise null
|
||||||
|
*/
|
||||||
|
export const parseMapSearchParams = (query: URLSearchParams): LiveAtlasParsedUrl | null => {
|
||||||
const world = query.get('worldname') /* Dynmap */ || query.get('world') /* Pl3xmap */ || undefined,
|
const world = query.get('worldname') /* Dynmap */ || query.get('world') /* Pl3xmap */ || undefined,
|
||||||
map = query.has('worldname') ? query.get('mapname') || undefined : undefined, //Dynmap only
|
map = query.has('worldname') ? query.get('mapname') || undefined : undefined, //Dynmap only
|
||||||
location = [
|
location = [
|
||||||
@ -104,6 +127,15 @@ export const parseMapSearchParams = (query: URLSearchParams) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the given {@link LiveAtlasParsedUrl} to ensure all required properties are present and have valid values
|
||||||
|
* @param {LiveAtlasParsedUrl} parsed The parsed URL to validate
|
||||||
|
* @return {LiveAtlasParsedUrl | null} The parsed URL, possibly modified to ensure validity, or null if it is invalid
|
||||||
|
* and cannot be fixed
|
||||||
|
* @see {@link parseMapSearchParams}
|
||||||
|
* @see {@link parseMapHash}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
const validateParsedUrl = (parsed: any) => {
|
const validateParsedUrl = (parsed: any) => {
|
||||||
if(typeof parsed.zoom !== 'undefined' && (isNaN(parsed.zoom) || parsed.zoom < 0 || !isFinite(parsed.zoom))) {
|
if(typeof parsed.zoom !== 'undefined' && (isNaN(parsed.zoom) || parsed.zoom < 0 || !isFinite(parsed.zoom))) {
|
||||||
parsed.zoom = undefined;
|
parsed.zoom = undefined;
|
||||||
@ -116,6 +148,14 @@ const validateParsedUrl = (parsed: any) => {
|
|||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a LiveAtlas formatted URL hash representing the given {@link LiveAtlasMapDefinition}map, {@link Coordinate}
|
||||||
|
* location and zoom level
|
||||||
|
* @param {LiveAtlasMapDefinition} map The map
|
||||||
|
* @param {Coordinate} location The location
|
||||||
|
* @param {number} zoom The zoom level
|
||||||
|
* @return {string} The URL hash (including the #), or an empty string if a valid hash cannot be constructed
|
||||||
|
*/
|
||||||
export const getUrlForLocation = (map: LiveAtlasMapDefinition, location: Coordinate, zoom: number): string => {
|
export const getUrlForLocation = (map: LiveAtlasMapDefinition, location: Coordinate, zoom: number): string => {
|
||||||
const x = Math.round(location.x),
|
const x = Math.round(location.x),
|
||||||
y = Math.round(location.y),
|
y = Math.round(location.y),
|
||||||
@ -129,6 +169,10 @@ export const getUrlForLocation = (map: LiveAtlasMapDefinition, location: Coordin
|
|||||||
return `#${map.world.name};${map.name};${locationString};${zoom}`;
|
return `#${map.world.name};${map.name};${locationString};${zoom}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Focuses the first html element which matches the given selector, if any
|
||||||
|
* @param {string} selector The selector string
|
||||||
|
*/
|
||||||
export const focus = (selector: string) => {
|
export const focus = (selector: string) => {
|
||||||
const element = document.querySelector(selector);
|
const element = document.querySelector(selector);
|
||||||
|
|
||||||
@ -139,31 +183,74 @@ export const focus = (selector: string) => {
|
|||||||
|
|
||||||
const decodeTextarea = document.createElement('textarea');
|
const decodeTextarea = document.createElement('textarea');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes HTML entities in the given string using a <textarea>
|
||||||
|
* @param {string} text The text to decode HTML entities in
|
||||||
|
* @returns {string} The given text with any HTML entities decoded
|
||||||
|
*/
|
||||||
export const decodeHTMLEntities = (text: string) => {
|
export const decodeHTMLEntities = (text: string) => {
|
||||||
decodeTextarea.innerHTML = text;
|
decodeTextarea.innerHTML = text;
|
||||||
return decodeTextarea.textContent || '';
|
return decodeTextarea.textContent || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strips HTML from the given string using a contextual {@link DocumentFragment} and converts <br>s to spaces
|
||||||
|
* @param {string} text The text to strip HTML from
|
||||||
|
* @returns {string} The given text with HTML stripped
|
||||||
|
*/
|
||||||
export const stripHTML = (text: string) => {
|
export const stripHTML = (text: string) => {
|
||||||
return documentRange.createContextualFragment(text.replace(brToSpaceRegex,' ')).textContent || '';
|
return documentRange.createContextualFragment(text.replace(brToSpaceRegex,' ')).textContent || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default success callback function for VueClipboard, will display a notification with the configured copy success
|
||||||
|
* message
|
||||||
|
*/
|
||||||
export const clipboardSuccess = () => () => notify(useStore().state.messages.copyToClipboardSuccess);
|
export const clipboardSuccess = () => () => notify(useStore().state.messages.copyToClipboardSuccess);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default error callback function for VueClipboard, will display a notification with the configured copy error
|
||||||
|
* message
|
||||||
|
*/
|
||||||
export const clipboardError = () => (e: Error) => {
|
export const clipboardError = () => (e: Error) => {
|
||||||
notify({ type: 'error', text: useStore().state.messages.copyToClipboardError });
|
notify({ type: 'error', text: useStore().state.messages.copyToClipboardError });
|
||||||
console.error('Error copying to clipboard', e);
|
console.error('Error copying to clipboard', e);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link LiveAtlasMessageConfig} from the provided config object. The provided object will be checked for all
|
||||||
|
* expected LiveAtlasMessageConfig messages, with fallback "Missing message" messages being used when a message is
|
||||||
|
* missing from the provided object.
|
||||||
|
* @param {Object} config Config object containing messages to include in the final LiveAtlasMessageConfig. Should
|
||||||
|
* contain a complete or subset of keys from LiveAtlasMessageConfig, additional keys will be ignored.
|
||||||
|
*/
|
||||||
export const getMessages = (config: any = {}) => {
|
export const getMessages = (config: any = {}) => {
|
||||||
return Object.assign(_getMessages(globalMessages, config),
|
return Object.assign(_getMessages(globalMessages, config),
|
||||||
_getMessages(serverMessages, config)) as LiveAtlasMessageConfig;
|
_getMessages(serverMessages, config)) as LiveAtlasMessageConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link LiveAtlasGlobalMessageConfig} from the provided config object. The provided object will be checked
|
||||||
|
* for all expected LiveAtlasGlobalMessageConfig messages, with fallback "Missing message" messages being used
|
||||||
|
* when a message is missing from the provided object.
|
||||||
|
* @param {Object} config Config object containing messages to include in the final LiveAtlasGlobalMessageConfig.
|
||||||
|
* Should contain a complete or subset of keys from LiveAtlasGlobalMessageConfig, additional keys will be ignored.
|
||||||
|
*/
|
||||||
export const getGlobalMessages = (config: any = {}) => {
|
export const getGlobalMessages = (config: any = {}) => {
|
||||||
return _getMessages(globalMessages, config) as LiveAtlasGlobalMessageConfig;
|
return _getMessages(globalMessages, config) as LiveAtlasGlobalMessageConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an object containing the keys present in the messageKeys object and the values present in the config object.
|
||||||
|
*
|
||||||
|
* For each key, the config object is checked for a corresponding value. A fallback "Missing message" value is used if
|
||||||
|
* config object does not contain a value.
|
||||||
|
* @param {Object} messageKeys The object to take the keys from
|
||||||
|
* @param {Object} config The object to take the values from, if present
|
||||||
|
* @see {@link getMessages}
|
||||||
|
* @see {@link getGlobalMessages}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
const _getMessages = (messageKeys: any, config: any = {}) => {
|
const _getMessages = (messageKeys: any, config: any = {}) => {
|
||||||
const messages: any = {};
|
const messages: any = {};
|
||||||
|
|
||||||
@ -190,7 +277,7 @@ export const getBounds = (x: number[], y: number[], z: number[]): LiveAtlasBound
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the bounds required to enclose the given array of {@see Coordinate}s
|
* Determines the bounds required to enclose the given array of {@link Coordinate}s
|
||||||
* Multiple dimension arrays are accepted and will be handled recursively
|
* Multiple dimension arrays are accepted and will be handled recursively
|
||||||
* @param {Coordinate[]} points Points to determine the bounds for
|
* @param {Coordinate[]} points Points to determine the bounds for
|
||||||
* @returns {LiveAtlasBounds} The calculated bounds
|
* @returns {LiveAtlasBounds} The calculated bounds
|
||||||
@ -220,7 +307,7 @@ export const getBoundsFromPoints = (points: Coordinate[]): LiveAtlasBounds => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the center point of the given {@see LiveAtlasBounds}
|
* Determines the center point of the given {@link LiveAtlasBounds}
|
||||||
* @param {LiveAtlasBounds} bounds The bounds to find the center point for
|
* @param {LiveAtlasBounds} bounds The bounds to find the center point for
|
||||||
* @return {LiveAtlasLocation} The center point
|
* @return {LiveAtlasLocation} The center point
|
||||||
*/
|
*/
|
||||||
@ -233,7 +320,8 @@ export const getMiddle = (bounds: LiveAtlasBounds): LiveAtlasLocation => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an "allow-scripts" sandboxed <iframe> to be used by {@see runSandboxed}
|
* Creates an "allow-scripts" sandboxed <iframe>
|
||||||
|
* @see {@link runSandboxed}
|
||||||
* @returns {Window} The iframe's contentWindow
|
* @returns {Window} The iframe's contentWindow
|
||||||
*/
|
*/
|
||||||
const createIframeSandbox = () => {
|
const createIframeSandbox = () => {
|
||||||
|
@ -23,6 +23,12 @@ import LiveAtlasPolygon from "@/leaflet/vector/LiveAtlasPolygon";
|
|||||||
import {Coordinate, LiveAtlasAreaMarker} from "@/index";
|
import {Coordinate, LiveAtlasAreaMarker} from "@/index";
|
||||||
import {arePointsEqual, createPopup, isStyleEqual, tooltipOptions} from "@/util/paths";
|
import {arePointsEqual, createPopup, isStyleEqual, tooltipOptions} from "@/util/paths";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link LiveAtlasPolyline} or {@link LiveAtlasPolygon} with the given options
|
||||||
|
* @param {LiveAtlasAreaMarker} options Marker options
|
||||||
|
* @param {Function} converter Function for projecting the marker location onto the map
|
||||||
|
* @return The created LiveAtlasPolyline or LiveAtlasPolygon
|
||||||
|
*/
|
||||||
export const createAreaLayer = (options: LiveAtlasAreaMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
export const createAreaLayer = (options: LiveAtlasAreaMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||||
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
||||||
points = options.points.map(projectPointsMapCallback, converter) as LatLngExpression[] | LatLngExpression[][],
|
points = options.points.map(projectPointsMapCallback, converter) as LatLngExpression[] | LatLngExpression[][],
|
||||||
@ -39,6 +45,13 @@ export const createAreaLayer = (options: LiveAtlasAreaMarker, converter: Functio
|
|||||||
return area;
|
return area;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates or creates a {@link LiveAtlasPolyline} or {@link LiveAtlasPolygon} with the given options
|
||||||
|
* @param {LiveAtlasPolyline | LiveAtlasPolygon} area Optional existing LiveAtlasPolyline or LiveAtlasPolygon
|
||||||
|
* @param {LiveAtlasAreaMarker} options Marker options
|
||||||
|
* @param {Function} converter Function for projecting the marker location onto the map
|
||||||
|
* @returns The created or updated LiveAtlasPolyline or LiveAtlasPolygon
|
||||||
|
*/
|
||||||
export const updateAreaLayer = (area: LiveAtlasPolyline | LiveAtlasPolygon | undefined, options: LiveAtlasAreaMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
export const updateAreaLayer = (area: LiveAtlasPolyline | LiveAtlasPolygon | undefined, options: LiveAtlasAreaMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||||
if (!area) {
|
if (!area) {
|
||||||
return createAreaLayer(options, converter);
|
return createAreaLayer(options, converter);
|
||||||
@ -80,6 +93,14 @@ export const updateAreaLayer = (area: LiveAtlasPolyline | LiveAtlasPolygon | und
|
|||||||
return area;
|
return area;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively applies the given function to the given array of {@link Coordinate}
|
||||||
|
* @param point
|
||||||
|
* @see {@link createAreaLayer}
|
||||||
|
* @see {@link updateAreaLayer}
|
||||||
|
* @returns Projected points as {@link LatLngExpression}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
const projectPointsMapCallback = function(this: Function, point: Coordinate | Coordinate[] | Coordinate[][]): LatLngExpression | LatLngExpression[] {
|
const projectPointsMapCallback = function(this: Function, point: Coordinate | Coordinate[] | Coordinate[][]): LatLngExpression | LatLngExpression[] {
|
||||||
if(Array.isArray(point)) {
|
if(Array.isArray(point)) {
|
||||||
return point.map(projectPointsMapCallback, this) as LatLngExpression[];
|
return point.map(projectPointsMapCallback, this) as LatLngExpression[];
|
||||||
@ -89,6 +110,14 @@ const projectPointsMapCallback = function(this: Function, point: Coordinate | Co
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates shape points for the given individual x y and z arrays
|
||||||
|
* @param {number[]} x Array of x coordinates
|
||||||
|
* @param {[number, number]} y Array of y coordinates
|
||||||
|
* @param {number[]} z Array of z coordinates
|
||||||
|
* @param outline Whether the resulting points will be used in a shape without a fill color
|
||||||
|
* @returns Array of Coordinates
|
||||||
|
*/
|
||||||
export const getPoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] | Coordinate[][] => {
|
export const getPoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] | Coordinate[][] => {
|
||||||
if (x.length === 2) { /* Only 2 points */
|
if (x.length === 2) { /* Only 2 points */
|
||||||
if (y[0] === y[1]) {
|
if (y[0] === y[1]) {
|
||||||
@ -105,7 +134,16 @@ export const getPoints = (x: number[], y: [number, number], z: number[], outline
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const get3DBoxPoints = (x: number[], y: [number, number], z: number[]): Coordinate[][] => {
|
/**
|
||||||
|
* Calculates cuboid points for the given individual x y and z arrays
|
||||||
|
* @param {number[]} x Array of x coordinates
|
||||||
|
* @param {[number, number]} y Array of y coordinates
|
||||||
|
* @param {number[]} z Array of z coordinates
|
||||||
|
* @private
|
||||||
|
* @see {@link getPoints}
|
||||||
|
* @returns Array of Coordinates
|
||||||
|
*/
|
||||||
|
const get3DBoxPoints = (x: number[], y: [number, number], z: number[]): Coordinate[][] => {
|
||||||
const maxX = x[0],
|
const maxX = x[0],
|
||||||
minX = x[1],
|
minX = x[1],
|
||||||
maxY = y[0],
|
maxY = y[0],
|
||||||
@ -148,7 +186,17 @@ export const get3DBoxPoints = (x: number[], y: [number, number], z: number[]): C
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const get2DBoxPoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] => {
|
/**
|
||||||
|
* Calculates rectangle points for the given individual x y and z arrays
|
||||||
|
* @param {number[]} x Array of x coordinates
|
||||||
|
* @param {[number, number]} y Array of y coordinates
|
||||||
|
* @param {number[]} z Array of z coordinates
|
||||||
|
* @param outline Whether the resulting points will be used in a shape without a fill color
|
||||||
|
* @private
|
||||||
|
* @see {@link getPoints}
|
||||||
|
* @returns Array of Coordinates
|
||||||
|
*/
|
||||||
|
const get2DBoxPoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] => {
|
||||||
const maxX = x[0],
|
const maxX = x[0],
|
||||||
minX = x[1],
|
minX = x[1],
|
||||||
minY = y[1],
|
minY = y[1],
|
||||||
@ -173,7 +221,16 @@ export const get2DBoxPoints = (x: number[], y: [number, number], z: number[], ou
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const get3DShapePoints = (x: number[], y: [number, number], z: number[]): Coordinate[][] => {
|
/**
|
||||||
|
* Calculates non-cuobidal 3d shape points for the given individual x y and z arrays
|
||||||
|
* @param {number[]} x Array of x coordinates
|
||||||
|
* @param {[number, number]} y Array of y coordinates
|
||||||
|
* @param {number[]} z Array of z coordinates
|
||||||
|
* @private
|
||||||
|
* @see {@link getPoints}
|
||||||
|
* @returns Array of Coordinates
|
||||||
|
*/
|
||||||
|
const get3DShapePoints = (x: number[], y: [number, number], z: number[]): Coordinate[][] => {
|
||||||
const toplist = [],
|
const toplist = [],
|
||||||
botlist = [],
|
botlist = [],
|
||||||
polylist = [];
|
polylist = [];
|
||||||
@ -198,7 +255,17 @@ export const get3DShapePoints = (x: number[], y: [number, number], z: number[]):
|
|||||||
return polylist;
|
return polylist;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const get2DShapePoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] => {
|
/**
|
||||||
|
* Calculates non-quadrilateral 2d shape points for the given individual x y and z arrays
|
||||||
|
* @param {number[]} x Array of x coordinates
|
||||||
|
* @param {[number, number]} y Array of y coordinates
|
||||||
|
* @param {number[]} z Array of z coordinates
|
||||||
|
* @param outline Whether the resulting points will be used in a shape without a fill color
|
||||||
|
* @private
|
||||||
|
* @see {@link getPoints}
|
||||||
|
* @returns Array of Coordinates
|
||||||
|
*/
|
||||||
|
const get2DShapePoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] => {
|
||||||
const points = [];
|
const points = [];
|
||||||
|
|
||||||
for (let i = 0; i < x.length; i++) {
|
for (let i = 0; i < x.length; i++) {
|
||||||
|
@ -23,6 +23,12 @@ import LiveAtlasPolygon from "@/leaflet/vector/LiveAtlasPolygon";
|
|||||||
import {LiveAtlasCircleMarker} from "@/index";
|
import {LiveAtlasCircleMarker} from "@/index";
|
||||||
import {createPopup, tooltipOptions} from "@/util/paths";
|
import {createPopup, tooltipOptions} from "@/util/paths";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link LiveAtlasPolygon} with the given options
|
||||||
|
* @param {LiveAtlasCircleMarker} options Marker options
|
||||||
|
* @param {Function} converter Function for projecting the marker location onto the map
|
||||||
|
* @return The created LiveAtlasPolygon
|
||||||
|
*/
|
||||||
export const createCircleLayer = (options: LiveAtlasCircleMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
export const createCircleLayer = (options: LiveAtlasCircleMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||||
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
||||||
points = getCirclePoints(options, converter, outline),
|
points = getCirclePoints(options, converter, outline),
|
||||||
@ -39,6 +45,13 @@ export const createCircleLayer = (options: LiveAtlasCircleMarker, converter: Fun
|
|||||||
return circle;
|
return circle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates or creates a {@link LiveAtlasPolyline} with the given options
|
||||||
|
* @param {?LiveAtlasPolyline | LiveAtlasPolygon | undefined} circle Optional existing LiveAtlasPolyline or LiveAtlasPolygons
|
||||||
|
* @param {LiveAtlasCircleMarker} options Marker options
|
||||||
|
* @param {Function} converter Function for projecting the marker location onto the map
|
||||||
|
* @returns The created or updated LiveAtlasPolyline or LiveAtlasPolygon
|
||||||
|
*/
|
||||||
export const updateCircleLayer = (circle: LiveAtlasPolyline | LiveAtlasPolygon | undefined, options: LiveAtlasCircleMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
export const updateCircleLayer = (circle: LiveAtlasPolyline | LiveAtlasPolygon | undefined, options: LiveAtlasCircleMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||||
if (!circle) {
|
if (!circle) {
|
||||||
return createCircleLayer(options, converter);
|
return createCircleLayer(options, converter);
|
||||||
@ -66,6 +79,13 @@ export const updateCircleLayer = (circle: LiveAtlasPolyline | LiveAtlasPolygon |
|
|||||||
return circle;
|
return circle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates projected points for the given {@link LiveAtlasCircleMarker}
|
||||||
|
* @param {LiveAtlasCircleMarker} options LiveAtlasCircleMarker to calculate points for
|
||||||
|
* @param {Function} converter Function for projecting the points
|
||||||
|
* @param outline Whether the resulting points will be used in a shape without a fill color
|
||||||
|
* @returns Array of projected points
|
||||||
|
*/
|
||||||
export const getCirclePoints = (options: LiveAtlasCircleMarker, converter: Function, outline: boolean): LatLngExpression[] => {
|
export const getCirclePoints = (options: LiveAtlasCircleMarker, converter: Function, outline: boolean): LatLngExpression[] => {
|
||||||
const points = [];
|
const points = [];
|
||||||
|
|
||||||
|
@ -21,11 +21,16 @@ import {useStore} from "@/store";
|
|||||||
import MapProvider from "@/providers/MapProvider";
|
import MapProvider from "@/providers/MapProvider";
|
||||||
import DynmapMapProvider from "@/providers/DynmapMapProvider";
|
import DynmapMapProvider from "@/providers/DynmapMapProvider";
|
||||||
|
|
||||||
const expectedConfigVersion = 1;
|
const expectedConfigVersion = 1,
|
||||||
|
registeredProviders: Map<string, new (config: any) => MapProvider> = new Map(),
|
||||||
const registeredProviders: Map<string, new (config: any) => MapProvider> = new Map();
|
serverProviders: Map<string, MapProvider> = new Map();
|
||||||
const serverProviders: Map<string, MapProvider> = new Map();
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the given {@link MapProvider} with the given id
|
||||||
|
* Server entries in {@link LiveAtlasGlobalConfig} with the given id will use the given MapProvider
|
||||||
|
* @param {string} id The id
|
||||||
|
* @param {new (config: any) => MapProvider} provider The MapProvider
|
||||||
|
*/
|
||||||
export const registerMapProvider = (id: string, provider: new (config: any) => MapProvider) => {
|
export const registerMapProvider = (id: string, provider: new (config: any) => MapProvider) => {
|
||||||
if(registeredProviders.has(id)) {
|
if(registeredProviders.has(id)) {
|
||||||
throw new TypeError(`${id} is already registered`);
|
throw new TypeError(`${id} is already registered`);
|
||||||
@ -34,10 +39,22 @@ export const registerMapProvider = (id: string, provider: new (config: any) => M
|
|||||||
registeredProviders.set(id, provider);
|
registeredProviders.set(id, provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MapProvider for the given server
|
||||||
|
* @param {string} server Name of the server
|
||||||
|
* @returns The MapProvider, if one exists
|
||||||
|
*/
|
||||||
export const getServerMapProvider = (server: string): MapProvider | undefined => {
|
export const getServerMapProvider = (server: string): MapProvider | undefined => {
|
||||||
return serverProviders.get(server);
|
return serverProviders.get(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to load server definitions from the provided config object
|
||||||
|
* @param {Object} config Config object to load server definitions from
|
||||||
|
* @returns Map of loaded servers
|
||||||
|
* @see {@link loadConfig}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
const loadLiveAtlasConfig = (config: any): Map<string, LiveAtlasServerDefinition> => {
|
const loadLiveAtlasConfig = (config: any): Map<string, LiveAtlasServerDefinition> => {
|
||||||
const check = '\nCheck your server configuration in index.html is correct.',
|
const check = '\nCheck your server configuration in index.html is correct.',
|
||||||
result = new Map<string, LiveAtlasServerDefinition>();
|
result = new Map<string, LiveAtlasServerDefinition>();
|
||||||
@ -78,6 +95,12 @@ const loadLiveAtlasConfig = (config: any): Map<string, LiveAtlasServerDefinition
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to load a Dynmap server definition from the given object
|
||||||
|
* @param {Object} config Config object to load from
|
||||||
|
* @see {@link loadConfig}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
const loadDefaultConfig = (config: DynmapUrlConfig): Map<string, LiveAtlasServerDefinition> => {
|
const loadDefaultConfig = (config: DynmapUrlConfig): Map<string, LiveAtlasServerDefinition> => {
|
||||||
const check = '\nCheck your standalone/config.js file exists and is being loaded correctly.';
|
const check = '\nCheck your standalone/config.js file exists and is being loaded correctly.';
|
||||||
const result = new Map<string, LiveAtlasServerDefinition>();
|
const result = new Map<string, LiveAtlasServerDefinition>();
|
||||||
@ -97,6 +120,14 @@ const loadDefaultConfig = (config: DynmapUrlConfig): Map<string, LiveAtlasServer
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to load server definitions from the provided config object
|
||||||
|
* If no servers definitions are present in the object, an attempt will be made to load a Dynmap server definition from
|
||||||
|
* a global dynmap config object defined by standalone/config.js
|
||||||
|
* @param {Object} config Config object to load server definitions from
|
||||||
|
* @returns Map of loaded servers
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
export const loadConfig = (config: LiveAtlasGlobalConfig): Map<string, LiveAtlasServerDefinition> => {
|
export const loadConfig = (config: LiveAtlasGlobalConfig): Map<string, LiveAtlasServerDefinition> => {
|
||||||
if (!config) {
|
if (!config) {
|
||||||
throw new ConfigurationError(`No configuration found.\nCheck for any syntax errors in your configuration in index.html. Your browser console may contain additional information.`);
|
throw new ConfigurationError(`No configuration found.\nCheck for any syntax errors in your configuration in index.html. Your browser console may contain additional information.`);
|
||||||
|
@ -23,6 +23,19 @@ const navigationKeys = new Set<string>([
|
|||||||
'End'
|
'End'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for handling keyboard based selection, along with focus navigation within a set of HTML elements.
|
||||||
|
*
|
||||||
|
* The given {@link KeyboardEvent} will be checked for common navigation keys (currently arrow keys + home/end)
|
||||||
|
* and the appropriate {@link HTMLElement} in the provided array of elements will be focused. No focus changes will occur
|
||||||
|
* if none of the provided elements are currently focused
|
||||||
|
*
|
||||||
|
* The event will also be checked for an enter key press, and a click event will be simulated on the target element. The
|
||||||
|
* element does not need to be in the provided element array for this to occur
|
||||||
|
*
|
||||||
|
* @param {KeyboardEvent} e The event to handle
|
||||||
|
* @param {HTMLElement[]} elements The elements to consider for focusing
|
||||||
|
*/
|
||||||
export const handleKeyboardEvent = (e: KeyboardEvent, elements: HTMLElement[]) => {
|
export const handleKeyboardEvent = (e: KeyboardEvent, elements: HTMLElement[]) => {
|
||||||
if(!e.target) {
|
if(!e.target) {
|
||||||
return;
|
return;
|
||||||
|
@ -25,7 +25,7 @@ const playerImageCache = new Map<string, HTMLImageElement>(),
|
|||||||
playerImageQueue: PlayerImageQueueEntry[] = [];
|
playerImageQueue: PlayerImageQueueEntry[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the corresponding pixel size for the given {@see LiveAtlasPlayerImageSize}
|
* Returns the corresponding pixel size for the given {@link LiveAtlasPlayerImageSize}
|
||||||
* @param {LiveAtlasPlayerImageSize} imageSize The image size to get the pixel size for
|
* @param {LiveAtlasPlayerImageSize} imageSize The image size to get the pixel size for
|
||||||
* @returns The pixel size
|
* @returns The pixel size
|
||||||
*/
|
*/
|
||||||
@ -42,12 +42,12 @@ export const getImagePixelSize = (imageSize: LiveAtlasPlayerImageSize) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@see HTMLImageElement} containing an image representing the given {@see LiveAtlasPlayer}
|
* Creates an {@link HTMLImageElement} containing an image representing the given {@link LiveAtlasPlayer}
|
||||||
* at the given {@see LiveAtlasPlayerImageSize} and ensures it has loaded successfully
|
* at the given {@link LiveAtlasPlayerImageSize} and ensures it has loaded successfully
|
||||||
*
|
*
|
||||||
* If an image has previously been loaded for the same player and image size, a cached copy of the image element
|
* If an image has previously been loaded for the same player and image size, a cached copy of the image element
|
||||||
* will be returned; Otherwise an attempt will be made to load the player image from the URL specified by the current
|
* will be returned; Otherwise an attempt will be made to load the player image from the URL specified by the current
|
||||||
* {@see LiveAtlasMapProvider}
|
* {@link LiveAtlasMapProvider}
|
||||||
*
|
*
|
||||||
* The number of concurrent image loads is limited and additional loads will be queued. If this method is called
|
* The number of concurrent image loads is limited and additional loads will be queued. If this method is called
|
||||||
* with the same player and image size multiple times, the load will only be queued once and the same element will be
|
* with the same player and image size multiple times, the load will only be queued once and the same element will be
|
||||||
@ -55,7 +55,8 @@ export const getImagePixelSize = (imageSize: LiveAtlasPlayerImageSize) => {
|
|||||||
*
|
*
|
||||||
* @param {LiveAtlasPlayer} player The player to retrieve the image for
|
* @param {LiveAtlasPlayer} player The player to retrieve the image for
|
||||||
* @param {LiveAtlasPlayerImageSize} size The image size to retrieve
|
* @param {LiveAtlasPlayerImageSize} size The image size to retrieve
|
||||||
* @returns {Promise<HTMLImageElement>} A promise which will resolve to a {@see HTMLImageElement} with the loaded player
|
* @see {@link getDefaultPlayerImage}
|
||||||
|
* @returns {Promise<HTMLImageElement>} A promise which will resolve to a HTMLImageElement with the loaded player
|
||||||
* image as the src. The promise will reject if the image fails to load
|
* image as the src. The promise will reject if the image fails to load
|
||||||
*/
|
*/
|
||||||
export const getPlayerImage = (player: LiveAtlasPlayer | string, size: LiveAtlasPlayerImageSize): Promise<HTMLImageElement> => {
|
export const getPlayerImage = (player: LiveAtlasPlayer | string, size: LiveAtlasPlayerImageSize): Promise<HTMLImageElement> => {
|
||||||
@ -105,7 +106,8 @@ export const getPlayerImage = (player: LiveAtlasPlayer | string, size: LiveAtlas
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the default "Steve" player image. This image can be used as a placeholder whilst waiting for
|
* Returns the default "Steve" player image. This image can be used as a placeholder whilst waiting for
|
||||||
* {@see getPlayerImage} to complete
|
* {@link getPlayerImage} to complete
|
||||||
|
* @see {@link getPlayerImage}
|
||||||
* @returns The default player image
|
* @returns The default player image
|
||||||
*/
|
*/
|
||||||
export const getDefaultPlayerImage = () => {
|
export const getDefaultPlayerImage = () => {
|
||||||
@ -131,7 +133,7 @@ const tickPlayerImageQueue = () => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the player image cache
|
* Clears the player image cache
|
||||||
* Future calls to {@see getPlayerImage} will result in fresh image loads
|
* Future calls to {@link getPlayerImage} will result in fresh image loads
|
||||||
*/
|
*/
|
||||||
export const clearPlayerImageCache = () => {
|
export const clearPlayerImageCache = () => {
|
||||||
playerImageCache.clear();
|
playerImageCache.clear();
|
||||||
|
@ -22,6 +22,12 @@ import {Coordinate, LiveAtlasLineMarker} from "@/index";
|
|||||||
import {LatLngExpression} from "leaflet";
|
import {LatLngExpression} from "leaflet";
|
||||||
import {createPopup, tooltipOptions} from "@/util/paths";
|
import {createPopup, tooltipOptions} from "@/util/paths";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link LiveAtlasPolyline} with the given options
|
||||||
|
* @param {LiveAtlasLineMarker} options Marker options
|
||||||
|
* @param {Function} converter Function for projecting the marker location onto the map
|
||||||
|
* @return The created LiveAtlasPolyline
|
||||||
|
*/
|
||||||
export const createLineLayer = (options: LiveAtlasLineMarker, converter: Function): LiveAtlasPolyline => {
|
export const createLineLayer = (options: LiveAtlasLineMarker, converter: Function): LiveAtlasPolyline => {
|
||||||
const points = options.points.map(projectPointsMapCallback, converter),
|
const points = options.points.map(projectPointsMapCallback, converter),
|
||||||
line = new LiveAtlasPolyline(points, options);
|
line = new LiveAtlasPolyline(points, options);
|
||||||
@ -37,6 +43,13 @@ export const createLineLayer = (options: LiveAtlasLineMarker, converter: Functio
|
|||||||
return line;
|
return line;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates or creates a {@link LiveAtlasPolyline} with the given options
|
||||||
|
* @param {?LiveAtlasPolyline} line Optional existing LiveAtlasPolyline
|
||||||
|
* @param {LiveAtlasLineMarker} options Marker options
|
||||||
|
* @param {Function} converter Function for projecting the marker location onto the map
|
||||||
|
* @returns The created or updated LiveAtlasPolyline
|
||||||
|
*/
|
||||||
export const updateLineLayer = (line: LiveAtlasPolyline | undefined, options: LiveAtlasLineMarker, converter: Function): LiveAtlasPolyline => {
|
export const updateLineLayer = (line: LiveAtlasPolyline | undefined, options: LiveAtlasLineMarker, converter: Function): LiveAtlasPolyline => {
|
||||||
if (!line) {
|
if (!line) {
|
||||||
return createLineLayer(options, converter);
|
return createLineLayer(options, converter);
|
||||||
@ -62,6 +75,13 @@ export const updateLineLayer = (line: LiveAtlasPolyline | undefined, options: Li
|
|||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively applies the given function to the given array of {@link Coordinate}
|
||||||
|
* @param point
|
||||||
|
* @see {@link createAreaLayer}
|
||||||
|
* @see {@link updateAreaLayer}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
const projectPointsMapCallback = function(point: Coordinate): LatLngExpression {
|
const projectPointsMapCallback = function(point: Coordinate): LatLngExpression {
|
||||||
if(Array.isArray(point)) {
|
if(Array.isArray(point)) {
|
||||||
return projectPointsMapCallback(point);
|
return projectPointsMapCallback(point);
|
||||||
@ -71,6 +91,13 @@ const projectPointsMapCallback = function(point: Coordinate): LatLngExpression {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates line points for the given individual x y and z arrays
|
||||||
|
* @param {number[]} x Array of x coordinates
|
||||||
|
* @param {[number, number]} y Array of y coordinates
|
||||||
|
* @param {number[]} z Array of z coordinates
|
||||||
|
* @returns Array of Coordinates
|
||||||
|
*/
|
||||||
export const getLinePoints = (x: number[], y: number[], z: number[]): Coordinate[] => {
|
export const getLinePoints = (x: number[], y: number[], z: number[]): Coordinate[] => {
|
||||||
const points = [];
|
const points = [];
|
||||||
|
|
||||||
|
@ -53,6 +53,9 @@ let pendingUpdates: ComputedRef;
|
|||||||
const updateHandlers: Set<LiveAtlasMarkerUpdateCallback> = new Set();
|
const updateHandlers: Set<LiveAtlasMarkerUpdateCallback> = new Set();
|
||||||
const setUpdateHandlers: { [key:string]: Set<LiveAtlasMarkerUpdateCallback>} = {};
|
const setUpdateHandlers: { [key:string]: Set<LiveAtlasMarkerUpdateCallback>} = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts handling of pending marker updates
|
||||||
|
*/
|
||||||
export const startUpdateHandling = () => {
|
export const startUpdateHandling = () => {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
@ -65,6 +68,9 @@ export const startUpdateHandling = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops handling of pending marker updates
|
||||||
|
*/
|
||||||
export const stopUpdateHandling = () => {
|
export const stopUpdateHandling = () => {
|
||||||
if(updateFrame) {
|
if(updateFrame) {
|
||||||
cancelAnimationFrame(updateFrame);
|
cancelAnimationFrame(updateFrame);
|
||||||
@ -72,14 +78,27 @@ export const stopUpdateHandling = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the given callback as a global handler for marker updates
|
||||||
|
* @param {LiveAtlasMarkerUpdateCallback} callback The callback
|
||||||
|
*/
|
||||||
export const registerUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback) => {
|
export const registerUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback) => {
|
||||||
updateHandlers.add(callback);
|
updateHandlers.add(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters the given callback as a global handler for marker updates
|
||||||
|
* @param {LiveAtlasMarkerUpdateCallback} callback The callback
|
||||||
|
*/
|
||||||
export const unregisterUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback) => {
|
export const unregisterUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback) => {
|
||||||
updateHandlers.delete(callback);
|
updateHandlers.delete(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the given callback as a handler for marker updates in the given marker set
|
||||||
|
* @param {LiveAtlasMarkerUpdateCallback} callback The callback
|
||||||
|
* @param {string} set: The marker set id
|
||||||
|
*/
|
||||||
export const registerSetUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback, set: string) => {
|
export const registerSetUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback, set: string) => {
|
||||||
if(!setUpdateHandlers[set]) {
|
if(!setUpdateHandlers[set]) {
|
||||||
setUpdateHandlers[set] = new Set();
|
setUpdateHandlers[set] = new Set();
|
||||||
@ -88,6 +107,11 @@ export const registerSetUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback
|
|||||||
setUpdateHandlers[set].add(callback);
|
setUpdateHandlers[set].add(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters the given callback as a handler for marker updates in the given marker set
|
||||||
|
* @param {LiveAtlasMarkerUpdateCallback} callback The callback
|
||||||
|
* @param {string} set: The marker set id
|
||||||
|
*/
|
||||||
export const unregisterSetUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback, set: string) => {
|
export const unregisterSetUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback, set: string) => {
|
||||||
if(!setUpdateHandlers[set]) {
|
if(!setUpdateHandlers[set]) {
|
||||||
return;
|
return;
|
||||||
@ -96,6 +120,12 @@ export const unregisterSetUpdateHandler = (callback: LiveAtlasMarkerUpdateCallba
|
|||||||
setUpdateHandlers[set].delete(callback);
|
setUpdateHandlers[set].delete(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles pending marker updates, if any exist
|
||||||
|
* Up to 10 updates will be taken from the list and the appropriate registered update handlers will be called
|
||||||
|
* If further updates remain, an animation frame will be scheduled for further calls
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
const handlePendingUpdates = async () => {
|
const handlePendingUpdates = async () => {
|
||||||
const store = useStore(),
|
const store = useStore(),
|
||||||
updates = await store.dispatch(ActionTypes.POP_MARKER_UPDATES, 10);
|
updates = await store.dispatch(ActionTypes.POP_MARKER_UPDATES, 10);
|
||||||
@ -116,6 +146,16 @@ const handlePendingUpdates = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the appropriate type of marker layer for the given {@link LiveAtlasMarker}
|
||||||
|
* @param {LiveAtlasMarker} options Marker options
|
||||||
|
* @param {Function} converter Function for projecting the marker location onto the map
|
||||||
|
* @returns The created layer
|
||||||
|
* @see createPointLayer
|
||||||
|
* @see createAreaLayer
|
||||||
|
* @see createCircleLayer
|
||||||
|
* @see createLineLayer
|
||||||
|
*/
|
||||||
export const createMarkerLayer = (options: LiveAtlasMarker, converter: Function): Layer => {
|
export const createMarkerLayer = (options: LiveAtlasMarker, converter: Function): Layer => {
|
||||||
switch(options.type) {
|
switch(options.type) {
|
||||||
case LiveAtlasMarkerType.POINT:
|
case LiveAtlasMarkerType.POINT:
|
||||||
@ -129,6 +169,17 @@ export const createMarkerLayer = (options: LiveAtlasMarker, converter: Function)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates or creates an appropriate type of marker layer with the given options
|
||||||
|
* @param {?Layer} marker Optional existing marker layer to update
|
||||||
|
* @param {?LiveAtlasMarker} options Marker options
|
||||||
|
* @param {Function} converter Function for projecting the marker location onto the map
|
||||||
|
* @returns The created layer
|
||||||
|
* @see updatePointLayer
|
||||||
|
* @see updateAreaLayer
|
||||||
|
* @see updateCircleLayer
|
||||||
|
* @see updateLineLayer
|
||||||
|
*/
|
||||||
export const updateMarkerLayer = (marker: Layer | undefined, options: LiveAtlasMarker, converter: Function): Layer => {
|
export const updateMarkerLayer = (marker: Layer | undefined, options: LiveAtlasMarker, converter: Function): Layer => {
|
||||||
switch(options.type) {
|
switch(options.type) {
|
||||||
case LiveAtlasMarkerType.POINT:
|
case LiveAtlasMarkerType.POINT:
|
||||||
|
@ -24,11 +24,23 @@ export const tooltipOptions = {
|
|||||||
interactive: false,
|
interactive: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the 2 given arrays of {@link LatLngExpression} are equal by comparing the JSON serialised representations
|
||||||
|
* @param {LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]} oldPoints Points to compare
|
||||||
|
* @param {LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]} newPoints Other points to compare
|
||||||
|
* @return Whether both arrays of points are considered equal
|
||||||
|
*/
|
||||||
export const arePointsEqual = (oldPoints: LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][],
|
export const arePointsEqual = (oldPoints: LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][],
|
||||||
newPoints: LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]) => {
|
newPoints: LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]) => {
|
||||||
return JSON.stringify(oldPoints) === JSON.stringify(newPoints);
|
return JSON.stringify(oldPoints) === JSON.stringify(newPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the 2 given {@link PathOptions} are equal by comapring their properties
|
||||||
|
* @param {PathOptions} oldStyle PathOptions to compare
|
||||||
|
* @param {PathOptions} newStyle Other PathOptions to compare
|
||||||
|
* @return Whether both PathOptions are considered equal
|
||||||
|
*/
|
||||||
export const isStyleEqual = (oldStyle: PathOptions, newStyle: PathOptions) => {
|
export const isStyleEqual = (oldStyle: PathOptions, newStyle: PathOptions) => {
|
||||||
return oldStyle && newStyle
|
return oldStyle && newStyle
|
||||||
&& (oldStyle.color === newStyle.color)
|
&& (oldStyle.color === newStyle.color)
|
||||||
@ -38,6 +50,12 @@ export const isStyleEqual = (oldStyle: PathOptions, newStyle: PathOptions) => {
|
|||||||
&& (oldStyle.fillOpacity === newStyle.fillOpacity)
|
&& (oldStyle.fillOpacity === newStyle.fillOpacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a popup element for the given marker
|
||||||
|
* @param {LiveAtlasPointMarker} options Marker options
|
||||||
|
* @param {string} className Classname to add to the popup element
|
||||||
|
* @returns {HTMLSpanElement} The marker element
|
||||||
|
*/
|
||||||
export const createPopup = (options: LiveAtlasPathMarker, className: string): HTMLElement => {
|
export const createPopup = (options: LiveAtlasPathMarker, className: string): HTMLElement => {
|
||||||
const popup = document.createElement('span');
|
const popup = document.createElement('span');
|
||||||
|
|
||||||
|
@ -14,12 +14,18 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {LeafletMouseEvent, Marker} from "leaflet";
|
import {LeafletMouseEvent} from "leaflet";
|
||||||
import {GenericIcon} from "@/leaflet/icon/GenericIcon";
|
import {GenericIcon} from "@/leaflet/icon/GenericIcon";
|
||||||
import {GenericMarker} from "@/leaflet/marker/GenericMarker";
|
import {GenericMarker} from "@/leaflet/marker/GenericMarker";
|
||||||
import {LiveAtlasPointMarker} from "@/index";
|
import {LiveAtlasPointMarker} from "@/index";
|
||||||
|
|
||||||
export const createPointLayer = (options: LiveAtlasPointMarker, converter: Function): Marker => {
|
/**
|
||||||
|
* Creates a {@link GenericMarker} with the given options
|
||||||
|
* @param {LiveAtlasPointMarker} options Marker options
|
||||||
|
* @param {Function} converter Function for projecting the marker location onto the map
|
||||||
|
* @return The created GenericMarker
|
||||||
|
*/
|
||||||
|
export const createPointLayer = (options: LiveAtlasPointMarker, converter: Function): GenericMarker => {
|
||||||
const marker = new GenericMarker(converter(options.location), options);
|
const marker = new GenericMarker(converter(options.location), options);
|
||||||
|
|
||||||
marker.on('click', (e: LeafletMouseEvent) => {
|
marker.on('click', (e: LeafletMouseEvent) => {
|
||||||
@ -35,7 +41,14 @@ export const createPointLayer = (options: LiveAtlasPointMarker, converter: Funct
|
|||||||
return marker;
|
return marker;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updatePointLayer = (marker: Marker | undefined, options: LiveAtlasPointMarker, converter: Function): Marker => {
|
/**
|
||||||
|
* Updates or creates a {@link GenericMarker} with the given options
|
||||||
|
* @param {?GenericMarker} marker Optional existing GenericMarker to update
|
||||||
|
* @param {LiveAtlasPointMarker} options Marker options
|
||||||
|
* @param {Function} converter Function for projecting the marker location onto the map
|
||||||
|
* @returns The created or updated GenericMarker
|
||||||
|
*/
|
||||||
|
export const updatePointLayer = (marker: GenericMarker | undefined, options: LiveAtlasPointMarker, converter: Function): GenericMarker => {
|
||||||
if (!marker) {
|
if (!marker) {
|
||||||
return createPointLayer(options, converter);
|
return createPointLayer(options, converter);
|
||||||
}
|
}
|
||||||
@ -71,6 +84,12 @@ export const updatePointLayer = (marker: Marker | undefined, options: LiveAtlasP
|
|||||||
return marker;
|
return marker;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a popup element for the given marker
|
||||||
|
* @param {LiveAtlasPointMarker} options Marker options
|
||||||
|
* @returns {HTMLSpanElement} The marker element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
const createPopup = (options: LiveAtlasPointMarker) => {
|
const createPopup = (options: LiveAtlasPointMarker) => {
|
||||||
const popup = document.createElement('span');
|
const popup = document.createElement('span');
|
||||||
|
|
||||||
|
@ -21,6 +21,10 @@ const app = document.getElementById('app'),
|
|||||||
splashErrorMessage = document.getElementById('splash__error-message'),
|
splashErrorMessage = document.getElementById('splash__error-message'),
|
||||||
splashRetry = document.getElementById('splash__error-retry');
|
splashRetry = document.getElementById('splash__error-retry');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the LiveAtlas splash screen, if it isn't already visible
|
||||||
|
* @param reset If true, any existing errors or retry counts will be removed
|
||||||
|
*/
|
||||||
export const showSplash = function(reset: boolean) {
|
export const showSplash = function(reset: boolean) {
|
||||||
if(!splash || !app) {
|
if(!splash || !app) {
|
||||||
return;
|
return;
|
||||||
@ -48,6 +52,10 @@ export const showSplash = function(reset: boolean) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the LiveAtlas splash screen, if it is visible
|
||||||
|
* The splash screen is not fully hidden immediately, as it has a CSS defined fade out animation
|
||||||
|
*/
|
||||||
export const hideSplash = () => {
|
export const hideSplash = () => {
|
||||||
if(!splash || !app) {
|
if(!splash || !app) {
|
||||||
return;
|
return;
|
||||||
@ -63,6 +71,16 @@ export const hideSplash = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the given error message on the splash screen
|
||||||
|
* If the splash screen is not currently visible {@link showSplash} should also be called
|
||||||
|
* @see {@link showSplash}
|
||||||
|
* @param {string} message The error message to display
|
||||||
|
* @param {boolean} fatal If true the loading spinner will be hidden to indicate a fatal error. This does not stop any
|
||||||
|
* ongoing processes the loading indicator was indicating
|
||||||
|
* @param {?number} attempts Optional number of previous retry attempts that occurred before the current error. If
|
||||||
|
* provided this will be displayed after the error message
|
||||||
|
*/
|
||||||
export const showSplashError = (message: string, fatal: boolean, attempts?: number) => {
|
export const showSplashError = (message: string, fatal: boolean, attempts?: number) => {
|
||||||
if(splashError) {
|
if(splashError) {
|
||||||
splashError.setAttribute('aria-hidden', 'false');
|
splashError.setAttribute('aria-hidden', 'false');
|
||||||
|
Loading…
Reference in New Issue
Block a user