This commit is contained in:
2026-07-27 15:43:28 +08:00
parent bec086a1ab
commit 272f04bb5c
3 changed files with 185 additions and 79 deletions
+36 -9
View File
@@ -35,6 +35,10 @@ export type Data_Source_Map_Display_Config = {
map2d: Data_Source_Map_Display_Data
map3d: Data_Source_Map_Display_Data
}
type Aircraft_Track_Request_Item = {
icao: string
last_size: number
}
export function default_map_display_data(): Data_Source_Map_Display_Data {
return {
base_station_show: true,
@@ -187,6 +191,13 @@ export class Data_Source extends enhance.Base {
}
async set_monitor_all_aircraft_mode(enabled: boolean) {
this.monitor_all_aircraft_mode = enabled;
if (!enabled) {
for (const aircraft of this.aircraftMap.values()) {
if (!this.manual_track_icao_set.has(aircraft.icao)) {
aircraft.hide_path();
}
}
}
await this.refresh_manual_tracked_aircraft();
this.refresh_manual_tracking_views();
}
@@ -210,19 +221,35 @@ export class Data_Source extends enhance.Base {
this.manual_track_icao_set.clear();
this.refresh_manual_tracking_views();
}
async refresh_manual_tracked_aircraft() {
const tasks: Promise<any>[] = [];
const tracked_icaos = new Set(this.monitor_all_aircraft_mode ? Array.from(this.aircraftMap.keys()) : []);
for (const icao of this.manual_track_icao_set) {
tracked_icaos.add(icao);
}
for (const icao of tracked_icaos) {
tracked_aircraft_track_request_items(): Aircraft_Track_Request_Item[] {
const tracked_icaos = this.monitor_all_aircraft_mode ? Array.from(this.aircraftMap.keys()) : this.manual_track_icao_list();
const ret: Aircraft_Track_Request_Item[] = [];
tracked_icaos.forEach((icao) => {
const aircraft = this.aircraftMap.get(icao);
if (aircraft) {
tasks.push(aircraft.refresh_monitored_path());
ret.push({icao, last_size: aircraft.last_size});
}
});
return ret;
}
async refresh_manual_tracked_aircraft() {
const items = this.tracked_aircraft_track_request_items();
if (items.length === 0) {
return;
}
await Promise.all(tasks);
const res = await axios.post(`${baseURL}/get_aircraft_track_list_batch`, {
data_source_key: this.key,
items
});
const list = Array.isArray(res.data?.list) ? res.data.list : [];
list.forEach((item: any) => {
const aircraft = this.aircraftMap.get(item.icao);
if (!aircraft) {
return;
}
aircraft.is_show_path = true;
aircraft.append_path_response(item);
});
}
refresh_manual_tracking_views() {
app.cesium_map?.sync_data_sources();
+36 -23
View File
@@ -481,19 +481,23 @@ export class Aircraft {
icao: this.icao,
last_size: this.last_size
})
if (!res.data) {
return this.apply_track_data(res.data)
}
apply_track_data(data: any) {
if (!data) {
return []
}
let list = res.data.list;
let end_seq = res.data.end_seq;
let sta_seq = res.data.sta_seq;
let list = Array.isArray(data.list) ? data.list : [];
let end_seq = Number(data.end_seq ?? this.last_size);
let sta_seq = Number(data.sta_seq ?? this.last_size);
let old_seq = this.last_size;
if (sta_seq != old_seq) {
return []
}
this.last_size = end_seq;
if (res.data.track_orientation) {
this.data_model.trackOrientation = orientation_from_item(res.data, this.data_model.trackOrientation);
if (data.track_orientation) {
this.data_model.trackOrientation = orientation_from_item(data, this.data_model.trackOrientation);
this.data_model.heading = this.data_model.trackOrientation.heading;
this.data_model.pitch = this.data_model.trackOrientation.pitch;
this.data_model.roll = this.data_model.trackOrientation.roll;
@@ -504,28 +508,37 @@ export class Aircraft {
}
append_path() {
return this.load_track_data().then(list => this.append_loaded_path(list))
}
append_loaded_path(list: any[]) {
let map = app.leaflet_map?.map;
return this.load_track_data().then(list => {
list.forEach((data) => {
let point = new Aircraft_Track_Point(data);
const style = this.data_source.map2d_style();
point.setColor(style.track_point_color || lightenColor(style.color));
if (map) {
point.addTo(map);
}
this.track_point_list.push(point)
this.track_path.addLatLng(point.getLatLng());
});
this.track_point_list.forEach((data, i) => {
if (map) {
list.forEach((data) => {
let point = new Aircraft_Track_Point(data);
const style = this.data_source.map2d_style();
point.setColor(style.track_point_color || lightenColor(style.color));
if (map) {
point.addTo(map);
}
this.track_point_list.push(point)
this.track_path.addLatLng(point.getLatLng());
});
this.track_point_list.forEach((data) => {
if (map) {
if (!map.hasLayer(data)) {
data.addTo(map)
}
});
if (map) {
}
});
if (map) {
if (!map.hasLayer(this.track_path)) {
this.track_path.addTo(map)
}
this.refresh_pos_by_track();
})
}
this.refresh_pos_by_track();
}
append_path_response(data: any) {
this.append_loaded_path(this.apply_track_data(data));
}
refresh_monitored_path() {
this.is_show_path = true;
+113 -47
View File
@@ -46,11 +46,21 @@ import {mark_cesium_webgl_unavailable, webgl_unavailable_message} from "./WebGL_
type Aircraft_Entity_Record = {
aircraft: Cesium.Entity
track: Cesium.Entity
point_entities: Cesium.Entity[]
point_collection: Cesium.PointPrimitiveCollection
point_records: Cesium_Track_Point_Record[]
point_start_index: number
track_positions: Cesium.Cartesian3[]
track_positions_key: string
}
type Cesium_Track_Point_Record = {
primitive?: Cesium.PointPrimitive
entity?: Cesium.Entity
}
type Track_Point_Pick_Record = {
ecap_track_point: Aircraft_Track_Point_Model
ecap_track_key: string
ecap_track_description: string
}
type Base_Station_Entity_Record = {
model: Cesium.Entity
height_line: Cesium.Entity
@@ -114,6 +124,7 @@ export class Cesium_Map extends enhance.Base {
performance_observer: PerformanceObserver | null = null;
performance_info: Performance_Info = {fps: 0, frame_ms: 0, cpu_pressure: 0, js_heap_mb: null, gpu_renderer: "", tile_state: ""};
context_menu: Cesium_Context_Menu | null = null;
track_point_selection_entity: Cesium.Entity | null = null;
prevent_context_menu_listener: ((event: Event) => void) | null = null;
max_track_points_per_aircraft = 1000;
constructor(scene_mode: Scene_Mode_Key = "3d") {
@@ -527,11 +538,7 @@ export class Cesium_Map extends enhance.Base {
}
for (const [key, record] of this.entity_map) {
if (alive.has(key)) continue;
this.viewer.entities.remove(record.aircraft);
this.viewer.entities.remove(record.track);
for (const point of record.point_entities) {
this.viewer.entities.remove(point);
}
this.remove_aircraft_record(record);
this.entity_map.delete(key);
if (this.selected_aircraft && key === this.entity_key(this.selected_aircraft.data_source.key, this.selected_aircraft.icao)) {
this.clear_selected_aircraft();
@@ -924,7 +931,15 @@ export class Cesium_Map extends enhance.Base {
}
});
(aircraft_entity as any).ecap_aircraft = aircraft;
return {aircraft: aircraft_entity, track: track_entity, point_entities: [], point_start_index: 0, track_positions, track_positions_key: ""};
const point_collection = this.viewer!.scene.primitives.add(new Cesium.PointPrimitiveCollection()) as Cesium.PointPrimitiveCollection;
point_collection.show = false;
return {aircraft: aircraft_entity, track: track_entity, point_collection, point_records: [], point_start_index: 0, track_positions, track_positions_key: ""};
}
remove_aircraft_record(record: Aircraft_Entity_Record) {
this.viewer!.entities.remove(record.aircraft);
this.viewer!.entities.remove(record.track);
this.clear_track_point_records(record);
this.viewer!.scene.primitives.remove(record.point_collection);
}
aircraft_model_item(aircraft: Aircraft): Map_Model_Item_Config {
const key = aircraft.data_model.vortexTypeKey;
@@ -996,6 +1011,16 @@ export class Cesium_Map extends enhance.Base {
if (record.track.polyline) {
record.track.polyline.material = new Cesium.ColorMaterialProperty(color.withAlpha(0.8));
}
this.apply_track_point_style(record, aircraft);
}
apply_track_point_style(record: Aircraft_Entity_Record, aircraft: Aircraft) {
const style = aircraft.data_source.map3d_style();
const color = Cesium.Color.fromCssColorString(style.track_point_color || style.color).withAlpha(0.9);
for (const point of record.point_records) {
if (point.primitive) {
point.primitive.color = color;
}
}
}
aircraft_label_enabled(aircraft: Aircraft): boolean {
const source = aircraft.data_source.map3d_style();
@@ -1015,24 +1040,21 @@ export class Cesium_Map extends enhance.Base {
}
sync_track_points(key: string, aircraft: Aircraft, record: Aircraft_Entity_Record) {
const points = aircraft.data_model.track_points;
if (points.length < record.point_start_index + record.point_entities.length) {
for (const entity of record.point_entities) {
this.viewer!.entities.remove(entity);
}
record.point_entities = [];
if (points.length < record.point_start_index + record.point_records.length) {
this.clear_track_point_records(record);
record.point_start_index = 0;
}
const next_start = Math.max(0, points.length - this.max_track_points_per_aircraft);
if (next_start > record.point_start_index) {
const remove_count = Math.min(next_start - record.point_start_index, record.point_entities.length);
for (const entity of record.point_entities.splice(0, remove_count)) {
this.viewer!.entities.remove(entity);
const remove_count = Math.min(next_start - record.point_start_index, record.point_records.length);
for (const item of record.point_records.splice(0, remove_count)) {
this.remove_track_point_record(record, item);
}
record.point_start_index += remove_count;
}
const next_index = record.point_start_index + record.point_entities.length;
const next_index = record.point_start_index + record.point_records.length;
for (let i = next_index; i < points.length; i++) {
record.point_entities.push(this.create_track_point_entity(key, aircraft, points[i], i));
record.point_records.push(this.create_track_point_record(record, key, aircraft, points[i], i));
}
const displayed_points = points.slice(record.point_start_index);
const aircraft_position = this.aircraft_position(aircraft);
@@ -1050,9 +1072,43 @@ export class Cesium_Map extends enhance.Base {
}
this.show_track(record);
}
clear_track_point_records(record: Aircraft_Entity_Record) {
for (const point of record.point_records) {
this.remove_track_point_record(record, point);
}
record.point_records = [];
}
remove_track_point_record(record: Aircraft_Entity_Record, point: Cesium_Track_Point_Record) {
if (point.primitive) {
record.point_collection.remove(point.primitive);
}
if (point.entity) {
this.viewer!.entities.remove(point.entity);
}
}
same_position(left: Aircraft_Position, right: Aircraft_Position): boolean {
return left.lon === right.lon && left.lat === right.lat && left.alt === right.alt;
}
create_track_point_record(record: Aircraft_Entity_Record, key: string, aircraft: Aircraft, point: Aircraft_Track_Point_Model, index: number): Cesium_Track_Point_Record {
if (this.is_special_track_point(point)) {
return {entity: this.create_track_point_entity(key, aircraft, point, index)};
}
const style = aircraft.data_source.map3d_style();
const id: Track_Point_Pick_Record = {
ecap_track_point: point,
ecap_track_key: key,
ecap_track_description: this.track_point_description(point)
};
const primitive = record.point_collection.add({
position: Cesium.Cartesian3.fromDegrees(point.lon, point.lat, point.alt),
pixelSize: 7,
color: Cesium.Color.fromCssColorString(style.track_point_color || style.color).withAlpha(0.9),
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1,
id
});
return {primitive};
}
create_track_point_entity(key: string, aircraft: Aircraft, point: Aircraft_Track_Point_Model, index: number): Cesium.Entity {
const base = {
id: `${key}:point:${index}`,
@@ -1060,21 +1116,12 @@ export class Cesium_Map extends enhance.Base {
position: Cesium.Cartesian3.fromDegrees(point.lon, point.lat, point.alt),
description: this.track_point_description(point)
};
const entity = this.viewer!.entities.add(this.is_special_track_point(point) ? {
const entity = this.viewer!.entities.add({
...base,
model: {
uri: track_point_model_uri,
scale: 16
}
} : {
...base,
point: {
pixelSize: 7,
color: Cesium.Color.fromCssColorString(aircraft.data_source.map3d_style().track_point_color || aircraft.data_source.map3d_style().color).withAlpha(0.9),
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1,
heightReference: Cesium.HeightReference.NONE
}
});
(entity as any).ecap_track_point = point;
(entity as any).ecap_track_key = key;
@@ -1086,8 +1133,11 @@ export class Cesium_Map extends enhance.Base {
}
hide_track(record: Aircraft_Entity_Record) {
record.track.show = false;
for (const entity of record.point_entities) {
entity.show = false;
record.point_collection.show = false;
for (const point of record.point_records) {
if (point.entity) {
point.entity.show = false;
}
}
}
hide_all_tracks() {
@@ -1099,8 +1149,11 @@ export class Cesium_Map extends enhance.Base {
}
show_track(record: Aircraft_Entity_Record) {
record.track.show = true;
for (const entity of record.point_entities) {
entity.show = true;
record.point_collection.show = true;
for (const point of record.point_records) {
if (point.entity) {
point.entity.show = true;
}
}
}
record_is_track_monitored(record: Aircraft_Entity_Record): boolean {
@@ -1111,23 +1164,25 @@ export class Cesium_Map extends enhance.Base {
const properties = point.properties || {};
return Boolean(properties.alarm || properties.alert || properties.warning || properties.is_alarm || properties.event_type);
}
pick_interactive_entity(position: Cesium.Cartesian2): Cesium.Entity | null {
pick_interactive_target(position: Cesium.Cartesian2): Cesium.Entity | Track_Point_Pick_Record | null {
if (!this.viewer) return null;
const picked_list = this.viewer.scene.drillPick(position, 16);
for (const picked of picked_list) {
const entity = picked.id as Cesium.Entity | undefined;
if (!entity || (entity as any).ecap_ignore_pick) {
const target = picked.id as Cesium.Entity | Track_Point_Pick_Record | undefined;
if (!target || (target as any).ecap_ignore_pick) {
continue;
}
return entity;
if ((target as any).ecap_aircraft || (target as any).ecap_base_station || (target as any).ecap_track_point) {
return target;
}
}
return null;
}
handle_right_click(position: Cesium.Cartesian2) {
if (!this.viewer) return;
const entity = this.pick_interactive_entity(position);
const aircraft = entity ? (entity as any).ecap_aircraft as Aircraft | undefined : undefined;
const base_station = entity ? (entity as any).ecap_base_station as Data_Source | undefined : undefined;
const target = this.pick_interactive_target(position);
const aircraft = target ? (target as any).ecap_aircraft as Aircraft | undefined : undefined;
const base_station = target ? (target as any).ecap_base_station as Data_Source | undefined : undefined;
if (aircraft) {
this.context_menu = {x: position.x, y: position.y, aircraft};
this.flush();
@@ -1144,24 +1199,24 @@ export class Cesium_Map extends enhance.Base {
handle_click(position: Cesium.Cartesian2) {
if (!this.viewer) return;
this.context_menu = null;
const entity = this.pick_interactive_entity(position);
if (!entity) {
const target = this.pick_interactive_target(position);
if (!target) {
this.clear_selected_aircraft();
return;
}
const aircraft = (entity as any).ecap_aircraft as Aircraft | undefined;
const aircraft = (target as any).ecap_aircraft as Aircraft | undefined;
if (aircraft) {
this.select_aircraft(aircraft);
return;
}
const track_point = (entity as any).ecap_track_point as Aircraft_Track_Point_Model | undefined;
const track_point = (target as any).ecap_track_point as Aircraft_Track_Point_Model | undefined;
if (track_point) {
this.select_track_point(entity);
this.select_track_point(target);
return;
}
const base_station = (entity as any).ecap_base_station as Data_Source | undefined;
const base_station = (target as any).ecap_base_station as Data_Source | undefined;
if (base_station) {
this.select_base_station(entity);
this.select_base_station(target as Cesium.Entity);
return;
}
this.clear_selected_aircraft();
@@ -1173,9 +1228,20 @@ export class Cesium_Map extends enhance.Base {
this.viewer.selectedEntity = entity;
this.viewer.scene.requestRender();
}
select_track_point(entity: Cesium.Entity) {
select_track_point(target: Cesium.Entity | Track_Point_Pick_Record) {
if (!this.viewer) return;
this.viewer.selectedEntity = entity;
const primitive_track_point = target as Track_Point_Pick_Record;
if (primitive_track_point.ecap_track_description) {
if (!this.track_point_selection_entity) {
this.track_point_selection_entity = this.viewer.entities.add({id: "ecap:selected-track-point", show: false});
}
this.track_point_selection_entity.name = "轨迹点";
this.track_point_selection_entity.position = new Cesium.ConstantPositionProperty(Cesium.Cartesian3.fromDegrees(primitive_track_point.ecap_track_point.lon, primitive_track_point.ecap_track_point.lat, primitive_track_point.ecap_track_point.alt));
this.track_point_selection_entity.description = new Cesium.ConstantProperty(primitive_track_point.ecap_track_description);
this.viewer.selectedEntity = this.track_point_selection_entity;
} else {
this.viewer.selectedEntity = target as Cesium.Entity;
}
this.viewer.scene.requestRender();
}
select_aircraft(aircraft: Aircraft) {