Clean up leaflet polygon API surface.

This commit is contained in:
Dan Albert 2022-03-06 23:25:25 -08:00
parent 15176223fa
commit 6ee235545f
10 changed files with 53 additions and 65 deletions

View File

@ -255,7 +255,7 @@ export type GetFlightByIdApiArg = {
withWaypoints?: boolean; withWaypoints?: boolean;
}; };
export type GetCommitBoundaryForFlightApiResponse = export type GetCommitBoundaryForFlightApiResponse =
/** status 200 Successful Response */ number[][]; /** status 200 Successful Response */ LatLng[];
export type GetCommitBoundaryForFlightApiArg = { export type GetCommitBoundaryForFlightApiArg = {
flightId: string; flightId: string;
}; };
@ -352,26 +352,26 @@ export type HttpValidationError = {
detail?: ValidationError[]; detail?: ValidationError[];
}; };
export type HoldZones = { export type HoldZones = {
homeBubble: number[][]; homeBubble: LatLng[];
targetBubble: number[][]; targetBubble: LatLng[];
joinBubble: number[][]; joinBubble: LatLng[];
excludedZones: number[][][]; excludedZones: LatLng[][];
permissibleZones: number[][][]; permissibleZones: LatLng[][];
preferredLines: number[][][]; preferredLines: LatLng[][];
}; };
export type IpZones = { export type IpZones = {
homeBubble: number[][]; homeBubble: LatLng[];
ipBubble: number[][]; ipBubble: LatLng[];
permissibleZone: number[][]; permissibleZone: LatLng[];
safeZones: number[][][]; safeZones: LatLng[][];
}; };
export type JoinZones = { export type JoinZones = {
homeBubble: number[][]; homeBubble: LatLng[];
targetBubble: number[][]; targetBubble: LatLng[];
ipBubble: number[][]; ipBubble: LatLng[];
excludedZones: number[][][]; excludedZones: LatLng[][];
permissibleZones: number[][][]; permissibleZones: LatLng[][];
preferredLines: number[][][]; preferredLines: LatLng[][];
}; };
export type Waypoint = { export type Waypoint = {
name: string; name: string;
@ -415,17 +415,17 @@ export type SupplyRoute = {
active_transports: string[]; active_transports: string[];
}; };
export type ThreatZones = { export type ThreatZones = {
full: number[][][]; full: LatLng[][];
aircraft: number[][][]; aircraft: LatLng[][];
air_defenses: number[][][]; air_defenses: LatLng[][];
radar_sams: number[][][]; radar_sams: LatLng[][];
}; };
export type ThreatZoneContainer = { export type ThreatZoneContainer = {
blue: ThreatZones; blue: ThreatZones;
red: ThreatZones; red: ThreatZones;
}; };
export type NavMeshPoly = { export type NavMeshPoly = {
poly: number[][]; poly: LatLng[];
threatened: boolean; threatened: boolean;
}; };
export type NavMesh = { export type NavMesh = {
@ -446,9 +446,9 @@ export type Game = {
map_center: LatLng; map_center: LatLng;
}; };
export type MapZones = { export type MapZones = {
inclusion: number[][][]; inclusion: LatLng[][];
exclusion: number[][][]; exclusion: LatLng[][];
sea: number[][][]; sea: LatLng[][];
}; };
export type UnculledZone = { export type UnculledZone = {
position: LatLng; position: LatLng;

View File

@ -1,7 +1,6 @@
import { Flight } from "../../api/flight"; import { Flight } from "../../api/flight";
import { useGetCommitBoundaryForFlightQuery } from "../../api/liberationApi"; import { useGetCommitBoundaryForFlightQuery } from "../../api/liberationApi";
import WaypointMarker from "../waypointmarker"; import WaypointMarker from "../waypointmarker";
import { LatLng } from "leaflet";
import { ReactElement } from "react"; import { ReactElement } from "react";
import { Polyline } from "react-leaflet"; import { Polyline } from "react-leaflet";
@ -83,15 +82,8 @@ function CommitBoundary(props: CommitBoundaryProps) {
); );
return <></>; return <></>;
} }
// TODO: Fix the response model and clean up.
const positions = data.map(([lat, lng]) => new LatLng(lat, lng));
return ( return (
<Polyline <Polyline positions={data} color="#ffff00" weight={1} interactive={false} />
positions={positions}
color="#ffff00"
weight={1}
interactive={false}
/>
); );
} }

View File

