diff --git a/frontend/react/public/images/others/arrow.svg b/frontend/react/public/images/others/arrow.svg
index 8ecc05ae..38ef0bce 100644
--- a/frontend/react/public/images/others/arrow.svg
+++ b/frontend/react/public/images/others/arrow.svg
@@ -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" />
+ style="stroke:none;stroke-width:2.30583;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="csccsscc" />
diff --git a/frontend/react/src/constants/constants.ts b/frontend/react/src/constants/constants.ts
index b9e89445..7fc93bab 100644
--- a/frontend/react/src/constants/constants.ts
+++ b/frontend/react/src/constants/constants.ts
@@ -403,6 +403,7 @@ export const MAP_OPTIONS_DEFAULTS: MapOptions = {
showUnitLabels: true,
showUnitsEngagementRings: true,
showUnitsAcquisitionRings: true,
+ showRacetracks: true,
fillSelectedRing: false,
showMinimap: false,
protectDCSUnits: true,
diff --git a/frontend/react/src/map/coalitionarea/coalitionareahandle.ts b/frontend/react/src/map/coalitionarea/coalitionareahandle.ts
index 9e72f100..3bc95b63 100644
--- a/frontend/react/src/map/coalitionarea/coalitionareahandle.ts
+++ b/frontend/react/src/map/coalitionarea/coalitionareahandle.ts
@@ -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);
}
}
diff --git a/frontend/react/src/map/coalitionarea/coalitioncircle.ts b/frontend/react/src/map/coalitionarea/coalitioncircle.ts
index 3c8b1f73..1a6f7f9e 100644
--- a/frontend/react/src/map/coalitionarea/coalitioncircle.ts
+++ b/frontend/react/src/map/coalitionarea/coalitioncircle.ts
@@ -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));
diff --git a/frontend/react/src/map/coalitionarea/coalitionpolygon.ts b/frontend/react/src/map/coalitionarea/coalitionpolygon.ts
index a0408358..1a2ead5f 100644
--- a/frontend/react/src/map/coalitionarea/coalitionpolygon.ts
+++ b/frontend/react/src/map/coalitionarea/coalitionpolygon.ts
@@ -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[];
diff --git a/frontend/react/src/map/stylesheets/map.css b/frontend/react/src/map/stylesheets/map.css
index 6834f088..155208cd 100644
--- a/frontend/react/src/map/stylesheets/map.css
+++ b/frontend/react/src/map/stylesheets/map.css
@@ -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;
}
diff --git a/frontend/react/src/types/types.ts b/frontend/react/src/types/types.ts
index 7dc22e28..f3114a56 100644
--- a/frontend/react/src/types/types.ts
+++ b/frontend/react/src/types/types.ts
@@ -18,6 +18,7 @@ export type MapOptions = {
showUnitLabels: boolean;
showUnitsEngagementRings: boolean;
showUnitsAcquisitionRings: boolean;
+ showRacetracks: boolean;
fillSelectedRing: boolean;
showMinimap: boolean;
protectDCSUnits: boolean;
diff --git a/frontend/react/src/ui/panels/header.tsx b/frontend/react/src/ui/panels/header.tsx
index d7e2b58a..99fb6a36 100644
--- a/frontend/react/src/ui/panels/header.tsx
+++ b/frontend/react/src/ui/panels/header.tsx
@@ -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 ? (
-
+
) : (
-
+
+
+
+
getApp().getMap().setOption("showUnitsEngagementRings", !mapOptions.showUnitsEngagementRings)}
+ checked={mapOptions.showUnitsEngagementRings}
+ icon={faTriangleExclamation}
+ className={""}
+ tooltip={"Hide/show units engagement rings"}
+ />
+ getApp().getMap().setOption("showUnitsAcquisitionRings", !mapOptions.showUnitsAcquisitionRings)}
+ checked={mapOptions.showUnitsAcquisitionRings}
+ icon={faWifi}
+ className={""}
+ tooltip={"Hide/show units acquisition rings"}
+ />
+
void; childre
onClick={() => getApp().getMap().setOption("showUnitLabels", !mapOptions.showUnitLabels)}
>
{}}>
- Show Unit Labels
+ Show unit labels
void; childre
onClick={() => getApp().getMap().setOption("showUnitsEngagementRings", !mapOptions.showUnitsEngagementRings)}
>
{}}>
-
Show Threat Rings
+
Show threat rings
void; childre
onClick={() => getApp().getMap().setOption("showUnitsAcquisitionRings", !mapOptions.showUnitsAcquisitionRings)}
>
{}}>
-
Show Detection rings
+
Show detection rings
void; childre
onClick={() => getApp().getMap().setOption("showUnitTargets", !mapOptions.showUnitTargets)}
>
{}}>
-
Show Detection lines
+
Show detection lines
void; childre
onClick={() => getApp().getMap().setOption("hideUnitsShortRangeRings", !mapOptions.hideUnitsShortRangeRings)}
>
{}}>
-
Hide Short range Rings
+
Hide short range rings
void; childre
onClick={() => getApp().getMap().setOption("hideGroupMembers", !mapOptions.hideGroupMembers)}
>
{}}>
-
Hide Group members
+
Hide group members
void; childre
{}}>
Show minimap
+ getApp().getMap().setOption("showRacetracks", !mapOptions.showRacetracks)}
+ >
+
{}}>
+
Show racetracks
+
void; childre
mapOptions.AWACSCoalition === "red" && getApp().getMap().setOption("AWACSCoalition", "blue");
}}
>
+
+
{}} coalition={mapOptions.AWACSCoalition} />
Coalition of unit bullseye info
+
+
+
{" "}
+
+ Change the coalition of the bullseye to use to provide bullseye information in the unit tooltip.
+
+
+
diff --git a/frontend/react/src/unit/unit.ts b/frontend/react/src/unit/unit.ts
index 92db8a1e..6c8c7e2b 100644
--- a/frontend/react/src/unit/unit.ts
+++ b/frontend/react/src/unit/unit.ts
@@ -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,