add details in gui for flight

This commit is contained in:
VALLONGOL 2025-05-30 12:42:19 +02:00
parent a13caa2c19
commit 99bc253b85
2 changed files with 113 additions and 78 deletions

View File

@ -661,7 +661,6 @@ class AppController:
else: module_logger.warning("Main window N/A to update BBox GUI fields.") else: module_logger.warning("Main window N/A to update BBox GUI fields.")
def update_general_map_info(self): def update_general_map_info(self):
# ... (come prima)
module_logger.debug("Controller: Request to update general map info.") module_logger.debug("Controller: Request to update general map info.")
if not (self.main_window and hasattr(self.main_window, "map_manager_instance") and self.main_window.map_manager_instance): if not (self.main_window and hasattr(self.main_window, "map_manager_instance") and self.main_window.map_manager_instance):
module_logger.debug("Skipping general map info update: MainWindow or map manager not ready.") module_logger.debug("Skipping general map info update: MainWindow or map manager not ready.")
@ -670,30 +669,47 @@ class AppController:
except Exception: pass except Exception: pass
return return
map_manager: "MapCanvasManager" = self.main_window.map_manager_instance map_manager: "MapCanvasManager" = self.main_window.map_manager_instance # type: ignore
if hasattr(map_manager, "get_current_map_info"): if hasattr(map_manager, "get_current_map_info"):
map_info = {} map_info = {}
try: try:
map_info = map_manager.get_current_map_info() map_info = map_manager.get_current_map_info() # Questa chiamata dovrebbe restituire il target_bbox_input
zoom, map_geo_bounds, target_bbox_input, flight_count = ( module_logger.debug(f"Fetched map info from manager for general display: {map_info}")
map_info.get("zoom"), map_info.get("map_geo_bounds"),
map_info.get("target_bbox_input"), map_info.get("flight_count") zoom = map_info.get("zoom")
) map_geo_bounds = map_info.get("map_geo_bounds")
map_size_km_w, map_size_km_h = map_info.get("map_size_km_w"), map_info.get("map_size_km_h") # target_bbox_input viene ora da map_info, che dovrebbe averlo copiato in modo sicuro
target_bbox_input_from_map_info = map_info.get("target_bbox_input")
flight_count = map_info.get("flight_count")
map_size_km_w = map_info.get("map_size_km_w")
map_size_km_h = map_info.get("map_size_km_h")
map_size_str = "N/A" map_size_str = "N/A"
if map_size_km_w is not None and map_size_km_h is not None: if map_size_km_w is not None and map_size_km_h is not None:
try: try:
decimals = getattr(app_config, "MAP_SIZE_KM_DECIMAL_PLACES", 1) decimals = getattr(app_config, "MAP_SIZE_KM_DECIMAL_PLACES", 1)
map_size_str = f"{map_size_km_w:.{decimals}f}km x {map_size_km_h:.{decimals}f}km" map_size_str = f"{map_size_km_w:.{decimals}f}km x {map_size_km_h:.{decimals}f}km"
except Exception as e_format: module_logger.warning(f"Error formatting map size: {e_format}. Using N/A.", exc_info=False); map_size_str = "N/A (FormatErr)" except Exception as e_format:
module_logger.warning(f"Error formatting map size: {e_format}. Using N/A.", exc_info=False)
map_size_str = "N/A (FormatErr)"
if hasattr(self.main_window, "update_general_map_info_display"): if hasattr(self.main_window, "update_general_map_info_display"):
try: self.main_window.update_general_map_info_display(zoom=zoom, map_size_str=map_size_str, map_geo_bounds=map_geo_bounds, target_bbox_input=target_bbox_input, flight_count=flight_count) try:
except tk.TclError as e_tcl: module_logger.warning(f"TclError updating general map info panel: {e_tcl}. GUI closing.") self.main_window.update_general_map_info_display(
except Exception as e_update: module_logger.error(f"Error updating general map info panel: {e_update}", exc_info=False) zoom=zoom,
else: module_logger.warning("MainWindow missing 'update_general_map_info_display' method.") map_size_str=map_size_str,
map_geo_bounds=map_geo_bounds,
target_bbox_input=target_bbox_input_from_map_info, # Usa quello da map_info
flight_count=flight_count
)
except tk.TclError as e_tcl:
module_logger.warning(f"TclError updating general map info panel: {e_tcl}. GUI closing.")
except Exception as e_update:
module_logger.error(f"Error updating general map info panel: {e_update}", exc_info=False)
else:
module_logger.warning("MainWindow missing 'update_general_map_info_display' method.")
except Exception as e_get_info: except Exception as e_get_info:
module_logger.error(f"Error getting map info from map manager: {e_get_info}", exc_info=False) module_logger.error(f"Error getting map info from map manager in AppController: {e_get_info}", exc_info=True) # Logga con stacktrace
if hasattr(self.main_window, "update_general_map_info_display"): if hasattr(self.main_window, "update_general_map_info_display"):
try: self.main_window.update_general_map_info_display(zoom=None, map_size_str="N/A", map_geo_bounds=None, target_bbox_input=None, flight_count=None) try: self.main_window.update_general_map_info_display(zoom=None, map_size_str="N/A", map_geo_bounds=None, target_bbox_input=None, flight_count=None)
except Exception: pass except Exception: pass

