mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
feat: Aligned orbits representation, added visibility option
This commit is contained in:
parent
c7ff73f8a6
commit
8aac6b7d7e
@ -22,9 +22,9 @@
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:zoom="8.9824657"
|
||||
inkscape:cx="20.985329"
|
||||
inkscape:cy="21.430641"
|
||||
inkscape:zoom="12.703125"
|
||||
inkscape:cx="27.316114"
|
||||
inkscape:cy="18.145142"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1009"
|
||||
inkscape:window-x="1912"
|
||||
@ -33,7 +33,8 @@
|
||||
inkscape:current-layer="svg1" />
|
||||
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M 23.307123,3.5189202 C 22.873778,2.4788845 21.852318,1.8041019 20.725614,1.8041019 c -1.126705,0 -2.14817,0.6747826 -2.581515,1.7148183 L 5.2674896,34.22469 c -0.5200196,1.238134 -0.086679,2.661992 1.0214597,3.411065 1.1081335,0.749072 2.5938946,0.600492 3.5410687,-0.346667 L 20.725614,26.393493 31.621209,37.289088 c 0.947171,0.947172 2.426747,1.089559 3.541067,0.346667 1.114324,-0.742886 1.541478,-2.172931 1.021461,-3.411065 z"
|
||||
d="M 23.307123,5.9592647 C 22.873778,4.919229 21.852318,4.2444464 20.725614,4.2444464 c -1.126705,0 -2.14817,0.6747826 -2.581515,1.7148183 L 4.9526064,31.075858 c -0.5200196,1.238134 -0.749486,3.365412 1.6615957,3.411065 3.2949087,0.06239 25.7802099,-0.167747 27.4538949,0 1.605575,0.16092 2.511915,-2.077361 1.800757,-3.411065 z"
|
||||
id="path1"
|
||||
style="stroke:#262626;stroke-width:2.30583;stroke-dasharray:none;stroke-opacity:1" />
|
||||
style="stroke:none;stroke-width:2.30583;stroke-dasharray:none;stroke-opacity:1"
|
||||
sodipodi:nodetypes="csccsscc" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.6 KiB |
@ -403,6 +403,7 @@ export const MAP_OPTIONS_DEFAULTS: MapOptions = {
|
||||
showUnitLabels: true,
|
||||
showUnitsEngagementRings: true,
|
||||
showUnitsAcquisitionRings: true,
|
||||
showRacetracks: true,
|
||||
fillSelectedRing: false,
|
||||
showMinimap: false,
|
||||
protectDCSUnits: true,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { DivIcon, LatLng } from "leaflet";
|
||||
import { CustomMarker } from "../markers/custommarker";
|
||||
|
||||
export class CoalitionAreaHandle extends CustomMarker {
|
||||
export class DraggableHandle extends CustomMarker {
|
||||
constructor(latlng: LatLng) {
|
||||
super(latlng, { interactive: true, draggable: true });
|
||||
|
||||
@ -15,11 +15,11 @@ export class CoalitionAreaHandle extends CustomMarker {
|
||||
new DivIcon({
|
||||
iconSize: [24, 24],
|
||||
iconAnchor: [12, 12],
|
||||
className: "leaflet-coalitionarea-handle-marker",
|
||||
className: "leaflet-draggable-handle-marker",
|
||||
})
|
||||
);
|
||||
var el = document.createElement("div");
|
||||
el.classList.add("ol-coalitionarea-handle-icon");
|
||||
el.classList.add("ol-draggable-handle-icon");
|
||||
this.getElement()?.appendChild(el);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { LatLngExpression, Map, Circle, DivIcon, Marker, CircleOptions, LatLng } from "leaflet";
|
||||
import { getApp } from "../../olympusapp";
|
||||
import { CoalitionAreaHandle } from "./coalitionareahandle";
|
||||
import { DraggableHandle } from "./coalitionareahandle";
|
||||
import { BLUE_COMMANDER, colors, RED_COMMANDER } from "../../constants/constants";
|
||||
import { Coalition } from "../../types/types";
|
||||
import * as turf from "@turf/turf";
|
||||
@ -12,7 +12,7 @@ export class CoalitionCircle extends Circle {
|
||||
#coalition: Coalition = "blue";
|
||||
#selected: boolean = true;
|
||||
#creating: boolean = false;
|
||||
#radiusHandle: CoalitionAreaHandle;
|
||||
#radiusHandle: DraggableHandle;
|
||||
#labelText: string;
|
||||
#label: Marker;
|
||||
#updateTimeout: number | null = null;
|
||||
@ -140,7 +140,7 @@ export class CoalitionCircle extends Circle {
|
||||
|
||||
if (this.#selected) {
|
||||
const dest = turf.destination(turf.point([this.getLatLng().lng, this.getLatLng().lat]), this.getRadius() / 1000, 0);
|
||||
this.#radiusHandle = new CoalitionAreaHandle(new LatLng(dest.geometry.coordinates[1], dest.geometry.coordinates[0]));
|
||||
this.#radiusHandle = new DraggableHandle(new LatLng(dest.geometry.coordinates[1], dest.geometry.coordinates[0]));
|
||||
this.#radiusHandle.addTo(getApp().getMap());
|
||||
this.#radiusHandle.on("drag", (e: any) => {
|
||||
this.setRadius(this.getLatLng().distanceTo(e.latlng));
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { LatLng, LatLngExpression, Map, Point, Polygon, PolylineOptions, DivIcon, Marker } from "leaflet";
|
||||
import { getApp } from "../../olympusapp";
|
||||
import { CoalitionAreaHandle } from "./coalitionareahandle";
|
||||
import { DraggableHandle } from "./coalitionareahandle";
|
||||
import { CoalitionAreaMiddleHandle } from "./coalitionareamiddlehandle";
|
||||
import { BLUE_COMMANDER, colors, RED_COMMANDER } from "../../constants/constants";
|
||||
import { Coalition } from "../../types/types";
|
||||
@ -13,7 +13,7 @@ export class CoalitionPolygon extends Polygon {
|
||||
#coalition: Coalition = "blue";
|
||||
#selected: boolean = true;
|
||||
#creating: boolean = false;
|
||||
#handles: CoalitionAreaHandle[] = [];
|
||||
#handles: DraggableHandle[] = [];
|
||||
#middleHandles: CoalitionAreaMiddleHandle[] = [];
|
||||
#activeIndex: number = 0;
|
||||
#labelText: string;
|
||||
@ -132,7 +132,7 @@ export class CoalitionPolygon extends Polygon {
|
||||
onRemove(map: Map): this {
|
||||
super.onRemove(map);
|
||||
this.#label?.removeFrom(map);
|
||||
this.#handles.concat(this.#middleHandles).forEach((handle: CoalitionAreaHandle | CoalitionAreaMiddleHandle) => handle.removeFrom(map));
|
||||
this.#handles.concat(this.#middleHandles).forEach((handle: DraggableHandle | CoalitionAreaMiddleHandle) => handle.removeFrom(map));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -161,13 +161,13 @@ export class CoalitionPolygon extends Polygon {
|
||||
}
|
||||
|
||||
#setHandles() {
|
||||
this.#handles.forEach((handle: CoalitionAreaHandle) => handle.removeFrom(getApp().getMap()));
|
||||
this.#handles.forEach((handle: DraggableHandle) => handle.removeFrom(getApp().getMap()));
|
||||
this.#handles = [];
|
||||
if (this.getSelected()) {
|
||||
var latlngs = this.getLatLngs()[0] as LatLng[];
|
||||
latlngs.forEach((latlng: LatLng, idx: number) => {
|
||||
/* Add the polygon vertex handle (for moving the vertex) */
|
||||
const handle = new CoalitionAreaHandle(latlng);
|
||||
const handle = new DraggableHandle(latlng);
|
||||
handle.addTo(getApp().getMap());
|
||||
handle.on("drag", (e: any) => {
|
||||
var latlngs = this.getLatLngs()[0] as LatLng[];
|
||||
|
||||
@ -100,20 +100,26 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.ol-coalitionarea-handle-icon {
|
||||
cursor: url("/images/cursors/pointer.svg") 13 5, auto;
|
||||
background-color: #FFFFFFAA;
|
||||
.ol-draggable-handle-icon {
|
||||
cursor:
|
||||
url("/images/cursors/pointer.svg") 13 5,
|
||||
auto;
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
|
||||
.ol-coalitionarea-middle-handle-icon {
|
||||
cursor: url("/images/cursors/pointer.svg") 13 5, auto;
|
||||
background-color: #FFFFFFAA;
|
||||
cursor:
|
||||
url("/images/cursors/pointer.svg") 13 5,
|
||||
auto;
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
|
||||
.ol-coalitionarea-label {
|
||||
@ -124,7 +130,11 @@
|
||||
.ol-coalitionarea-label.selected {
|
||||
color: white;
|
||||
/* 1 pixel black shadow to left, top, right and bottom */
|
||||
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
|
||||
text-shadow:
|
||||
-1px 0 black,
|
||||
0 1px black,
|
||||
1px 0 black,
|
||||
0 -1px black;
|
||||
}
|
||||
|
||||
.ol-coalitionarea-label.blue {
|
||||
@ -139,15 +149,15 @@
|
||||
background-image: url("/images/markers/target.svg");
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
filter: drop-shadow( 3px 3px 3px rgba(0, 0, 0, .2));
|
||||
|
||||
filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
|
||||
.ol-spot-icon {
|
||||
background-image: url("/images/markers/target.svg");
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
filter: drop-shadow( 3px 3px 3px rgba(0, 0, 0, .2));
|
||||
filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
|
||||
.ol-text-icon {
|
||||
@ -162,10 +172,10 @@
|
||||
|
||||
.ol-smoke-icon {
|
||||
opacity: 75%;
|
||||
filter: drop-shadow( 3px 3px 3px rgba(0, 0, 0, .2));
|
||||
filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
|
||||
.ol-explosion-icon * {
|
||||
.ol-explosion-icon * {
|
||||
opacity: 75%;
|
||||
}
|
||||
|
||||
@ -185,7 +195,9 @@ path.leaflet-interactive:focus {
|
||||
cursor: url("/images/cursors/follow.svg"), auto !important;
|
||||
}
|
||||
|
||||
.fire-at-area-cursor, .bomb-cursor, .carpet-bomb-cursor {
|
||||
.fire-at-area-cursor,
|
||||
.bomb-cursor,
|
||||
.carpet-bomb-cursor {
|
||||
cursor: url("/images/cursors/fire-at-area.svg"), auto !important;
|
||||
}
|
||||
|
||||
@ -213,9 +225,10 @@ path.leaflet-interactive:focus {
|
||||
cursor: url("/images/cursors/measure.svg"), auto !important;
|
||||
}
|
||||
|
||||
|
||||
#map-container.leaflet-grab {
|
||||
cursor: url("/images/cursors/grab.svg") 16 16, auto;
|
||||
cursor:
|
||||
url("/images/cursors/grab.svg") 16 16,
|
||||
auto;
|
||||
}
|
||||
|
||||
.explosion-cursor {
|
||||
@ -247,7 +260,13 @@ path.leaflet-interactive:focus {
|
||||
}
|
||||
|
||||
.pointer-cursor {
|
||||
cursor: url("/images/cursors/pointer.svg") 13 5, auto !important;
|
||||
cursor:
|
||||
url("/images/cursors/pointer.svg") 13 5,
|
||||
auto !important;
|
||||
}
|
||||
|
||||
.ol-arrow-icon {
|
||||
filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
|
||||
.ol-arrow-icon svg {
|
||||
@ -256,6 +275,5 @@ path.leaflet-interactive:focus {
|
||||
}
|
||||
|
||||
.ol-arrow-icon svg path {
|
||||
fill: #FFFFFFAA;
|
||||
|
||||
fill: #ffffff;
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ export type MapOptions = {
|
||||
showUnitLabels: boolean;
|
||||
showUnitsEngagementRings: boolean;
|
||||
showUnitsAcquisitionRings: boolean;
|
||||
showRacetracks: boolean;
|
||||
fillSelectedRing: boolean;
|
||||
showMinimap: boolean;
|
||||
protectDCSUnits: boolean;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { OlRoundStateButton, OlStateButton, OlLockStateButton } from "../components/olstatebutton";
|
||||
import { faSkull, faCamera, faFlag, faVolumeHigh, faDownload, faUpload, faDrawPolygon } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faSkull, faCamera, faFlag, faVolumeHigh, faDownload, faUpload, faDrawPolygon, faCircle, faTriangleExclamation, faWifi, faHourglass, faInfo } from "@fortawesome/free-solid-svg-icons";
|
||||
import { OlDropdownItem, OlDropdown } from "../components/oldropdown";
|
||||
import { OlLabelToggle } from "../components/ollabeltoggle";
|
||||
import { getApp, IP } from "../../olympusapp";
|
||||
@ -146,17 +146,13 @@ export function Header() {
|
||||
}}
|
||||
checked={false}
|
||||
/>
|
||||
{savingSessionData ? (
|
||||
{savingSessionData ? (
|
||||
<div className="text-white">
|
||||
<FaSpinner
|
||||
className={`animate-spin text-2xl`}
|
||||
/>
|
||||
<FaSpinner className={`animate-spin text-2xl`} />
|
||||
</div>
|
||||
) : (
|
||||
<div className={`relative text-white`}>
|
||||
<FaFloppyDisk
|
||||
className={`absolute -top-3 text-2xl`}
|
||||
/>
|
||||
<FaFloppyDisk className={`absolute -top-3 text-2xl`} />
|
||||
<FaCheck
|
||||
className={`
|
||||
absolute left-[9px] top-[-6px] text-2xl text-olympus-900
|
||||
@ -271,6 +267,23 @@ export function Header() {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className={`h-8 w-0 border-l-[2px] border-gray-700`}></div>
|
||||
<div className={`flex h-fit flex-row items-center justify-start gap-1`}>
|
||||
<OlRoundStateButton
|
||||
onClick={() => getApp().getMap().setOption("showUnitsEngagementRings", !mapOptions.showUnitsEngagementRings)}
|
||||
checked={mapOptions.showUnitsEngagementRings}
|
||||
icon={faTriangleExclamation}
|
||||
className={""}
|
||||
tooltip={"Hide/show units engagement rings"}
|
||||
/>
|
||||
<OlRoundStateButton
|
||||
onClick={() => getApp().getMap().setOption("showUnitsAcquisitionRings", !mapOptions.showUnitsAcquisitionRings)}
|
||||
checked={mapOptions.showUnitsAcquisitionRings}
|
||||
icon={faWifi}
|
||||
className={""}
|
||||
tooltip={"Hide/show units acquisition rings"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<OlLabelToggle
|
||||
toggled={mapOptions.cameraPluginMode === "map"}
|
||||
|
||||
@ -11,6 +11,7 @@ import { Shortcut } from "../../shortcut/shortcut";
|
||||
import { OlSearchBar } from "../components/olsearchbar";
|
||||
import { FaTrash, FaXmark } from "react-icons/fa6";
|
||||
import { OlCoalitionToggle } from "../components/olcoalitiontoggle";
|
||||
import { FaQuestionCircle } from "react-icons/fa";
|
||||
|
||||
const enum Accordion {
|
||||
NONE,
|
||||
@ -92,7 +93,7 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
|
||||
onClick={() => getApp().getMap().setOption("showUnitLabels", !mapOptions.showUnitLabels)}
|
||||
>
|
||||
<OlCheckbox checked={mapOptions.showUnitLabels} onChange={() => {}}></OlCheckbox>
|
||||
<span className="my-auto">Show Unit Labels</span>
|
||||
<span className="my-auto">Show unit labels</span>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
@ -103,7 +104,7 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
|
||||
onClick={() => getApp().getMap().setOption("showUnitsEngagementRings", !mapOptions.showUnitsEngagementRings)}
|
||||
>
|
||||
<OlCheckbox checked={mapOptions.showUnitsEngagementRings} onChange={() => {}}></OlCheckbox>
|
||||
<span className="my-auto">Show Threat Rings</span>
|
||||
<span className="my-auto">Show threat rings</span>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
@ -114,7 +115,7 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
|
||||
onClick={() => getApp().getMap().setOption("showUnitsAcquisitionRings", !mapOptions.showUnitsAcquisitionRings)}
|
||||
>
|
||||
<OlCheckbox checked={mapOptions.showUnitsAcquisitionRings} onChange={() => {}}></OlCheckbox>
|
||||
<span className="my-auto">Show Detection rings</span>
|
||||
<span className="my-auto">Show detection rings</span>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
@ -125,7 +126,7 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
|
||||
onClick={() => getApp().getMap().setOption("showUnitTargets", !mapOptions.showUnitTargets)}
|
||||
>
|
||||
<OlCheckbox checked={mapOptions.showUnitTargets} onChange={() => {}}></OlCheckbox>
|
||||
<span className="my-auto">Show Detection lines</span>
|
||||
<span className="my-auto">Show detection lines</span>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
@ -136,7 +137,7 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
|
||||
onClick={() => getApp().getMap().setOption("hideUnitsShortRangeRings", !mapOptions.hideUnitsShortRangeRings)}
|
||||
>
|
||||
<OlCheckbox checked={mapOptions.hideUnitsShortRangeRings} onChange={() => {}}></OlCheckbox>
|
||||
<span className="my-auto">Hide Short range Rings</span>
|
||||
<span className="my-auto">Hide short range rings</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
@ -148,7 +149,7 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
|
||||
onClick={() => getApp().getMap().setOption("hideGroupMembers", !mapOptions.hideGroupMembers)}
|
||||
>
|
||||
<OlCheckbox checked={mapOptions.hideGroupMembers} onChange={() => {}}></OlCheckbox>
|
||||
<span className="my-auto">Hide Group members</span>
|
||||
<span className="my-auto">Hide group members</span>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
@ -161,6 +162,17 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
|
||||
<OlCheckbox checked={mapOptions.showMinimap} onChange={() => {}}></OlCheckbox>
|
||||
<span className="my-auto">Show minimap</span>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
group flex cursor-pointer flex-row content-center justify-start
|
||||
gap-4 rounded-md p-2
|
||||
dark:hover:bg-olympus-400
|
||||
`}
|
||||
onClick={() => getApp().getMap().setOption("showRacetracks", !mapOptions.showRacetracks)}
|
||||
>
|
||||
<OlCheckbox checked={mapOptions.showRacetracks} onChange={() => {}}></OlCheckbox>
|
||||
<span className="my-auto">Show racetracks</span>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
group flex cursor-pointer flex-row content-center justify-start
|
||||
@ -173,8 +185,20 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
|
||||
mapOptions.AWACSCoalition === "red" && getApp().getMap().setOption("AWACSCoalition", "blue");
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex content-center gap-4">
|
||||
<OlCoalitionToggle onClick={() => {}} coalition={mapOptions.AWACSCoalition} />
|
||||
<span className="my-auto">Coalition of unit bullseye info</span>
|
||||
</div>
|
||||
<div className="flex gap-1 text-sm text-gray-400">
|
||||
<FaQuestionCircle className={`my-auto w-8`} />{" "}
|
||||
<div
|
||||
className={`my-auto ml-2`}
|
||||
>
|
||||
Change the coalition of the bullseye to use to provide bullseye information in the unit tooltip.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</OlAccordion>
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ import {
|
||||
UnitSelectedEvent,
|
||||
UnitUpdatedEvent,
|
||||
} from "../events";
|
||||
import { CoalitionAreaHandle } from "../map/coalitionarea/coalitionareahandle";
|
||||
import { DraggableHandle } from "../map/coalitionarea/coalitionareahandle";
|
||||
import { ArrowMarker } from "../map/markers/arrowmarker";
|
||||
import { Spot } from "../mission/spot";
|
||||
import { SpotEditMarker } from "../map/markers/spoteditmarker";
|
||||
@ -171,7 +171,7 @@ export abstract class Unit extends CustomMarker {
|
||||
#trailPolylines: Polyline[] = [];
|
||||
#racetrackPolylines: Polyline[] = [];
|
||||
#racetrackArcs: Polyline[] = [];
|
||||
#racetrackAnchorMarkers: CoalitionAreaHandle[] = [new CoalitionAreaHandle(new LatLng(0, 0)), new CoalitionAreaHandle(new LatLng(0, 0))];
|
||||
#racetrackAnchorMarkers: DraggableHandle[] = [new DraggableHandle(new LatLng(0, 0)), new DraggableHandle(new LatLng(0, 0))];
|
||||
#racetrackArrow: ArrowMarker = new ArrowMarker(new LatLng(0, 0));
|
||||
#inhibitRacetrackDraw: boolean = false;
|
||||
#spotLines: { [key: number]: Polyline } = {};
|
||||
@ -379,13 +379,13 @@ export abstract class Unit extends CustomMarker {
|
||||
});
|
||||
|
||||
this.#racetrackPolylines = [
|
||||
new Polyline([], { color: colors.OLYMPUS_BLUE, weight: 3, opacity: 0.5, smoothFactor: 1 }),
|
||||
new Polyline([], { color: colors.OLYMPUS_BLUE, weight: 3, opacity: 0.5, smoothFactor: 1 }),
|
||||
new Polyline([], { color: colors.WHITE, weight: 3, smoothFactor: 1, dashArray: "5, 5" }),
|
||||
new Polyline([], { color: colors.WHITE, weight: 3, smoothFactor: 1, dashArray: "5, 5" }),
|
||||
];
|
||||
|
||||
this.#racetrackArcs = [
|
||||
new Polyline([], { color: colors.OLYMPUS_BLUE, weight: 3, opacity: 0.5, smoothFactor: 1 }),
|
||||
new Polyline([], { color: colors.OLYMPUS_BLUE, weight: 3, opacity: 0.5, smoothFactor: 1 }),
|
||||
new Polyline([], { color: colors.WHITE, weight: 3, smoothFactor: 1, dashArray: "5, 5" }),
|
||||
new Polyline([], { color: colors.WHITE, weight: 3, smoothFactor: 1, dashArray: "5, 5" }),
|
||||
];
|
||||
|
||||
this.#racetrackAnchorMarkers[0].on("drag", (e: any) => {
|
||||
@ -1724,84 +1724,88 @@ export abstract class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
#drawRacetrack() {
|
||||
let groundspeed = this.#speed;
|
||||
this.#clearRacetrack();
|
||||
|
||||
// Determine racetrack length
|
||||
let racetrackLength = this.#racetrackLength;
|
||||
if (racetrackLength === 0) {
|
||||
if (this.getIsActiveTanker())
|
||||
racetrackLength = nmToM(50); // Default length for active tanker
|
||||
else racetrackLength = this.#desiredSpeed * 30; // Default length based on desired speed
|
||||
if (getApp().getMap().getOptions().showRacetracks) {
|
||||
let groundspeed = this.#speed;
|
||||
|
||||
// Determine racetrack length
|
||||
let racetrackLength = this.#racetrackLength;
|
||||
if (racetrackLength === 0) {
|
||||
if (this.getIsActiveTanker())
|
||||
racetrackLength = nmToM(50); // Default length for active tanker
|
||||
else racetrackLength = this.#desiredSpeed * 30; // Default length based on desired speed
|
||||
}
|
||||
|
||||
// Calculate the radius of the racetrack turns
|
||||
const radius = Math.pow(groundspeed, 2) / 9.81 / Math.tan(deg2rad(22.5));
|
||||
|
||||
let point1;
|
||||
let point2;
|
||||
|
||||
// Determine the anchor points of the racetrack
|
||||
if (!this.#inhibitRacetrackDraw) {
|
||||
point1 = this.#racetrackAnchor;
|
||||
point2 = bearingAndDistanceToLatLng(point1.lat, point1.lng, this.#racetrackBearing, racetrackLength);
|
||||
} else {
|
||||
point1 = this.#racetrackAnchorMarkers[0].getLatLng();
|
||||
point2 = this.#racetrackAnchorMarkers[1].getLatLng();
|
||||
this.#racetrackBearing = deg2rad(bearing(point1.lat, point1.lng, point2.lat, point2.lng, false));
|
||||
this.#racetrackLength = point1.distanceTo(point2);
|
||||
}
|
||||
|
||||
// Calculate the other points of the racetrack
|
||||
const point3 = bearingAndDistanceToLatLng(point2.lat, point2.lng, this.#racetrackBearing - deg2rad(90), radius * 2);
|
||||
const point4 = bearingAndDistanceToLatLng(point1.lat, point1.lng, this.#racetrackBearing - deg2rad(90), radius * 2);
|
||||
const pointArrow = bearingAndDistanceToLatLng(point1.lat, point1.lng, this.#racetrackBearing, racetrackLength / 2);
|
||||
|
||||
// Calculate the centers of the racetrack turns
|
||||
const center1 = bearingAndDistanceToLatLng(point2.lat, point2.lng, this.#racetrackBearing - deg2rad(90), radius);
|
||||
const center2 = bearingAndDistanceToLatLng(point1.lat, point1.lng, this.#racetrackBearing - deg2rad(90), radius);
|
||||
|
||||
// Draw or update the straight segments of the racetrack
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackPolylines[0])) this.#racetrackPolylines[0].addTo(getApp().getMap());
|
||||
this.#racetrackPolylines[0].setLatLngs([point1, point2]);
|
||||
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackPolylines[1])) this.#racetrackPolylines[1].addTo(getApp().getMap());
|
||||
this.#racetrackPolylines[1].setLatLngs([point3, point4]);
|
||||
|
||||
const arc1Points: LatLng[] = [];
|
||||
const arc2Points: LatLng[] = [];
|
||||
|
||||
// Calculate the points for the racetrack arcs
|
||||
for (let theta = 0; theta <= 180; theta += 5) {
|
||||
arc1Points.push(bearingAndDistanceToLatLng(center1.lat, center1.lng, this.#racetrackBearing + deg2rad(theta - 90), radius));
|
||||
arc2Points.push(bearingAndDistanceToLatLng(center2.lat, center2.lng, this.#racetrackBearing + deg2rad(theta + 90), radius));
|
||||
}
|
||||
|
||||
// Draw or update the racetrack arcs
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackArcs[0])) this.#racetrackArcs[0].addTo(getApp().getMap());
|
||||
this.#racetrackArcs[0].setLatLngs(arc1Points);
|
||||
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackArcs[1])) this.#racetrackArcs[1].addTo(getApp().getMap());
|
||||
|
||||
this.#racetrackArcs[1].setLatLngs(arc2Points);
|
||||
|
||||
// Update the positions of the racetrack anchor markers
|
||||
this.#racetrackAnchorMarkers[0].setLatLng(point1);
|
||||
this.#racetrackAnchorMarkers[1].setLatLng(point2);
|
||||
|
||||
// Add the racetrack anchor markers to the map if they are not already present
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackAnchorMarkers[0])) {
|
||||
this.#racetrackAnchorMarkers[0].addTo(getApp().getMap());
|
||||
}
|
||||
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackAnchorMarkers[1])) {
|
||||
this.#racetrackAnchorMarkers[1].addTo(getApp().getMap());
|
||||
}
|
||||
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackArrow)) {
|
||||
this.#racetrackArrow.addTo(getApp().getMap());
|
||||
}
|
||||
this.#racetrackArrow.setLatLng(pointArrow);
|
||||
this.#racetrackArrow.setBearing(this.#racetrackBearing);
|
||||
}
|
||||
|
||||
// Calculate the radius of the racetrack turns
|
||||
const radius = Math.pow(groundspeed, 2) / 9.81 / Math.tan(deg2rad(22.5));
|
||||
|
||||
let point1;
|
||||
let point2;
|
||||
|
||||
// Determine the anchor points of the racetrack
|
||||
if (!this.#inhibitRacetrackDraw) {
|
||||
point1 = this.#racetrackAnchor;
|
||||
point2 = bearingAndDistanceToLatLng(point1.lat, point1.lng, this.#racetrackBearing, racetrackLength);
|
||||
} else {
|
||||
point1 = this.#racetrackAnchorMarkers[0].getLatLng();
|
||||
point2 = this.#racetrackAnchorMarkers[1].getLatLng();
|
||||
this.#racetrackBearing = deg2rad(bearing(point1.lat, point1.lng, point2.lat, point2.lng, false));
|
||||
this.#racetrackLength = point1.distanceTo(point2);
|
||||
}
|
||||
|
||||
// Calculate the other points of the racetrack
|
||||
const point3 = bearingAndDistanceToLatLng(point2.lat, point2.lng, this.#racetrackBearing - deg2rad(90), radius * 2);
|
||||
const point4 = bearingAndDistanceToLatLng(point1.lat, point1.lng, this.#racetrackBearing - deg2rad(90), radius * 2);
|
||||
const pointArrow = bearingAndDistanceToLatLng(point1.lat, point1.lng, this.#racetrackBearing, racetrackLength / 2);
|
||||
|
||||
// Calculate the centers of the racetrack turns
|
||||
const center1 = bearingAndDistanceToLatLng(point2.lat, point2.lng, this.#racetrackBearing - deg2rad(90), radius);
|
||||
const center2 = bearingAndDistanceToLatLng(point1.lat, point1.lng, this.#racetrackBearing - deg2rad(90), radius);
|
||||
|
||||
// Draw or update the straight segments of the racetrack
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackPolylines[0])) this.#racetrackPolylines[0].addTo(getApp().getMap());
|
||||
this.#racetrackPolylines[0].setLatLngs([point1, point2]);
|
||||
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackPolylines[1])) this.#racetrackPolylines[1].addTo(getApp().getMap());
|
||||
this.#racetrackPolylines[1].setLatLngs([point3, point4]);
|
||||
|
||||
const arc1Points: LatLng[] = [];
|
||||
const arc2Points: LatLng[] = [];
|
||||
|
||||
// Calculate the points for the racetrack arcs
|
||||
for (let theta = 0; theta <= 180; theta += 5) {
|
||||
arc1Points.push(bearingAndDistanceToLatLng(center1.lat, center1.lng, this.#racetrackBearing + deg2rad(theta - 90), radius));
|
||||
arc2Points.push(bearingAndDistanceToLatLng(center2.lat, center2.lng, this.#racetrackBearing + deg2rad(theta + 90), radius));
|
||||
}
|
||||
|
||||
// Draw or update the racetrack arcs
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackArcs[0])) this.#racetrackArcs[0].addTo(getApp().getMap());
|
||||
this.#racetrackArcs[0].setLatLngs(arc1Points);
|
||||
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackArcs[1])) this.#racetrackArcs[1].addTo(getApp().getMap());
|
||||
|
||||
this.#racetrackArcs[1].setLatLngs(arc2Points);
|
||||
|
||||
// Update the positions of the racetrack anchor markers
|
||||
this.#racetrackAnchorMarkers[0].setLatLng(point1);
|
||||
this.#racetrackAnchorMarkers[1].setLatLng(point2);
|
||||
|
||||
// Add the racetrack anchor markers to the map if they are not already present
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackAnchorMarkers[0])) {
|
||||
this.#racetrackAnchorMarkers[0].addTo(getApp().getMap());
|
||||
}
|
||||
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackAnchorMarkers[1])) {
|
||||
this.#racetrackAnchorMarkers[1].addTo(getApp().getMap());
|
||||
}
|
||||
|
||||
if (!getApp().getMap().hasLayer(this.#racetrackArrow)) {
|
||||
this.#racetrackArrow.addTo(getApp().getMap());
|
||||
}
|
||||
this.#racetrackArrow.setLatLng(pointArrow);
|
||||
this.#racetrackArrow.setBearing(this.#racetrackBearing);
|
||||
}
|
||||
|
||||
#clearRacetrack() {
|
||||
@ -1993,8 +1997,8 @@ export abstract class Unit extends CustomMarker {
|
||||
var color;
|
||||
if (contactData.detectionMethod === VISUAL || contactData.detectionMethod === OPTIC) color = colors.MAGENTA;
|
||||
else if (contactData.detectionMethod === RADAR || contactData.detectionMethod === IRST) color = colors.YELLOW;
|
||||
else if (contactData.detectionMethod === RWR) color = colors.GREEN;
|
||||
else color = colors.WHITE;
|
||||
else if (contactData.detectionMethod === RWR) color = colors.GREEN_YELLOW;
|
||||
else color = colors.LIGHT_GREY;
|
||||
var contactPolyline = new Polyline([startLatLng, endLatLng], {
|
||||
color: color,
|
||||
weight: 3,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user