@ -1,6 +1,5 @@
import { selectNavMeshes } from "../../api/navMeshSlice"; import { selectNavMeshes } from "../../api/navMeshSlice";
import { useAppSelector } from "../../app/hooks"; import { useAppSelector } from "../../app/hooks";
import { LatLng } from "leaflet";
import { LayerGroup, Polygon } from "react-leaflet"; import { LayerGroup, Polygon } from "react-leaflet";
interface NavMeshLayerProps { interface NavMeshLayerProps {
@ -13,11 +12,10 @@ export default function NavMeshLayer(props: NavMeshLayerProps) {
return ( return (
<LayerGroup> <LayerGroup>
{mesh.map((zone, idx) => { {mesh.map((zone, idx) => {
const positions = zone.poly.map(([lat, lng]) => new LatLng(lat, lng));
return ( return (
<Polygon <Polygon
key={idx} key={idx}
positions={positions} positions={zone.poly}
color="#000000" color="#000000"
weight={1} weight={1}
fill fill

View File

@ -1,18 +1,16 @@
import { LatLng } from "leaflet"; import { LatLng } from "../../api/liberationApi";
import { Polygon } from "react-leaflet"; import { Polygon } from "react-leaflet";
interface ThreatZoneProps { interface ThreatZoneProps {
poly: number[][]; poly: LatLng[];
blue: boolean; blue: boolean;
} }
export default function ThreatZone(props: ThreatZoneProps) { export default function ThreatZone(props: ThreatZoneProps) {
const color = props.blue ? "#0084ff" : "#c85050"; const color = props.blue ? "#0084ff" : "#c85050";
// TODO: Fix response model so the type can be used directly.
const positions = props.poly.map(([lat, lng]) => new LatLng(lat, lng));
return ( return (
<Polygon <Polygon
positions={positions} positions={props.poly}
color={color} color={color}
weight={1} weight={1}
fill fill

View File

@ -8,7 +8,7 @@ from pydantic import BaseModel
from game.server.combat.models import FrozenCombatJs from game.server.combat.models import FrozenCombatJs
from game.server.flights.models import FlightJs from game.server.flights.models import FlightJs
from game.server.frontlines.models import FrontLineJs from game.server.frontlines.models import FrontLineJs
from game.server.leaflet import LeafletLatLon from game.server.leaflet import LeafletPoint
if TYPE_CHECKING: if TYPE_CHECKING:
from game import Game from game import Game
@ -16,7 +16,7 @@ if TYPE_CHECKING:
class GameUpdateEventsJs(BaseModel): class GameUpdateEventsJs(BaseModel):
updated_flight_positions: dict[UUID, LeafletLatLon] updated_flight_positions: dict[UUID, LeafletPoint]
new_combats: list[FrozenCombatJs] new_combats: list[FrozenCombatJs]
updated_combats: list[FrozenCombatJs] updated_combats: list[FrozenCombatJs]
ended_combats: list[UUID] ended_combats: list[UUID]
@ -33,7 +33,7 @@ class GameUpdateEventsJs(BaseModel):
deleted_front_lines: set[UUID] deleted_front_lines: set[UUID]
updated_tgos: set[UUID] updated_tgos: set[UUID]
updated_control_points: set[int] updated_control_points: set[int]
reset_on_map_center: LeafletLatLon | None reset_on_map_center: LeafletPoint | None
game_unloaded: bool game_unloaded: bool
new_turn: bool new_turn: bool
@ -55,14 +55,9 @@ class GameUpdateEventsJs(BaseModel):
for c in events.updated_combats for c in events.updated_combats
] ]
recenter_map = None
if events.reset_on_map_center is not None:
recenter_map = events.reset_on_map_center.as_list()
return GameUpdateEventsJs( return GameUpdateEventsJs(
updated_flight_positions={ updated_flight_positions={
f[0].id: f[1].latlng().as_list() f[0].id: f[1].latlng() for f in events.updated_flight_positions
for f in events.updated_flight_positions
}, },
new_combats=new_combats, new_combats=new_combats,
updated_combats=updated_combats, updated_combats=updated_combats,
@ -84,7 +79,7 @@ class GameUpdateEventsJs(BaseModel):
deleted_front_lines=events.deleted_front_lines, deleted_front_lines=events.deleted_front_lines,
updated_tgos=events.updated_tgos, updated_tgos=events.updated_tgos,
updated_control_points=events.updated_control_points, updated_control_points=events.updated_control_points,
reset_on_map_center=recenter_map, reset_on_map_center=events.reset_on_map_center,
game_unloaded=events.game_unloaded, game_unloaded=events.game_unloaded,
new_turn=events.new_turn, new_turn=events.new_turn,
) )

View File

@ -3,14 +3,12 @@ from __future__ import annotations
from typing import Union from typing import Union
from dcs import Point from dcs import Point
from dcs.mapping import LatLng
from pydantic import BaseModel from pydantic import BaseModel
from shapely.geometry import LineString, MultiLineString, MultiPolygon, Polygon from shapely.geometry import LineString, MultiLineString, MultiPolygon, Polygon
from game.theater import ConflictTheater from game.theater import ConflictTheater
LeafletLatLon = list[float]
LeafletPoly = list[LeafletLatLon]
class LeafletPoint(BaseModel): class LeafletPoint(BaseModel):
lat: float lat: float
@ -22,13 +20,20 @@ class LeafletPoint(BaseModel):
title = "LatLng" title = "LatLng"
LeafletPoly = list[LeafletPoint]
class ShapelyUtil: class ShapelyUtil:
@staticmethod @staticmethod
def poly_to_leaflet(poly: Polygon, theater: ConflictTheater) -> LeafletPoly: def latlng_to_leaflet(latlng: LatLng) -> LeafletPoint:
return LeafletPoint(lat=latlng.lat, lng=latlng.lng)
@classmethod
def poly_to_leaflet(cls, poly: Polygon, theater: ConflictTheater) -> LeafletPoly:
if poly.is_empty: if poly.is_empty:
return [] return []
return [ return [
Point(x, y, theater.terrain).latlng().as_list() cls.latlng_to_leaflet(Point(x, y, theater.terrain).latlng())
for x, y in poly.exterior.coords for x, y in poly.exterior.coords
] ]
@ -43,15 +48,13 @@ class ShapelyUtil:
return [cls.poly_to_leaflet(poly, theater) for poly in polys] return [cls.poly_to_leaflet(poly, theater) for poly in polys]
@staticmethod @staticmethod
def line_to_leaflet( def line_to_leaflet(line: LineString, theater: ConflictTheater) -> list[LatLng]:
line: LineString, theater: ConflictTheater return [Point(x, y, theater.terrain).latlng() for x, y in line.coords]
) -> list[LeafletLatLon]:
return [Point(x, y, theater.terrain).latlng().as_list() for x, y in line.coords]
@classmethod @classmethod
def lines_to_leaflet( def lines_to_leaflet(
cls, line_string: MultiLineString | LineString, theater: ConflictTheater cls, line_string: MultiLineString | LineString, theater: ConflictTheater
) -> list[list[LeafletLatLon]]: ) -> list[list[LatLng]]:
if isinstance(line_string, MultiLineString): if isinstance(line_string, MultiLineString):
lines = line_string.geoms lines = line_string.geoms
else: else:

View File

@ -6,12 +6,12 @@ from PySide2.QtCore import Property, QObject, Signal, Slot
from dcs import Point from dcs import Point
from dcs.mapping import LatLng from dcs.mapping import LatLng
from game.server.leaflet import LeafletLatLon
from game.theater import ConflictTheater, ControlPoint from game.theater import ConflictTheater, ControlPoint
from game.utils import meters, nautical_miles from game.utils import meters, nautical_miles
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.basemenu.QBaseMenu2 import QBaseMenu2 from qt_ui.windows.basemenu.QBaseMenu2 import QBaseMenu2
from .leaflet import LeafletLatLon
MAX_SHIP_DISTANCE = nautical_miles(80) MAX_SHIP_DISTANCE = nautical_miles(80)

View File

@ -0,0 +1,2 @@
LeafletLatLon = list[float]
LeafletPoly = list[LeafletLatLon]

View File

@ -7,13 +7,13 @@ from dcs.mapping import LatLng
from game import Game from game import Game
from game.profiling import logged_duration from game.profiling import logged_duration
from game.server.leaflet import LeafletLatLon
from game.theater import ( from game.theater import (
ConflictTheater, ConflictTheater,
) )
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
from .controlpointjs import ControlPointJs from .controlpointjs import ControlPointJs
from .leaflet import LeafletLatLon
from .supplyroutejs import SupplyRouteJs from .supplyroutejs import SupplyRouteJs

View File

@ -5,9 +5,9 @@ from typing import List
from PySide2.QtCore import Property, QObject, Signal from PySide2.QtCore import Property, QObject, Signal
from game import Game from game import Game
from game.server.leaflet import LeafletLatLon
from game.theater import ControlPoint from game.theater import ControlPoint
from game.transfers import MultiGroupTransport, TransportMap from game.transfers import MultiGroupTransport, TransportMap
from .leaflet import LeafletLatLon
class SupplyRouteJs(QObject): class SupplyRouteJs(QObject):