diff --git a/src/components/map/vector/Areas.vue b/src/components/map/vector/Areas.vue index c7bead8..1becc7a 100644 --- a/src/components/map/vector/Areas.vue +++ b/src/components/map/vector/Areas.vue @@ -19,7 +19,6 @@ import {defineComponent, computed, onMounted, onUnmounted, watch} from "@vue/run import {useStore} from "@/store"; import {ActionTypes} from "@/store/action-types"; import {createArea, updateArea} from "@/util/areas"; -import {getPointConverter} from '@/util'; import LiveAtlasLayerGroup from "@/leaflet/layer/LiveAtlasLayerGroup"; import LiveAtlasPolygon from "@/leaflet/vector/LiveAtlasPolygon"; import LiveAtlasPolyline from "@/leaflet/vector/LiveAtlasPolyline"; @@ -50,7 +49,7 @@ export default defineComponent({ layers = Object.freeze(new Map()) as Map, createAreas = () => { - const converter = getPointConverter(); + const converter = currentMap.value!.locationToLatLng.bind(currentMap.value); props.set.areas.forEach((area: LiveAtlasArea, id: string) => { const layer = createArea(area, converter); @@ -72,18 +71,17 @@ export default defineComponent({ }, handlePendingUpdates = async () => { - const updates = await useStore().dispatch(ActionTypes.POP_AREA_UPDATES, { + const updates = await store.dispatch(ActionTypes.POP_AREA_UPDATES, { markerSet: props.set.id, amount: 10, - }); - - const converter = getPointConverter(); + }), + converter = currentMap.value!.locationToLatLng.bind(currentMap.value); for(const update of updates) { if(update.removed) { deleteArea(update.id); } else { - const layer = updateArea(layers.get(update.id), update.payload as LiveAtlasArea, converter) + const layer = updateArea(layers.get(update.id), update.payload as LiveAtlasArea, converter); if(!layers.has(update.id)) { props.layerGroup.addLayer(layer); @@ -103,7 +101,7 @@ export default defineComponent({ watch(currentMap, (newValue, oldValue) => { if(newValue && (!oldValue || oldValue.world === newValue.world)) { - const converter = getPointConverter(); + const converter = newValue.locationToLatLng.bind(newValue); for (const [id, area] of props.set.areas) { updateArea(layers.get(id), area, converter); diff --git a/src/components/map/vector/Circles.vue b/src/components/map/vector/Circles.vue index a9ce9e2..6cc6c6f 100644 --- a/src/components/map/vector/Circles.vue +++ b/src/components/map/vector/Circles.vue @@ -19,7 +19,6 @@ import {defineComponent, computed, onMounted, onUnmounted, watch} from "@vue/run import {useStore} from "@/store"; import {ActionTypes} from "@/store/action-types"; import {createCircle, updateCircle} from "@/util/circles"; -import {getPointConverter} from '@/util'; import LiveAtlasPolyline from "@/leaflet/vector/LiveAtlasPolyline"; import LiveAtlasPolygon from "@/leaflet/vector/LiveAtlasPolygon"; import LiveAtlasLayerGroup from "@/leaflet/layer/LiveAtlasLayerGroup"; @@ -50,7 +49,7 @@ export default defineComponent({ layers = Object.freeze(new Map()), createCircles = () => { - const converter = getPointConverter(); + const converter = currentMap.value!.locationToLatLng.bind(store.state.currentMap); props.set.circles.forEach((circle: LiveAtlasCircle, id: string) => { const layer = createCircle(circle, converter); @@ -75,9 +74,8 @@ export default defineComponent({ const updates = await useStore().dispatch(ActionTypes.POP_CIRCLE_UPDATES, { markerSet: props.set.id, amount: 10, - }); - - const converter = getPointConverter(); + }), + converter = currentMap.value!.locationToLatLng.bind(store.state.currentMap); for(const update of updates) { if(update.removed) { @@ -103,7 +101,7 @@ export default defineComponent({ watch(currentMap, (newValue, oldValue) => { if(newValue && (!oldValue || oldValue.world === newValue.world)) { - const converter = getPointConverter(); + const converter = currentMap.value!.locationToLatLng.bind(store.state.currentMap); for (const [id, circle] of props.set.circles) { updateCircle(layers.get(id), circle, converter); diff --git a/src/components/map/vector/Lines.vue b/src/components/map/vector/Lines.vue index 6035f22..b78117f 100644 --- a/src/components/map/vector/Lines.vue +++ b/src/components/map/vector/Lines.vue @@ -19,7 +19,6 @@ import {defineComponent, computed, onMounted, onUnmounted, watch} from "@vue/run import {useStore} from "@/store"; import {ActionTypes} from "@/store/action-types"; import {createLine, updateLine} from "@/util/lines"; -import {getPointConverter} from '@/util'; import LiveAtlasPolyline from "@/leaflet/vector/LiveAtlasPolyline"; import LiveAtlasLayerGroup from "@/leaflet/layer/LiveAtlasLayerGroup"; import {LiveAtlasLine, LiveAtlasMarkerSet} from "@/index"; @@ -49,7 +48,7 @@ export default defineComponent({ layers = Object.freeze(new Map()), createLines = () => { - const converter = getPointConverter(); + const converter = currentMap.value!.locationToLatLng.bind(store.state.currentMap); props.set.lines.forEach((line: LiveAtlasLine, id: string) => { const layer = createLine(line, converter); @@ -74,9 +73,8 @@ export default defineComponent({ const updates = await useStore().dispatch(ActionTypes.POP_LINE_UPDATES, { markerSet: props.set.id, amount: 10, - }); - - const converter = getPointConverter(); + }), + converter = currentMap.value!.locationToLatLng.bind(store.state.currentMap); for(const update of updates) { if(update.removed) { @@ -102,7 +100,7 @@ export default defineComponent({ watch(currentMap, (newValue, oldValue) => { if(newValue && (!oldValue || oldValue.world === newValue.world)) { - const converter = getPointConverter(); + const converter = currentMap.value!.locationToLatLng.bind(store.state.currentMap); for (const [id, line] of props.set.lines) { updateLine(layers.get(id), line, converter); diff --git a/src/components/map/vector/Markers.vue b/src/components/map/vector/Markers.vue index abff197..29e4ec1 100644 --- a/src/components/map/vector/Markers.vue +++ b/src/components/map/vector/Markers.vue @@ -21,7 +21,6 @@ import {useStore} from "@/store"; import {ActionTypes} from "@/store/action-types"; import {createMarker, updateMarker} from "@/util/markers"; import LiveAtlasLayerGroup from "@/leaflet/layer/LiveAtlasLayerGroup"; -import {getPointConverter} from "@/util"; import {LiveAtlasMarker, LiveAtlasMarkerSet} from "@/index"; export default defineComponent({ @@ -49,7 +48,7 @@ export default defineComponent({ layers = Object.freeze(new Map()) as Map, createMarkers = () => { - const converter = getPointConverter(); + const converter = currentMap.value!.locationToLatLng.bind(store.state.currentMap); props.set.markers.forEach((marker: LiveAtlasMarker, id: string) => { const layer = createMarker(marker, converter); @@ -74,9 +73,8 @@ export default defineComponent({ const updates = await useStore().dispatch(ActionTypes.POP_MARKER_UPDATES, { markerSet: props.set.id, amount: 10, - }); - - const converter = getPointConverter(); + }), + converter = currentMap.value!.locationToLatLng.bind(store.state.currentMap); for(const update of updates) { if(update.removed) { @@ -102,8 +100,10 @@ export default defineComponent({ watch(currentMap, (newValue, oldValue) => { if(newValue && (!oldValue || oldValue.world === newValue.world)) { + const converter = currentMap.value!.locationToLatLng.bind(store.state.currentMap); + for (const [id, marker] of props.set.markers) { - updateMarker(layers.get(id), marker, getPointConverter()); + updateMarker(layers.get(id), marker, converter); } } }); diff --git a/src/index.d.ts b/src/index.d.ts index ccde558..a1347d0 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -203,33 +203,7 @@ interface LiveAtlasMarker { popupContent?: string; } -interface LiveAtlasArea { - style: PolylineOptions; - label: string; - isHTML: boolean; - x: Array; - y: PointTuple; - z: Array; - minZoom?: number; - maxZoom?: number; - popupContent?: string; -} - -interface LiveAtlasLine { - x: Array; - y: Array; - z: Array; - style: PolylineOptions; - label: string; - isHTML: boolean; - minZoom?: number; - maxZoom?: number; - popupContent?: string; -} - -interface LiveAtlasCircle { - location: Coordinate; - radius: PointTuple; +interface LiveAtlasPath { style: PathOptions; label: string; isHTML: boolean; @@ -238,6 +212,23 @@ interface LiveAtlasCircle { popupContent?: string; } +interface LiveAtlasArea extends LiveAtlasPath { + style: PolylineOptions; + outline: boolean; + points: Coordinate[] | Coordinate[][] | Coordinate[][][] +} + +interface LiveAtlasLine extends LiveAtlasPath { + points: Coordinate[]; + style: PolylineOptions; +} + +interface LiveAtlasCircle extends LiveAtlasPath { + location: Coordinate; + radius: PointTuple; + style: PathOptions; +} + interface HeadQueueEntry { cacheKey: string; name: string; diff --git a/src/providers/DynmapMapProvider.ts b/src/providers/DynmapMapProvider.ts index 917f7e7..e93338b 100644 --- a/src/providers/DynmapMapProvider.ts +++ b/src/providers/DynmapMapProvider.ts @@ -37,6 +37,8 @@ import {MutationTypes} from "@/store/mutation-types"; import MapProvider from "@/providers/MapProvider"; import {ActionTypes} from "@/store/action-types"; import {endWorldNameRegex, netherWorldNameRegex, titleColoursRegex} from "@/util"; +import {getPoints} from "@/util/areas"; +import {getLinePoints} from "@/util/lines"; export default class DynmapMapProvider extends MapProvider { private configurationAbort?: AbortController = undefined; @@ -307,6 +309,11 @@ export default class DynmapMapProvider extends MapProvider { } private static buildArea(area: any): LiveAtlasArea { + const opacity = area.fillopacity || 0, + x = area.x || [0, 0], + y: [number, number] = [area.ybottom || 0, area.ytop || 0], + z = area.z || [0, 0]; + return { style: { color: area.color || '#ff0000', @@ -315,11 +322,10 @@ export default class DynmapMapProvider extends MapProvider { fillColor: area.fillcolor || '#ff0000', fillOpacity: area.fillopacity || 0, }, + outline: !opacity, label: area.label || '', isHTML: area.markup || false, - x: area.x || [0, 0], - y: [area.ybottom || 0, area.ytop || 0], - z: area.z || [0, 0], + points: getPoints(x, y, z, !opacity), minZoom: typeof area.minzoom !== 'undefined' && area.minzoom > -1 ? area.minzoom : undefined, maxZoom: typeof area.maxzoom !== 'undefined' && area.maxzoom > -1 ? area.maxzoom : undefined, popupContent: area.desc || undefined, @@ -342,9 +348,6 @@ export default class DynmapMapProvider extends MapProvider { private static buildLine(line: any): LiveAtlasLine { return { - x: line.x || [0, 0], - y: line.y || [0, 0], - z: line.z || [0, 0], style: { color: line.color || '#ff0000', opacity: line.opacity || 1, @@ -352,6 +355,7 @@ export default class DynmapMapProvider extends MapProvider { }, label: line.label || '', isHTML: line.markup || false, + points: getLinePoints(line.x || [0, 0], line.y || [0, 0], line.z || [0, 0]), minZoom: typeof line.minzoom !== 'undefined' && line.minzoom > -1 ? line.minzoom : undefined, maxZoom: typeof line.maxzoom !== 'undefined' && line.maxzoom > -1 ? line.maxzoom : undefined, popupContent: line.desc || undefined, diff --git a/src/util.ts b/src/util.ts index ebe63b7..8b8649f 100644 --- a/src/util.ts +++ b/src/util.ts @@ -103,20 +103,6 @@ const tickHeadQueue = () => { tickHeadQueue(); } -export const getPointConverter = () => { - const map = useStore().state.currentMap; - - if(map) { - return (x: number, y: number, z: number) => { - return map.locationToLatLng({x, y, z}); - }; - } else { - return (x: number, y: number, z: number) => { - return LiveAtlasMapDefinition.defaultProjection.locationToLatLng({x, y, z}); - }; - } -} - export const parseUrl = () => { const query = new URLSearchParams(window.location.search), hash = window.location.hash.replace('#', ''); diff --git a/src/util/areas.ts b/src/util/areas.ts index a6f4b9f..515dcb5 100644 --- a/src/util/areas.ts +++ b/src/util/areas.ts @@ -20,11 +20,11 @@ import {LatLngExpression} from "leaflet"; import LiveAtlasPolyline from "@/leaflet/vector/LiveAtlasPolyline"; import LiveAtlasPolygon from "@/leaflet/vector/LiveAtlasPolygon"; -import {LiveAtlasArea} from "@/index"; +import {Coordinate, LiveAtlasArea} from "@/index"; export const createArea = (options: LiveAtlasArea, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => { const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0), - points = getPoints(options, converter, outline), + points = options.points.map(projectPointsMapCallback, converter) as LatLngExpression[] | LatLngExpression[][], area = outline ? new LiveAtlasPolyline(points, { ...options.style, minZoom: options.minZoom, @@ -43,14 +43,13 @@ export const createArea = (options: LiveAtlasArea, converter: Function): LiveAtl }; export const updateArea = (area: LiveAtlasPolyline | LiveAtlasPolygon | undefined, options: LiveAtlasArea, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => { - const outline = !options.style || !options.style.fillOpacity || (options.style.fillOpacity <= 0) as boolean, - points = getPoints(options, converter, outline); - if (!area) { return createArea(options, converter); } - const oldPoints = area.getLatLngs(); + const points = options.points.map(projectPointsMapCallback, converter) as LatLngExpression[] | LatLngExpression[][], + oldPoints = area.getLatLngs(); + let dirty = false; //Avoid pointless setStyle() redrawing by checking if styles have actually changed @@ -104,120 +103,129 @@ export const createPopup = (options: LiveAtlasArea): HTMLElement => { return popup; }; -export const getPoints = (options: LiveAtlasArea, converter: Function, outline: boolean): LatLngExpression[] | LatLngExpression[][] => { - if (options.x.length === 2) { /* Only 2 points */ - if (options.y[0] === options.y[1]) { - return get2DBoxPoints(options, converter, outline); +const projectPointsMapCallback = function(this: Function, point: Coordinate | Coordinate[] | Coordinate[][]): LatLngExpression | LatLngExpression[] { + if(Array.isArray(point)) { + return point.map(projectPointsMapCallback, this) as LatLngExpression[]; + } else { + // @ts-ignore + return this(point); + } +}; + +export const getPoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] | Coordinate[][] => { + if (x.length === 2) { /* Only 2 points */ + if (y[0] === y[1]) { + return get2DBoxPoints(x, y, z, outline); } else { - return get3DBoxPoints(options, converter); + return get3DBoxPoints(x, y, z); } } else { - if (options.y[0] === options.y[1]) { - return get2DShapePoints(options, converter, outline); + if (y[0] === y[1]) { + return get2DShapePoints(x, y, z, outline); } else { - return get3DShapePoints(options, converter); + return get3DShapePoints(x, y, z); } } }; -export const get3DBoxPoints = (options: LiveAtlasArea, converter: Function): LatLngExpression[][] => { - const maxX = options.x[0], - minX = options.x[1], - maxY = options.y[0], - minY = options.y[1], - maxZ = options.z[0], - minZ = options.z[1]; +export const get3DBoxPoints = (x: number[], y: [number, number], z: number[]): Coordinate[][] => { + const maxX = x[0], + minX = x[1], + maxY = y[0], + minY = y[1], + maxZ = z[0], + minZ = z[1]; return [ [ - converter(minX, minY, minZ), - converter(maxX, minY, minZ), - converter(maxX, minY, maxZ), - converter(minX, minY, maxZ) + {x: minX, y: minY, z: minZ}, + {x: maxX, y: minY, z: minZ}, + {x: maxX, y: minY, z: maxZ}, + {x: minX, y: minY, z: maxZ} ], [ - converter(minX, maxY, minZ), - converter(maxX, maxY, minZ), - converter(maxX, maxY, maxZ), - converter(minX, maxY, maxZ) + {x: minX, y: maxY, z: minZ}, + {x: maxX, y: maxY, z: minZ}, + {x: maxX, y: maxY, z: maxZ}, + {x: minX, y: maxY, z: maxZ} ], [ - converter(minX, minY, minZ), - converter(minX, maxY, minZ), - converter(maxX, maxY, minZ), - converter(maxX, minY, minZ) + {x: minX, y: minY, z: minZ}, + {x: minX, y: maxY, z: minZ}, + {x: maxX, y: maxY, z: minZ}, + {x: maxX, y: minY, z: minZ} ], [ - converter(maxX, minY, minZ), - converter(maxX, maxY, minZ), - converter(maxX, maxY, maxZ), - converter(maxX, minY, maxZ) + {x: maxX, y: minY, z: minZ}, + {x: maxX, y: maxY, z: minZ}, + {x: maxX, y: maxY, z: maxZ}, + {x: maxX, y: minY, z: maxZ} ], [ - converter(minX, minY, maxZ), - converter(minX, maxY, maxZ), - converter(maxX, maxY, maxZ), - converter(maxX, minY, maxZ) + {x: minX, y: minY, z: maxZ}, + {x: minX, y: maxY, z: maxZ}, + {x: maxX, y: maxY, z: maxZ}, + {x: maxX, y: minY, z: maxZ} ], [ - converter(minX, minY, minZ), - converter(minX, maxY, minZ), - converter(minX, maxY, maxZ), - converter(minX, minY, maxZ) + {x: minX, y: minY, z: minZ}, + {x: minX, y: maxY, z: minZ}, + {x: minX, y: maxY, z: maxZ}, + {x: minX, y: minY, z: maxZ} ] ]; }; -export const get2DBoxPoints = (options: LiveAtlasArea, converter: Function, outline: boolean): LatLngExpression[] => { - const maxX = options.x[0], - minX = options.x[1], - minY = options.y[1], - maxZ = options.z[0], - minZ = options.z[1]; +export const get2DBoxPoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] => { + const maxX = x[0], + minX = x[1], + minY = y[1], + maxZ = z[0], + minZ = z[1]; if (outline) { return [ - converter(minX, minY, minZ), - converter(maxX, minY, minZ), - converter(maxX, minY, maxZ), - converter(minX, minY, maxZ), - converter(minX, minY, minZ) + {x: minX, y: minY, z: minZ}, + {x: maxX, y: minY, z: minZ}, + {x: maxX, y: minY, z: maxZ}, + {x: minX, y: minY, z: maxZ}, + {x: minX, y: minY, z: minZ} ]; } else { return [ - converter(minX, minY, minZ), - converter(maxX, minY, minZ), - converter(maxX, minY, maxZ), - converter(minX, minY, maxZ) + {x: minX, y: minY, z: minZ}, + {x: maxX, y: minY, z: minZ}, + {x: maxX, y: minY, z: maxZ}, + {x: minX, y: minY, z: maxZ} ]; } }; -export const get3DShapePoints = (options: LiveAtlasArea, converter: Function): LatLngExpression[][] => { +export const get3DShapePoints = (x: number[], y: [number, number], z: number[]): Coordinate[][] => { const toplist = [], botlist = [], polylist = []; - for (let i = 0; i < options.x.length; i++) { - toplist[i] = converter(options.x[i], options.y[0], options.z[i]); - botlist[i] = converter(options.x[i], options.y[1], options.z[i]); + for (let i = 0; i < x.length; i++) { + toplist[i] = {x: x[i], y: y[0], z: z[i]}; + botlist[i] = {x: x[i], y: y[1], z: z[i]}; } - for (let i = 0; i < options.x.length; i++) { - const sidelist = []; - sidelist[0] = toplist[i]; - sidelist[1] = botlist[i]; - sidelist[2] = botlist[(i + 1) % options.x.length]; - sidelist[3] = toplist[(i + 1) % options.x.length]; - polylist[i] = sidelist; + for (let i = 0; i < x.length; i++) { + polylist[i] = [ + toplist[i], + botlist[i], + botlist[(i + 1) % x.length], + toplist[(i + 1) % x.length], + ]; } - polylist[options.x.length] = botlist; - polylist[options.x.length + 1] = toplist; + polylist[x.length] = botlist; + polylist[x.length + 1] = toplist; return polylist; }; -export const get2DShapePoints = (options: LiveAtlasArea, converter: Function, outline: boolean): LatLngExpression[] => { +export const get2DShapePoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] => { const points = []; - for (let i = 0; i < options.x.length; i++) { - points[i] = converter(options.x[i], options.y[1], options.z[i]); + for (let i = 0; i < x.length; i++) { + points[i] = {x: x[i], y: y[1], z: z[i]}; } if (outline) { @@ -225,4 +233,4 @@ export const get2DShapePoints = (options: LiveAtlasArea, converter: Function, ou } return points; -} +}; diff --git a/src/util/circles.ts b/src/util/circles.ts index 08a717d..8388fd7 100644 --- a/src/util/circles.ts +++ b/src/util/circles.ts @@ -84,7 +84,7 @@ export const getCirclePoints = (options: LiveAtlasCircle, converter: Function, o x = options.radius[0] * Math.sin(rad) + options.location.x, z = options.radius[1] * Math.cos(rad) + options.location.z; - points.push(converter(x, options.location.y, z)); + points.push(converter({x, y:options.location.y, z})); } if(outline && points.length) { diff --git a/src/util/lines.ts b/src/util/lines.ts index 31c135f..0aefb3d 100644 --- a/src/util/lines.ts +++ b/src/util/lines.ts @@ -17,12 +17,12 @@ * limitations under the License. */ -import {LatLngExpression} from "leaflet"; import LiveAtlasPolyline from "@/leaflet/vector/LiveAtlasPolyline"; -import {LiveAtlasLine} from "@/index"; +import {Coordinate, LiveAtlasLine} from "@/index"; +import {LatLngExpression} from "leaflet"; export const createLine = (options: LiveAtlasLine, converter: Function): LiveAtlasPolyline => { - const points = getLinePoints(options, converter), + const points = options.points.map(projectPointsMapCallback, converter) as LatLngExpression[], line = new LiveAtlasPolyline(points, { ...options.style, minZoom: options.minZoom, @@ -37,7 +37,7 @@ export const createLine = (options: LiveAtlasLine, converter: Function): LiveAtl }; export const updateLine = (line: LiveAtlasPolyline | undefined, options: LiveAtlasLine, converter: Function): LiveAtlasPolyline => { - const points = getLinePoints(options, converter); + const points = options.points.map(projectPointsMapCallback, converter); if (!line) { return createLine(options, converter); @@ -53,6 +53,15 @@ export const updateLine = (line: LiveAtlasPolyline | undefined, options: LiveAtl return line; } +const projectPointsMapCallback = function(point: Coordinate): LatLngExpression { + if(Array.isArray(point)) { + return projectPointsMapCallback(point); + } else { + // @ts-ignore + return this(point); + } +}; + export const createPopup = (options: LiveAtlasLine) => { const popup = document.createElement('span'); @@ -69,11 +78,11 @@ export const createPopup = (options: LiveAtlasLine) => { return popup; } -export const getLinePoints = (options: LiveAtlasLine, converter: Function): LatLngExpression[] => { +export const getLinePoints = (x: number[], y: number[], z: number[]): Coordinate[] => { const points = []; - for(let i = 0; i < options.x.length; i++) { - points.push(converter(options.x[i], options.y[i], options.z[i])); + for(let i = 0; i < x.length; i++) { + points.push({x: x[i], y: y[i], z: z[i]}); } return points; diff --git a/src/util/markers.ts b/src/util/markers.ts index adc6235..553966a 100644 --- a/src/util/markers.ts +++ b/src/util/markers.ts @@ -23,7 +23,7 @@ import {GenericMarker} from "@/leaflet/marker/GenericMarker"; import {LiveAtlasMarker} from "@/index"; export const createMarker = (options: LiveAtlasMarker, converter: Function): Marker => { - const marker = new GenericMarker(converter(options.location.x, options.location.y, options.location.z), { + const marker = new GenericMarker(converter(options.location), { icon: new GenericIcon({ icon: options.icon, label: options.label, @@ -51,7 +51,7 @@ export const updateMarker = (marker: Marker | undefined, options: LiveAtlasMarke } const oldLocation = marker.getLatLng(), - newLocation = converter(options.location.x, options.location.y, options.location.z); + newLocation = converter(options.location); if(!oldLocation.equals(newLocation)) { marker.setLatLng(newLocation);