View File

@ -7,7 +7,8 @@ from typing import Optional, Tuple, List, Dict, Any
from collections import deque from collections import deque
import queue # For Queue and Empty import queue # For Queue and Empty
import threading import threading
import copy # For deepcopy from . import map_utils
import copy
try: try:
from PIL import Image, ImageTk, ImageDraw, ImageFont from PIL import Image, ImageTk, ImageDraw, ImageFont
@ -1267,75 +1268,93 @@ class MapCanvasManager:
self._is_left_button_pressed = True self._is_left_button_pressed = True
def _on_left_button_release(self, event: tk.Event): def _on_left_button_release(self, event: tk.Event):
if not self.canvas.winfo_exists(): if not self.canvas.winfo_exists(): return
logger.debug(f"MCM Left Button Release: CanvasX={event.x}, CanvasY={event.y}") # Usa module_logger
if not self._is_left_button_pressed: # Verifica se il bottone era stato premuto
logger.debug("MCM Left Button Release: Button was not previously pressed. Ignoring.")
self._drag_start_x_canvas, self._drag_start_y_canvas = None, None # Resetta per sicurezza
return return
logger.debug( self._is_left_button_pressed = False # Resetta lo stato del bottone
f"MCM _on_left_button_release: CanvasX={event.x}, CanvasY={event.y}"
) clicked_flight_icao: Optional[str] = None # Per memorizzare l'ICAO del volo cliccato
if not self._is_left_button_pressed:
logger.debug( if self._drag_start_x_canvas is not None and self._drag_start_y_canvas is not None:
"MCM _on_left_button_release: Button was not pressed. Ignoring." drag_threshold_px = 10 # Soglia per distinguere click da drag
)
return
self._is_left_button_pressed = False
if (
self._drag_start_x_canvas is not None
and self._drag_start_y_canvas is not None
):
drag_thresh = 5
dx = abs(event.x - self._drag_start_x_canvas) dx = abs(event.x - self._drag_start_x_canvas)
dy = abs(event.y - self._drag_start_y_canvas) dy = abs(event.y - self._drag_start_y_canvas)
logger.debug(
f"MCM _on_left_button_release: Drag dx={dx}, dy={dy}. Threshold={drag_thresh}" is_click = (dx < drag_threshold_px and dy < drag_threshold_px)
) logger.debug(f"MCM Left Button Release: dx={dx}, dy={dy}. Is click: {is_click}")
if dx < drag_thresh and dy < drag_thresh: # È un click
logger.debug(f"MCM _on_left_button_release: Detected as a click.") if is_click:
if ( logger.debug("MCM Left Button Release: Detected as a map click.")
self._current_map_geo_bounds_gui is not None if self._current_map_geo_bounds_gui is not None and self._map_photo_image is not None:
and self._map_photo_image is not None
):
try: try:
map_pixel_shape = ( map_pixel_shape = (self._map_photo_image.width(), self._map_photo_image.height())
self._map_photo_image.width(), clicked_lon, clicked_lat = map_utils._pixel_to_geo( # Usa map_drawing._pixel_to_geo
self._map_photo_image.height(), event.x, event.y,
)
logger.debug(
f"MCM _on_left_button_release: Using map_pixel_shape={map_pixel_shape} and bounds={self._current_map_geo_bounds_gui} for geo conversion."
)
clicked_lon, clicked_lat = _pixel_to_geo(
event.x,
event.y,
self._current_map_geo_bounds_gui, self._current_map_geo_bounds_gui,
map_pixel_shape, map_pixel_shape
) )
if clicked_lon is not None and clicked_lat is not None: if clicked_lon is not None and clicked_lat is not None:
logger.info( logger.info(f"Map Left-Clicked at Geo ({clicked_lat:.5f}, {clicked_lon:.5f}) from Canvas ({event.x},{event.y})")
f"Map Left-Clicked at Geo ({clicked_lat:.5f}, {clicked_lon:.5f}) from Canvas ({event.x},{event.y})" if self.app_controller and hasattr(self.app_controller, "on_map_left_click"):
) self.app_controller.on_map_left_click(clicked_lat, clicked_lon, event.x_root, event.y_root)
if self.app_controller and hasattr(
self.app_controller, "on_map_left_click" # --- Logica per identificare il volo cliccato ---
): min_dist_sq_to_flight = float('inf')
self.app_controller.on_map_left_click( # Soglia di click in pixel per selezionare un aereo, al quadrato per evitare sqrt
clicked_lat, clicked_lon, event.x_root, event.y_root flight_click_radius_px_sq = (15 * 15)
)
else: with self._map_data_lock: # Accedi in modo sicuro alla lista dei voli
logger.warning( flights_on_map = self._current_flights_to_display_gui
f"Failed to convert left click pixel ({event.x},{event.y}) to geo. Current map bounds: {self._current_map_geo_bounds_gui}"
) if flights_on_map: # Solo se ci sono voli da controllare
except Exception as e_click_convert: for flight in flights_on_map:
logger.error( if flight.latitude is not None and flight.longitude is not None:
f"Error during left click geo conversion: {e_click_convert}", # Converte la posizione del volo in pixel sulla mappa attuale
exc_info=True, flight_px_coords = map_drawing._geo_to_pixel_on_unscaled_map(
) flight.latitude, flight.longitude,
else: self._current_map_geo_bounds_gui, # Bounds della mappa visualizzata
logger.warning( map_pixel_shape # Dimensioni in pixel della mappa visualizzata
"Map context missing for left click geo conversion (_current_map_geo_bounds_gui or _map_photo_image is None)." )
) if flight_px_coords:
else: # È un drag # Calcola la distanza al quadrato tra il click e l'aereo
# La logica di panning con drag è più complessa, per ora gestiamo solo il click dist_sq = (event.x - flight_px_coords[0])**2 + (event.y - flight_px_coords[1])**2
logger.debug( if dist_sq < flight_click_radius_px_sq and dist_sq < min_dist_sq_to_flight:
"MCM _on_left_button_release: Detected as a drag, not a click. (Drag Panning TBD)" min_dist_sq_to_flight = dist_sq
) clicked_flight_icao = flight.icao24
if clicked_flight_icao:
logger.info(f"Flight selected by click: {clicked_flight_icao}")
if self.app_controller and hasattr(self.app_controller, "request_detailed_flight_info"):
self.app_controller.request_detailed_flight_info(clicked_flight_icao)
else:
logger.info("No specific flight selected by click (click was on map but not near an aircraft). Clearing details.")
if self.app_controller and hasattr(self.app_controller, "request_detailed_flight_info"):
self.app_controller.request_detailed_flight_info("") # Invia ICAO vuoto per pulire il pannello
else: # clicked_lon/lat is None
logger.warning(f"Failed to convert left click pixel ({event.x},{event.y}) to geo coordinates.")
if self.app_controller and hasattr(self.app_controller, "request_detailed_flight_info"):
self.app_controller.request_detailed_flight_info("") # Pulisci dettagli se il click non è valido
except Exception as e_click_processing:
logger.error(f"Error during left click processing (geo conversion or flight selection): {e_click_processing}", exc_info=True)
if self.app_controller and hasattr(self.app_controller, "request_detailed_flight_info"):
self.app_controller.request_detailed_flight_info("") # Pulisci in caso di errore
else: # Manca il contesto della mappa (_current_map_geo_bounds_gui o _map_photo_image)
logger.warning("Map context missing for left click geo conversion or flight selection.")
if self.app_controller and hasattr(self.app_controller, "request_detailed_flight_info"):
self.app_controller.request_detailed_flight_info("")
else: # Era un drag
logger.debug("MCM Left Button Release: Detected as a drag. Panning logic (if any) would go here.")
# Se implementi il drag-to-pan, qui non faresti nulla per la selezione dei voli.
# Resetta le coordinate di inizio drag
self._drag_start_x_canvas, self._drag_start_y_canvas = None, None self._drag_start_x_canvas, self._drag_start_y_canvas = None, None
def _on_right_click(self, event: tk.Event): def _on_right_click(self, event: tk.Event):