Precalculate bounds for path markers

This commit is contained in:
James Lyne 2022-01-16 21:18:48 +00:00
parent 846f894502
commit aaf4ee630d
4 changed files with 92 additions and 40 deletions

18
src/index.d.ts vendored
View File

@ -17,7 +17,14 @@
import {State} from "@/store";
import {DynmapUrlConfig} from "@/dynmap";
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
import {Coords, DoneCallback, InternalTiles, PathOptions, PointTuple, PolylineOptions} from "leaflet";
import {
Coords,
DoneCallback, FitBoundsOptions,
InternalTiles,
PathOptions,
PointTuple,
PolylineOptions
} from "leaflet";
import {CoordinatesControlOptions} from "@/leaflet/control/CoordinatesControl";
import {ClockControlOptions} from "@/leaflet/control/ClockControl";
import {LogoControlOptions} from "@/leaflet/control/LogoControl";
@ -70,6 +77,12 @@ interface LiveAtlasLocation {
world?: string;
}
interface LiveAtlasBounds {
min: Coordinate;
max: Coordinate;
world?: string;
}
interface LiveAtlasGlobalConfig {
servers: Map<string, LiveAtlasServerDefinition>;
messages: LiveAtlasGlobalMessageConfig;
@ -199,6 +212,7 @@ interface LiveAtlasPointMarker extends LiveAtlasMarker {
interface LiveAtlasPathMarker extends LiveAtlasMarker {
style: PathOptions;
bounds: LiveAtlasBounds;
}
interface LiveAtlasLineMarker extends LiveAtlasPathMarker {
@ -210,7 +224,7 @@ interface LiveAtlasLineMarker extends LiveAtlasPathMarker {
interface LiveAtlasAreaMarker extends LiveAtlasLineMarker {
type: LiveAtlasMarkerType.AREA;
outline: boolean;
points: Coordinate[] | Coordinate[][] | Coordinate[][][];
points: Coordinate[] | Coordinate[][];
}
interface LiveAtlasCircleMarker extends LiveAtlasPathMarker {

View File

@ -34,8 +34,9 @@ import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
import {MutationTypes} from "@/store/mutation-types";
import MapProvider from "@/providers/MapProvider";
import {ActionTypes} from "@/store/action-types";
import {getMiddleFromPoints, stripHTML, titleColoursRegex} from "@/util";
import {getBoundsFromPoints, getMiddle, stripHTML, titleColoursRegex} from "@/util";
import {LiveAtlasMarkerType} from "@/util/markers";
import {PointTuple} from "leaflet";
export default class Pl3xmapMapProvider extends MapProvider {
private configurationAbort?: AbortController = undefined;
@ -310,7 +311,7 @@ export default class Pl3xmapMapProvider extends MapProvider {
}
private static buildArea(id: string, area: any): LiveAtlasAreaMarker {
let points = area.points;
let points;
if(area.type === 'rectangle') {
points = [
@ -319,8 +320,12 @@ export default class Pl3xmapMapProvider extends MapProvider {
{x: area.points[1].x, y: 0, z: area.points[1].z},
{x: area.points[1].x, y: 0, z: area.points[0].z},
];
} else {
points = this.addY(area.points);
}
const bounds = getBoundsFromPoints(points);
return {
id,
type: LiveAtlasMarkerType.AREA,
@ -329,13 +334,14 @@ export default class Pl3xmapMapProvider extends MapProvider {
color: area.color || '#3388ff',
weight: area.weight || 3,
opacity: typeof area.opacity !== 'undefined' ? area.opacity : 1,
fill: typeof area.stroke !== 'undefined' ? !!area.stroke : true,
fill: typeof area.fill !== 'undefined' ? !!area.fill : true,
fillColor: area.fillColor || area.color || '#3388ff',
fillOpacity: area.fillOpacity || 0.2,
fillRule: area.fillRule,
},
points,
location: getMiddleFromPoints(area.points),
bounds,
location: getMiddle(bounds),
outline: false,
tooltip: area.tooltip ? stripHTML(area.tooltip) : '',
@ -346,7 +352,8 @@ export default class Pl3xmapMapProvider extends MapProvider {
}
private static buildLine(id: string, line: any): LiveAtlasLineMarker {
const points = this.addY(line.points);
const points = this.addY(line.points),
bounds = getBoundsFromPoints(points);
return {
id,
@ -358,8 +365,8 @@ export default class Pl3xmapMapProvider extends MapProvider {
opacity: typeof line.opacity !== 'undefined' ? line.opacity : 1,
},
points,
location: getMiddleFromPoints(points),
bounds,
location: getMiddle(bounds),
tooltip: line.tooltip ? stripHTML(line.tooltip) : '',
tooltipHTML: line.tooltip,
popup: line.popup,
@ -368,15 +375,22 @@ export default class Pl3xmapMapProvider extends MapProvider {
}
private static buildCircle(id: string, circle: any): LiveAtlasCircleMarker {
return {
id,
type: LiveAtlasMarkerType.CIRCLE,
location: {
const radius = [circle.radiusX || circle.radius || 0, circle.radiusZ || circle.radius || 0] as PointTuple,
location = {
x: circle.center?.x || 0,
y: 0,
z: circle.center?.z || 0,
};
return {
id,
type: LiveAtlasMarkerType.CIRCLE,
location,
radius,
bounds: {
max: {x: location.x + radius[0], y: 0, z: location.z + radius[1] },
min: {x: location.x - radius[0], y: 0, z: location.z - radius[1] },
},
radius: [circle.radiusX || circle.radius || 0, circle.radiusZ || circle.radius || 0],
style: {
stroke: typeof circle.stroke !== 'undefined' ? !!circle.stroke : true,
color: circle.color || '#3388ff',

View File

@ -18,8 +18,8 @@ import {useStore} from "@/store";
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
import {
Coordinate,
HeadQueueEntry,
LiveAtlasGlobalMessageConfig,
HeadQueueEntry, LiveAtlasBounds,
LiveAtlasGlobalMessageConfig, LiveAtlasLocation,
LiveAtlasMessageConfig,
LiveAtlasPlayer,
LiveAtlasPlayerImageSize,
@ -249,29 +249,35 @@ const _getMessages = (messageKeys: any, config: any = {}) => {
return messages as LiveAtlasGlobalMessageConfig;
}
export const getMiddle = (points: number[]) => {
const min = Math.min.apply(this, points),
max = Math.max.apply(this, points);
return min + ((max - min) / 2)
export const getBounds = (x: number[], y: number[], z: number[]): LiveAtlasBounds => {
return {
min: {x: Math.min.apply(null, x), y: Math.min.apply(null, y), z: Math.min.apply(null, z)},
max: {x: Math.max.apply(null, x), y: Math.max.apply(null, y), z: Math.max.apply(null, z)},
};
}
export const getMiddleFromPoints = (points: Coordinate[]): Coordinate => {
const min = {x: points[0].x, y: points[0].y, z: points[0].z},
max = {...min};
export const getBoundsFromPoints = (points: Coordinate[]): LiveAtlasBounds => {
const bounds = {
max: {...points[0]},
min: {...points[0]},
}
for (const point of points) {
min.x = Math.min(min.x, point.x);
max.x = Math.max(min.x, point.x);
min.y = Math.min(min.y, point.y);
max.y = Math.max(min.y, point.y);
min.z = Math.min(min.z, point.z);
max.z = Math.max(min.z, point.z);
bounds.max.x = Math.max(point.x, bounds.max.x);
bounds.max.y = Math.max(point.y, bounds.max.y);
bounds.max.z = Math.max(point.z, bounds.max.z);
bounds.min.x = Math.min(point.x, bounds.min.x);
bounds.min.y = Math.min(point.y, bounds.min.y);
bounds.min.z = Math.min(point.z, bounds.min.z);
}
return bounds;
}
export const getMiddle = (bounds: LiveAtlasBounds): LiveAtlasLocation => {
return {
x: min.x + ((max.x - min.x) / 2),
y: min.y + ((max.y - min.y) / 2),
z: min.z + ((max.z - min.z) / 2),
}
x: bounds.min.x + ((bounds.max.x - bounds.min.x) / 2),
y: bounds.min.y + ((bounds.max.y - bounds.min.y) / 2),
z: bounds.min.z + ((bounds.max.z - bounds.min.z) / 2),
};
}

View File

@ -31,7 +31,7 @@ import {
import {getPoints} from "@/util/areas";
import {
decodeHTMLEntities,
endWorldNameRegex,
endWorldNameRegex, getBounds,
getMiddle,
netherWorldNameRegex,
stripHTML,
@ -346,7 +346,9 @@ export function buildAreas(data: any, list: Map<string, LiveAtlasMarker>): void
export function buildArea(id: string, area: MarkerArea): LiveAtlasAreaMarker {
const x = area.x || [0, 0],
y = [area.ybottom || 0, area.ytop || 0] as [number, number],
z = area.z || [0, 0];
z = area.z || [0, 0],
bounds = getBounds(x, y, z),
location = getMiddle(bounds);
return {
id,
@ -359,7 +361,8 @@ export function buildArea(id: string, area: MarkerArea): LiveAtlasAreaMarker {
fillOpacity: area.fillopacity || 0,
},
outline: !area.fillopacity,
location: {x: getMiddle(x), y: getMiddle(y), z: getMiddle(z)},
bounds,
location,
points: getPoints(x, y, z, !area.fillopacity),
minZoom: typeof area.minzoom !== 'undefined' && area.minzoom > -1 ? area.minzoom : undefined,
maxZoom: typeof area.maxzoom !== 'undefined' && area.maxzoom > -1 ? area.maxzoom : undefined,
@ -387,7 +390,9 @@ export function buildLines(data: any, list: Map<string, LiveAtlasMarker>): void
export function buildLine(id: string, line: MarkerLine): LiveAtlasLineMarker {
const x = line.x || [0, 0],
y = line.y || [0, 0],
z = line.z || [0, 0];
z = line.z || [0, 0],
bounds = getBounds(x, y, z),
location = getMiddle(bounds);
return {
id,
@ -397,7 +402,8 @@ export function buildLine(id: string, line: MarkerLine): LiveAtlasLineMarker {
opacity: line.opacity || 1,
weight: line.weight || 1,
},
location: {x: getMiddle(x), y: getMiddle(y), z: getMiddle(z)},
location,
bounds,
points: getLinePoints(x, y, z),
minZoom: typeof line.minzoom !== 'undefined' && line.minzoom > -1 ? line.minzoom : undefined,
maxZoom: typeof line.maxzoom !== 'undefined' && line.maxzoom > -1 ? line.maxzoom : undefined,
@ -431,6 +437,18 @@ export function buildCircle(id: string, circle: MarkerCircle): LiveAtlasCircleMa
y: circle.y || 0,
z: circle.z || 0,
},
bounds: {
max: {
x: (circle.x || 0) + (circle.xr || 0),
y: circle.y || 0,
z: (circle.z || 0) + (circle.z || 0),
},
min: {
x: (circle.x || 0) - (circle.xr || 0),
y: circle.y || 0,
z: (circle.z || 0) - (circle.z || 0),
}
},
radius: [circle.xr || 0, circle.zr || 0],
style: {
fillColor: circle.fillcolor || '#ff0000',