Draw patrol commit ranges in the new map.

This commit is contained in:
Dan Albert 2021-05-14 23:41:55 -07:00
parent dae9c368b7
commit bdb959d986
3 changed files with 49 additions and 10 deletions

View File

@ -476,6 +476,9 @@ class LatLon:
latitude: float latitude: float
longitude: float longitude: float
def as_list(self) -> List[float]:
return [self.latitude, self.longitude]
class ConflictTheater: class ConflictTheater:
terrain: Terrain terrain: Terrain

View File

@ -6,8 +6,10 @@ from PySide2.QtCore import Property, QObject, Signal, Slot
from dcs import Point from dcs import Point
from dcs.unit import Unit from dcs.unit import Unit
from dcs.vehicles import vehicle_map from dcs.vehicles import vehicle_map
from shapely.geometry import LineString, Point as ShapelyPoint, Polygon
from game import Game, db from game import Game, db
from game.factions.faction import Faction
from game.profiling import logged_duration from game.profiling import logged_duration
from game.theater import ( from game.theater import (
ConflictTheater, ConflictTheater,
@ -18,7 +20,7 @@ from game.theater import (
from game.utils import meters, nautical_miles from game.utils import meters, nautical_miles
from gen.ato import AirTaskingOrder from gen.ato import AirTaskingOrder
from gen.flights.flight import Flight, FlightWaypoint, FlightWaypointType from gen.flights.flight import Flight, FlightWaypoint, FlightWaypointType
from gen.flights.flightplan import FlightPlan from gen.flights.flightplan import FlightPlan, PatrollingFlightPlan
from qt_ui.dialogs import Dialog from qt_ui.dialogs import Dialog
from qt_ui.models import GameModel from qt_ui.models import GameModel
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
@ -43,6 +45,14 @@ LeafletLatLon = List[float]
# needs a named signal for every property, even if it is constant. # needs a named signal for every property, even if it is constant.
def shapely_poly_to_leaflet_points(
poly: Polygon, theater: ConflictTheater
) -> Optional[List[LeafletLatLon]]:
if poly.is_empty:
return None
return [theater.point_to_ll(Point(x, y)).as_list() for x, y in poly.exterior.coords]
class ControlPointJs(QObject): class ControlPointJs(QObject):
nameChanged = Signal() nameChanged = Signal()
blueChanged = Signal() blueChanged = Signal()
@ -312,18 +322,20 @@ class FlightJs(QObject):
flightPlanChanged = Signal() flightPlanChanged = Signal()
blueChanged = Signal() blueChanged = Signal()
selectedChanged = Signal() selectedChanged = Signal()
commitBoundaryChanged = Signal()
def __init__( def __init__(
self, flight: Flight, selected: bool, theater: ConflictTheater self, flight: Flight, selected: bool, theater: ConflictTheater, faction: Faction
) -> None: ) -> None:
super().__init__() super().__init__()
self.flight = flight self.flight = flight
self._selected = selected self._selected = selected
self.theater = theater self.theater = theater
self._waypoints = [] self.faction = faction
self.reset_waypoints() self._waypoints = self.make_waypoints()
self._commit_boundary = self.make_commit_boundary()
def reset_waypoints(self) -> None: def make_waypoints(self) -> List[WaypointJs]:
departure = FlightWaypoint( departure = FlightWaypoint(
FlightWaypointType.TAKEOFF, FlightWaypointType.TAKEOFF,
self.flight.departure.position.x, self.flight.departure.position.x,
@ -331,11 +343,25 @@ class FlightJs(QObject):
meters(0), meters(0),
) )
departure.alt_type = "RADIO" departure.alt_type = "RADIO"
self._waypoints = [ return [
WaypointJs(p, i, self.flight.flight_plan, self.theater) WaypointJs(p, i, self.flight.flight_plan, self.theater)
for i, p in enumerate([departure] + self.flight.points) for i, p in enumerate([departure] + self.flight.points)
] ]
self.flightPlanChanged.emit()
def make_commit_boundary(self) -> Optional[List[LeafletLatLon]]:
if not isinstance(self.flight.flight_plan, PatrollingFlightPlan):
return []
start = self.flight.flight_plan.patrol_start
end = self.flight.flight_plan.patrol_end
line = LineString(
[
ShapelyPoint(start.x, start.y),
ShapelyPoint(end.x, end.y),
]
)
doctrine = self.faction.doctrine
bubble = line.buffer(doctrine.cap_engagement_range.meters)
return shapely_poly_to_leaflet_points(bubble, self.theater)
@Property(list, notify=flightPlanChanged) @Property(list, notify=flightPlanChanged)
def flightPlan(self) -> List[WaypointJs]: def flightPlan(self) -> List[WaypointJs]:
@ -349,6 +375,10 @@ class FlightJs(QObject):
def selected(self) -> bool: def selected(self) -> bool:
return self._selected return self._selected
@Property(list)
def commitBoundary(self) -> Optional[List[LeafletLatLon]]:
return self._commit_boundary
class MapModel(QObject): class MapModel(QObject):
cleared = Signal() cleared = Signal()
@ -452,6 +482,7 @@ class MapModel(QObject):
flight, flight,
selected=blue and (p_idx, f_idx) == self._selected_flight_index, selected=blue and (p_idx, f_idx) == self._selected_flight_index,
theater=self.game.theater, theater=self.game.theater,
faction=self.game.faction_for(blue),
) )
) )
return flights return flights

View File

@ -7,7 +7,6 @@
* - CV waypoints * - CV waypoints
* - Time of day/weather themeing * - Time of day/weather themeing
* - Exclusion zones * - Exclusion zones
* - Commit ranges
* - Supply route status * - Supply route status
* - "Actual" front line * - "Actual" front line
* - Debug flight plan drawing * - Debug flight plan drawing
@ -247,8 +246,14 @@ function drawFlightPlan(flight) {
}); });
if (flight.selected) { if (flight.selected) {
L.polyline(points, { color: highlight }).addTo(selectedFlightPlansLayer); L.polyline(points, { color: highlight })
L.polyline(points, { color: highlight }).addTo(layer); .addTo(layer)
.addTo(selectedFlightPlansLayer);
if (flight.commitBoundary) {
L.polyline(flight.commitBoundary, { color: highlight, weight: 1 }).addTo(
layer.addTo(selectedFlightPlansLayer)
);
}
} else { } else {
L.polyline(points, { color: color, weight: 1 }).addTo(layer); L.polyline(points, { color: color, weight: 1 }).addTo(layer);
} }