Draw waypoint markers for the selected flight.

https://github.com/dcs-liberation/dcs_liberation/issues/2039
This commit is contained in:
Dan Albert 2022-03-01 23:06:03 -08:00
parent 030675812e
commit aac333e132
3 changed files with 103 additions and 0 deletions

View File

@ -1,5 +1,6 @@
import { Flight } from "../../api/flight";
import { Polyline } from "react-leaflet";
import WaypointMarker from "../waypointmarker";
const BLUE_PATH = "#0084ff";
const RED_PATH = "#c85050";
@ -35,10 +36,33 @@ function FlightPlanPath(props: FlightPlanProps) {
);
}
const WaypointMarkers = (props: FlightPlanProps) => {
if (!props.selected || props.flight.waypoints == null) {
return <></>;
}
return (
<>
{props.flight.waypoints
.filter((p) => p.should_mark)
.map((p, idx) => {
return (
<WaypointMarker
key={idx}
number={idx}
waypoint={p}
></WaypointMarker>
);
})}
</>
);
};
export default function FlightPlan(props: FlightPlanProps) {
return (
<>
<FlightPlanPath {...props} />
<WaypointMarkers {...props} />
</>
);
}

View File

@ -0,0 +1,76 @@
import { Marker, Tooltip, useMap, useMapEvent } from "react-leaflet";
import { MutableRefObject, useCallback, useEffect, useRef } from "react";
import { Icon } from "leaflet";
import { Marker as LMarker } from "leaflet";
import { Waypoint } from "../../api/waypoint";
import icon from "leaflet/dist/images/marker-icon.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";
const WAYPOINT_ICON = new Icon({
iconUrl: icon,
shadowUrl: iconShadow,
iconAnchor: [12, 41],
});
interface WaypointMarkerProps {
number: number;
waypoint: Waypoint;
}
const WaypointMarker = (props: WaypointMarkerProps) => {
// Most props of react-leaflet types are immutable and components will not
// update to account for changes, so we can't simply use the `permanent`
// property of the tooltip to control tooltip visibility based on the zoom
// level.
//
// On top of that, listening for zoom changes and opening/closing is not
// sufficient because clicking anywhere will close any opened tooltips (even
// if they are permanent; once openTooltip has been called that seems to no
// longer have any effect).
//
// Instead, listen for zoom changes and rebind the tooltip when the zoom level
// changes.
const map = useMap();
const marker: MutableRefObject<LMarker | undefined> = useRef();
const rebindTooltip = useCallback(() => {
if (marker.current === undefined) {
return;
}
const tooltip = marker.current.getTooltip();
if (tooltip === undefined) {
return;
}
const permanent = map.getZoom() >= 9;
marker.current
.unbindTooltip()
.bindTooltip(tooltip, { permanent: permanent });
}, [map]);
useMapEvent("zoomend", rebindTooltip);
const waypoint = props.waypoint;
return (
<Marker
position={waypoint.position}
icon={WAYPOINT_ICON}
ref={(ref) => {
if (ref != null) {
marker.current = ref;
}
}}
>
<Tooltip position={waypoint.position}>
{`${props.number} ${waypoint.name}`}
<br />
{`${waypoint.altitude_ft} ft ${waypoint.altitude_reference}`}
<br />
TODO: Timing info
</Tooltip>
</Marker>
);
};
export default WaypointMarker;

View File

@ -0,0 +1,3 @@
import WaypointMarker from "./WaypointMarker";
export default WaypointMarker;