fix map with grey band
This commit is contained in:
parent
e46b86aea5
commit
7934fc8d2c
@ -157,34 +157,44 @@ class MapCanvasManager:
|
||||
self.update_map_view_for_bbox(new_bbox_dict, preserve_current_zoom_if_possible=False)
|
||||
|
||||
def update_map_view_for_bbox(self, target_bbox_dict: Dict[str, float], preserve_current_zoom_if_possible: bool = False):
|
||||
# Questa funzione ora calcola il centro e lo zoom OTTIMALI
|
||||
# per visualizzare target_bbox_dict e poi chiama recenter_and_redraw.
|
||||
if not target_bbox_dict:
|
||||
logger.warning("update_map_view_for_bbox called with no target_bbox_dict.")
|
||||
return
|
||||
|
||||
self._target_bbox_input = target_bbox_dict.copy()
|
||||
self._target_bbox_input = target_bbox_dict.copy() # Memorizza il BBox utente
|
||||
|
||||
# Se questa chiamata deriva da un'impostazione esplicita del BBox (non da pan/zoom interattivo),
|
||||
# aggiorna anche il BBox di riferimento per i voli.
|
||||
if not preserve_current_zoom_if_possible:
|
||||
self._active_api_bbox_for_flights = target_bbox_dict.copy()
|
||||
|
||||
|
||||
lat_min = target_bbox_dict['lat_min']
|
||||
lon_min = target_bbox_dict['lon_min']
|
||||
lat_max = target_bbox_dict['lat_max']
|
||||
lon_max = target_bbox_dict['lon_max']
|
||||
|
||||
center_lat = (lat_min + lat_max) / 2.0
|
||||
center_lon = (lon_min + lon_max) / 2.0
|
||||
if lon_min > lon_max:
|
||||
# Il centro della mappa sarà il centro del BBox utente
|
||||
view_center_lat = (lat_min + lat_max) / 2.0
|
||||
view_center_lon = (lon_min + lon_max) / 2.0
|
||||
if lon_min > lon_max: # Antimeridian
|
||||
center_lon_adjusted = (lon_min + (lon_max + 360.0)) / 2.0
|
||||
center_lon = center_lon_adjusted - 360.0 if center_lon_adjusted >= 180.0 else center_lon_adjusted
|
||||
view_center_lon = center_lon_adjusted - 360.0 if center_lon_adjusted >= 180.0 else center_lon_adjusted
|
||||
|
||||
logger.info(f"Updating map view for target BBox: {self._target_bbox_input}. Calculated center: ({center_lat:.4f}, {center_lon:.4f})")
|
||||
logger.info(f"Updating map view for target BBox: {self._target_bbox_input}. Target view center: ({view_center_lat:.4f}, {view_center_lon:.4f})")
|
||||
|
||||
new_zoom_level_to_use = self._current_zoom if self._current_zoom is not None and preserve_current_zoom_if_possible else DEFAULT_INITIAL_ZOOM
|
||||
# Lo zoom da usare. Se preserviamo, usiamo il corrente, altrimenti calcoliamo.
|
||||
zoom_to_use = self._current_zoom if self._current_zoom is not None and preserve_current_zoom_if_possible else DEFAULT_INITIAL_ZOOM
|
||||
|
||||
if not preserve_current_zoom_if_possible:
|
||||
calculated_zoom_val = DEFAULT_INITIAL_ZOOM
|
||||
calculated_zoom_for_target_bbox = DEFAULT_INITIAL_ZOOM
|
||||
if PYPROJ_MODULE_LOCALLY_AVAILABLE and pyproj is not None:
|
||||
try:
|
||||
geod = pyproj.Geod(ellps="WGS84")
|
||||
_, _, height_m = geod.inv(center_lon, lat_min, center_lon, lat_max)
|
||||
_, _, width_m = geod.inv(lon_min, center_lat, lon_max, center_lat)
|
||||
_, _, height_m = geod.inv(view_center_lon, lat_min, view_center_lon, lat_max)
|
||||
_, _, width_m = geod.inv(lon_min, view_center_lat, lon_max, view_center_lat)
|
||||
height_m = abs(height_m)
|
||||
width_m = abs(width_m)
|
||||
logger.debug(f"Geographic dimensions of target BBox: Width={width_m:.0f}m, Height={height_m:.0f}m")
|
||||
@ -207,54 +217,56 @@ class MapCanvasManager:
|
||||
if res_needed_for_height != float('inf') and res_needed_for_height > 0:
|
||||
target_resolution_m_px = res_needed_for_height
|
||||
valid_res_found = True
|
||||
# Modifica qui per usare max correttemente
|
||||
if res_needed_for_width != float('inf') and res_needed_for_width > 0:
|
||||
if valid_res_found:
|
||||
target_resolution_m_px = max(target_resolution_m_px, res_needed_for_width)
|
||||
else:
|
||||
target_resolution_m_px = res_needed_for_width
|
||||
current_target_res = target_resolution_m_px if valid_res_found else float('inf') # Inizializza con l'altezza se valida
|
||||
target_resolution_m_px = max(current_target_res, res_needed_for_width) # Prendi la risoluzione maggiore (zoom minore)
|
||||
valid_res_found = True
|
||||
|
||||
if not valid_res_found: target_resolution_m_px = float('inf')
|
||||
if not valid_res_found and target_resolution_m_px == float('inf'): # Se nessuna dimensione valida
|
||||
logger.warning("Could not determine valid target resolution from BBox dimensions or canvas size.")
|
||||
target_resolution_m_px = 0 # Per forzare fallback
|
||||
|
||||
logger.debug(f"Canvas: {current_canvas_width}x{current_canvas_height}. Resolutions needed H,W (m/px): {res_needed_for_height:.2f}, {res_needed_for_width:.2f}. Target res: {target_resolution_m_px:.2f} m/px")
|
||||
logger.debug(f"Canvas: {current_canvas_width}x{current_canvas_height}. Resolutions needed for target BBox (H,W) (m/px): {res_needed_for_height:.2f}, {res_needed_for_width:.2f}. Final Target res: {target_resolution_m_px:.2f} m/px")
|
||||
|
||||
if target_resolution_m_px > 0 and target_resolution_m_px != float('inf'):
|
||||
EARTH_CIRCUMFERENCE_METERS = 40075016.686
|
||||
clamped_center_lat_for_cos = max(-85.05, min(85.05, center_lat))
|
||||
clamped_center_lat_for_cos = max(-85.05, min(85.05, view_center_lat)) # Usa il centro del BBox per il calcolo dello zoom
|
||||
cos_val = math.cos(math.radians(clamped_center_lat_for_cos))
|
||||
if cos_val > 1e-9 and self.tile_manager.tile_size > 0:
|
||||
term_for_log = (EARTH_CIRCUMFERENCE_METERS * cos_val) / \
|
||||
(self.tile_manager.tile_size * target_resolution_m_px)
|
||||
if term_for_log > 0:
|
||||
precise_zoom = math.log2(term_for_log)
|
||||
calculated_zoom_val = int(round(precise_zoom))
|
||||
calculated_zoom_for_target_bbox = int(round(precise_zoom))
|
||||
max_zoom_limit = self.map_service.max_zoom if self.map_service else DEFAULT_MAX_ZOOM_FALLBACK
|
||||
new_zoom_level_to_use = max(MIN_ZOOM_LEVEL, min(calculated_zoom_val, max_zoom_limit))
|
||||
logger.info(f"Calculated zoom {new_zoom_level_to_use} to fit BBox (precise float: {precise_zoom:.2f}).")
|
||||
zoom_to_use = max(MIN_ZOOM_LEVEL, min(calculated_zoom_for_target_bbox, max_zoom_limit))
|
||||
logger.info(f"Calculated zoom {zoom_to_use} to fit target BBox (precise float: {precise_zoom:.2f}).")
|
||||
else:
|
||||
logger.warning(f"Cannot calculate zoom for BBox: term for log2 is non-positive ({term_for_log}). Using zoom {DEFAULT_INITIAL_ZOOM}.")
|
||||
new_zoom_level_to_use = DEFAULT_INITIAL_ZOOM
|
||||
logger.warning(f"Cannot calculate zoom for BBox: term for log2 non-positive. Using zoom {DEFAULT_INITIAL_ZOOM}.")
|
||||
zoom_to_use = DEFAULT_INITIAL_ZOOM
|
||||
else:
|
||||
logger.warning(f"Cannot calculate zoom for BBox: cosine of latitude or tile_size is problematic. Using zoom {DEFAULT_INITIAL_ZOOM}.")
|
||||
new_zoom_level_to_use = DEFAULT_INITIAL_ZOOM
|
||||
logger.warning(f"Cannot calculate zoom for BBox: cosine of latitude or tile_size problematic. Using zoom {DEFAULT_INITIAL_ZOOM}.")
|
||||
zoom_to_use = DEFAULT_INITIAL_ZOOM
|
||||
else:
|
||||
logger.warning(f"Cannot calculate zoom for BBox: target resolution is invalid or zero. Using zoom {DEFAULT_INITIAL_ZOOM}.")
|
||||
new_zoom_level_to_use = DEFAULT_INITIAL_ZOOM
|
||||
logger.warning(f"Cannot calculate zoom for BBox: target resolution invalid. Using zoom {DEFAULT_INITIAL_ZOOM}.")
|
||||
zoom_to_use = DEFAULT_INITIAL_ZOOM
|
||||
except Exception as e:
|
||||
logger.error(f"Error calculating zoom for BBox using pyproj: {e}. Using zoom {DEFAULT_INITIAL_ZOOM}.", exc_info=True)
|
||||
new_zoom_level_to_use = DEFAULT_INITIAL_ZOOM
|
||||
zoom_to_use = DEFAULT_INITIAL_ZOOM
|
||||
else:
|
||||
logger.warning("Pyproj module not available in MapCanvasManager, cannot accurately calculate zoom for BBox. Using default zoom.")
|
||||
new_zoom_level_to_use = DEFAULT_INITIAL_ZOOM
|
||||
logger.warning("Pyproj module not available. Using default zoom.")
|
||||
zoom_to_use = DEFAULT_INITIAL_ZOOM
|
||||
|
||||
self.recenter_and_redraw(center_lat, center_lon, new_zoom_level_to_use, ensure_bbox_is_covered=self._target_bbox_input)
|
||||
# recenter_and_redraw userà view_center_lat, view_center_lon e zoom_to_use.
|
||||
# Non passerà più `ensure_bbox_is_covered` perché il centro e lo zoom
|
||||
# sono già stati calcolati per mostrare il _target_bbox_input.
|
||||
self.recenter_and_redraw(view_center_lat, view_center_lon, zoom_to_use)
|
||||
|
||||
def recenter_and_redraw(self, center_lat: float, center_lon: float, zoom_level: int,
|
||||
ensure_bbox_is_covered: Optional[Dict[str,float]] = None):
|
||||
logger.info(f"Recentering map. Target Center: ({center_lat:.4f}, {center_lon:.4f}), Zoom: {zoom_level}")
|
||||
if ensure_bbox_is_covered:
|
||||
logger.debug(f"This redraw will ensure BBox is covered: {ensure_bbox_is_covered}")
|
||||
ensure_bbox_is_covered_dict: Optional[Dict[str, float]] = None):
|
||||
logger.info(f"Recentering map. Target View Center: ({center_lat:.4f}, {center_lon:.4f}), Zoom: {zoom_level}")
|
||||
if ensure_bbox_is_covered_dict:
|
||||
logger.debug(f"This redraw must ensure BBox is fully visible: {ensure_bbox_is_covered_dict}")
|
||||
|
||||
self._current_center_lat = center_lat
|
||||
self._current_center_lon = center_lon
|
||||
@ -262,54 +274,62 @@ class MapCanvasManager:
|
||||
|
||||
current_canvas_width = self.canvas.winfo_width()
|
||||
current_canvas_height = self.canvas.winfo_height()
|
||||
if current_canvas_width <=1 : current_canvas_width = self.canvas_width
|
||||
if current_canvas_height <=1 : current_canvas_height = self.canvas_height
|
||||
if current_canvas_width <= 1: current_canvas_width = self.canvas_width
|
||||
if current_canvas_height <= 1: current_canvas_height = self.canvas_height
|
||||
|
||||
map_fetch_geo_bounds_for_tiles: Optional[Tuple[float, float, float, float]]
|
||||
map_fetch_geo_bounds_for_tiles_tuple: Optional[Tuple[float, float, float, float]]
|
||||
|
||||
if ensure_bbox_is_covered:
|
||||
# Logica per calcolare un BBox di tile che copra `ensure_bbox_is_covered`
|
||||
# E che sia anche centrato su `center_lat`, `center_lon` e riempia il canvas
|
||||
# Questo è il caso più complesso: vogliamo vedere un BBox specifico E riempire il canvas.
|
||||
# Lo zoom è già stato calcolato in `update_map_view_for_bbox` per far entrare `ensure_bbox_is_covered`.
|
||||
# Quindi, i `map_fetch_geo_bounds_for_tiles` dovrebbero essere quelli che, a questo zoom e centro,
|
||||
# riempiono il canvas. Se questi bounds sono più piccoli di `ensure_bbox_is_covered`,
|
||||
# allora lo zoom calcolato non era sufficientemente basso.
|
||||
# Per ora, semplifichiamo: il BBox per le tile sarà quello che riempie il canvas
|
||||
# al centro/zoom calcolati (che dovrebbero già tenere conto di far entrare `ensure_bbox_is_covered`).
|
||||
map_fetch_geo_bounds_for_tiles = calculate_geographic_bbox_from_pixel_size_and_zoom(
|
||||
self._current_center_lat, self._current_center_lon,
|
||||
if ensure_bbox_is_covered_dict:
|
||||
# Caso 1: Dobbiamo visualizzare un BBox specifico (_target_bbox_input)
|
||||
# Lo zoom e il centro sono già stati calcolati da update_map_view_for_bbox
|
||||
# per far entrare questo BBox nel canvas.
|
||||
# Ora dobbiamo determinare le tile da scaricare.
|
||||
# Il BBox delle tile deve coprire almeno ensure_bbox_is_covered_dict.
|
||||
# E, per evitare barre grigie, dovrebbe anche cercare di riempire il canvas
|
||||
# mantenendo il centro e lo zoom calcolati.
|
||||
|
||||
user_bb = ensure_bbox_is_covered_dict
|
||||
|
||||
# Calcola il BBox che riempirebbe il canvas a questo centro e zoom
|
||||
canvas_fill_bbox = calculate_geographic_bbox_from_pixel_size_and_zoom(
|
||||
self._current_center_lat, self._current_center_lon, # Centro del BBox utente
|
||||
current_canvas_width, current_canvas_height,
|
||||
self._current_zoom, self.tile_manager.tile_size
|
||||
)
|
||||
if map_fetch_geo_bounds_for_tiles:
|
||||
logger.debug(f"Tile fetching for BBox coverage, calculated canvas fill bounds: {map_fetch_geo_bounds_for_tiles} at zoom {self._current_zoom}")
|
||||
|
||||
if not canvas_fill_bbox:
|
||||
logger.error("Failed to calculate canvas_fill_bbox even when ensure_bbox_is_covered was set. Using user_bbox directly.")
|
||||
map_fetch_geo_bounds_for_tiles_tuple = (
|
||||
user_bb['lon_min'], user_bb['lat_min'],
|
||||
user_bb['lon_max'], user_bb['lat_max']
|
||||
)
|
||||
else:
|
||||
logger.error("Failed to calculate canvas filling BBox even when ensure_bbox_is_covered was set.")
|
||||
# Fallback: usa direttamente ensure_bbox_is_covered per le tile, potrebbe non riempire il canvas
|
||||
map_fetch_geo_bounds_for_tiles = (
|
||||
ensure_bbox_is_covered['lon_min'], ensure_bbox_is_covered['lat_min'],
|
||||
ensure_bbox_is_covered['lon_max'], ensure_bbox_is_covered['lat_max']
|
||||
)
|
||||
logger.warning(f"Falling back to fetching tiles strictly for ensure_bbox_is_covered: {map_fetch_geo_bounds_for_tiles}")
|
||||
# Ora crea un BBox che sia l'unione del BBox utente e del BBox che riempie il canvas.
|
||||
# Questo assicura che il BBox utente sia dentro E che il canvas sia riempito.
|
||||
final_west = min(user_bb['lon_min'], canvas_fill_bbox[0])
|
||||
final_south = min(user_bb['lat_min'], canvas_fill_bbox[1])
|
||||
final_east = max(user_bb['lon_max'], canvas_fill_bbox[2])
|
||||
final_north = max(user_bb['lat_max'], canvas_fill_bbox[3])
|
||||
map_fetch_geo_bounds_for_tiles_tuple = (final_west, final_south, final_east, final_north)
|
||||
logger.debug(f"Combined BBox (user & canvas fill) for tile fetching: {map_fetch_geo_bounds_for_tiles_tuple} at zoom {self._current_zoom}")
|
||||
|
||||
else: # Pan/Zoom interattivo
|
||||
map_fetch_geo_bounds_for_tiles = calculate_geographic_bbox_from_pixel_size_and_zoom(
|
||||
else: # Caso 2: Pan/Zoom interattivo, non c'è un "ensure_bbox_is_covered_dict"
|
||||
map_fetch_geo_bounds_for_tiles_tuple = calculate_geographic_bbox_from_pixel_size_and_zoom(
|
||||
self._current_center_lat, self._current_center_lon,
|
||||
current_canvas_width, current_canvas_height,
|
||||
self._current_zoom, self.tile_manager.tile_size
|
||||
)
|
||||
if map_fetch_geo_bounds_for_tiles:
|
||||
logger.debug(f"Tile fetching for interactive pan/zoom (canvas-fill): {map_fetch_geo_bounds_for_tiles} at zoom {self._current_zoom}")
|
||||
if map_fetch_geo_bounds_for_tiles_tuple:
|
||||
logger.debug(f"Tile fetching for interactive pan/zoom (canvas-fill): {map_fetch_geo_bounds_for_tiles_tuple} at zoom {self._current_zoom}")
|
||||
|
||||
if not map_fetch_geo_bounds_for_tiles:
|
||||
if not map_fetch_geo_bounds_for_tiles_tuple:
|
||||
logger.error("Failed to determine geographic bounds for tile fetching. Cannot draw map.")
|
||||
self._clear_canvas_content()
|
||||
return
|
||||
|
||||
tile_xy_ranges = get_tile_ranges_for_bbox(map_fetch_geo_bounds_for_tiles, self._current_zoom)
|
||||
tile_xy_ranges = get_tile_ranges_for_bbox(map_fetch_geo_bounds_for_tiles_tuple, self._current_zoom)
|
||||
if not tile_xy_ranges:
|
||||
logger.error(f"Failed to get tile ranges for fetch_bounds {map_fetch_geo_bounds_for_tiles}. Cannot draw map.")
|
||||
logger.error(f"Failed to get tile ranges for fetch_bounds {map_fetch_geo_bounds_for_tiles_tuple}. Cannot draw map.")
|
||||
self._clear_canvas_content()
|
||||
return
|
||||
logger.debug(f"Tile ranges for current view: X={tile_xy_ranges[0]}, Y={tile_xy_ranges[1]}")
|
||||
@ -326,11 +346,11 @@ class MapCanvasManager:
|
||||
actual_stitched_geo_bounds = self.tile_manager._get_bounds_for_tile_range(self._current_zoom, tile_xy_ranges)
|
||||
if not actual_stitched_geo_bounds:
|
||||
logger.error("Failed to get actual geographic bounds of stitched tiles. Using calculated fetch_bounds as fallback.")
|
||||
self._current_map_geo_bounds = map_fetch_geo_bounds_for_tiles
|
||||
self._current_map_geo_bounds = map_fetch_geo_bounds_for_tiles_tuple
|
||||
else:
|
||||
self._current_map_geo_bounds = actual_stitched_geo_bounds
|
||||
|
||||
logger.debug(f"Actual geographic bounds of final stitched map: {self._current_map_geo_bounds}")
|
||||
logger.debug(f"Actual geographic bounds of final stitched map (self._current_map_geo_bounds): {self._current_map_geo_bounds}")
|
||||
self._map_pil_image = stitched_map_pil
|
||||
self._redraw_canvas_content()
|
||||
|
||||
@ -517,28 +537,74 @@ class MapCanvasManager:
|
||||
|
||||
if new_zoom != self._current_zoom:
|
||||
logger.info(f"Zoom changed from {self._current_zoom} to {new_zoom}")
|
||||
# Durante lo zoom interattivo, non c'è un "ensure_bbox_is_covered" fisso.
|
||||
# Il _target_bbox_input (contorno blu) rimane, ma la vista si adatta.
|
||||
self.recenter_and_redraw(target_center_lat, target_center_lon, new_zoom, ensure_bbox_is_covered=None)
|
||||
self.recenter_and_redraw(target_center_lat, target_center_lon, new_zoom)
|
||||
else:
|
||||
logger.debug(f"Zoom unchanged (already at min/max: {self._current_zoom})")
|
||||
|
||||
def _on_mouse_button_press(self, event: tk.Event):
|
||||
if not self.canvas.winfo_exists(): return
|
||||
self._drag_start_x = event.x
|
||||
self._drag_start_y = event.y
|
||||
self._is_dragging = True
|
||||
# Salva il punto di inizio del drag in coordinate CANVAS
|
||||
self._drag_start_x_canvas = event.x
|
||||
self._drag_start_y_canvas = event.y
|
||||
# Salva anche il centro geografico corrente all'inizio del drag
|
||||
if self._current_center_lat is not None and self._current_center_lon is not None:
|
||||
self._drag_start_center_lon = self._current_center_lon
|
||||
self._drag_start_center_lat = self._current_center_lat
|
||||
else: # Non dovrebbe succedere se la mappa è visualizzata
|
||||
self._drag_start_center_lon = None
|
||||
self._drag_start_center_lat = None
|
||||
|
||||
self._is_dragging = False # Non considerarlo un drag finché non c'è movimento
|
||||
self.canvas.config(cursor="fleur")
|
||||
logger.debug(f"Mouse button press at ({event.x}, {event.y}) for panning.")
|
||||
logger.debug(f"Mouse button press at ({event.x}, {event.y}). Ready for potential pan.")
|
||||
|
||||
def _on_mouse_drag(self, event: tk.Event):
|
||||
if not self._is_dragging or self._drag_start_x is None or self._drag_start_y is None or \
|
||||
self._current_map_geo_bounds is None or not self.canvas.winfo_exists() or \
|
||||
self._current_center_lat is None or self._current_center_lon is None or self._current_zoom is None:
|
||||
if self._drag_start_x_canvas is None or self._drag_start_y_canvas is None or \
|
||||
self._drag_start_center_lon is None or self._drag_start_center_lat is None or \
|
||||
self._current_map_geo_bounds is None or not self.canvas.winfo_exists() or self._current_zoom is None:
|
||||
return
|
||||
|
||||
dx_pixel = event.x - self._drag_start_x
|
||||
dy_pixel = event.y - self._drag_start_y
|
||||
self._is_dragging = True # Il mouse si è mosso mentre era premuto
|
||||
|
||||
# --- Logica per visualizzare un'anteprima del pan (OPZIONALE e più complesso) ---
|
||||
# Si potrebbe spostare l'immagine PhotoImage esistente sul canvas SPOSTANDO l'item_id
|
||||
# self.canvas.move(self._canvas_image_id, dx_pixel, dy_pixel)
|
||||
# Questo però non ricarica le tile, mostra solo la stessa immagine spostata.
|
||||
# Per ora, omettiamo l'anteprima per semplicità e ridisegniamo solo al rilascio.
|
||||
# Potremmo cambiare il cursore per indicare il drag.
|
||||
# logger.debug(f"Dragging to ({event.x}, {event.y})") # Troppo verboso
|
||||
pass
|
||||
|
||||
def _on_mouse_button_release(self, event: tk.Event):
|
||||
if not self.canvas.winfo_exists():
|
||||
self.canvas.config(cursor="")
|
||||
return
|
||||
|
||||
self.canvas.config(cursor="") # Ripristina cursore
|
||||
|
||||
if not self._is_dragging: # Se non c'è stato drag, è stato un click semplice
|
||||
logger.debug("Mouse button release without dragging (simple click). Action handled by specific button bindings (e.g., right-click).")
|
||||
self._drag_start_x_canvas = None # Resetta per sicurezza
|
||||
self._drag_start_y_canvas = None
|
||||
self._drag_start_center_lon = None
|
||||
self._drag_start_center_lat = None
|
||||
self._is_dragging = False
|
||||
return
|
||||
|
||||
# Se c'è stato un drag (self._is_dragging è True)
|
||||
logger.debug(f"Mouse button release after drag to ({event.x}, {event.y}). Finalizing pan.")
|
||||
|
||||
if self._drag_start_x_canvas is None or self._drag_start_y_canvas is None or \
|
||||
self._drag_start_center_lon is None or self._drag_start_center_lat is None or \
|
||||
self._current_map_geo_bounds is None or self._current_zoom is None :
|
||||
logger.warning("Cannot finalize pan: drag start state or map context is missing.")
|
||||
self._is_dragging = False
|
||||
self._drag_start_x_canvas = None
|
||||
self._drag_start_y_canvas = None
|
||||
return
|
||||
|
||||
dx_pixel = event.x - self._drag_start_x_canvas
|
||||
dy_pixel = event.y - self._drag_start_y_canvas
|
||||
|
||||
map_width_deg = self._current_map_geo_bounds[2] - self._current_map_geo_bounds[0]
|
||||
map_height_deg = self._current_map_geo_bounds[3] - self._current_map_geo_bounds[1]
|
||||
@ -550,7 +616,8 @@ class MapCanvasManager:
|
||||
if current_canvas_height <=1 : current_canvas_height = self.canvas_height
|
||||
|
||||
if current_canvas_width <= 0 or current_canvas_height <= 0:
|
||||
logger.warning("Cannot pan, canvas dimensions are zero.")
|
||||
logger.warning("Cannot finalize pan, canvas dimensions are zero.")
|
||||
self._is_dragging = False
|
||||
return
|
||||
|
||||
deg_per_pixel_lon = map_width_deg / current_canvas_width
|
||||
@ -559,24 +626,24 @@ class MapCanvasManager:
|
||||
delta_lon = -dx_pixel * deg_per_pixel_lon
|
||||
delta_lat = dy_pixel * deg_per_pixel_lat
|
||||
|
||||
new_center_lon = self._current_center_lon + delta_lon
|
||||
new_center_lat = self._current_center_lat + delta_lat
|
||||
# Il nuovo centro è calcolato rispetto al centro che avevamo ALL'INIZIO del drag
|
||||
new_center_lon = self._drag_start_center_lon + delta_lon
|
||||
new_center_lat = self._drag_start_center_lat + delta_lat
|
||||
|
||||
new_center_lon = (new_center_lon + 180) % 360 - 180
|
||||
new_center_lat = max(-85.05112878, min(85.05112878, new_center_lat)) # Limiti Web Mercator
|
||||
new_center_lat = max(-85.05112878, min(85.05112878, new_center_lat))
|
||||
|
||||
self.recenter_and_redraw(new_center_lat, new_center_lon, self._current_zoom, ensure_bbox_is_covered=None)
|
||||
logger.info(f"Pan finalized. Old center: ({self._drag_start_center_lat:.4f}, {self._drag_start_center_lon:.4f}), New center: ({new_center_lat:.4f}, {new_center_lon:.4f})")
|
||||
|
||||
self._drag_start_x = event.x
|
||||
self._drag_start_y = event.y
|
||||
# Ridisegna la mappa con il nuovo centro, mantenendo lo zoom.
|
||||
# Non c'è un "ensure_bbox_is_covered" specifico per il pan.
|
||||
self.recenter_and_redraw(new_center_lat, new_center_lon, self._current_zoom, ensure_bbox_is_covered_dict=None) #MODIFICATO nome parametro
|
||||
|
||||
def _on_mouse_button_release(self, event: tk.Event):
|
||||
if not self.canvas.winfo_exists(): return
|
||||
self._is_dragging = False
|
||||
self._drag_start_x = None
|
||||
self._drag_start_y = None
|
||||
self.canvas.config(cursor="")
|
||||
logger.debug("Mouse button release, panning finished.")
|
||||
self._drag_start_x_canvas = None
|
||||
self._drag_start_y_canvas = None
|
||||
self._drag_start_center_lon = None
|
||||
self._drag_start_center_lat = None
|
||||
|
||||
def _on_right_click(self, event: tk.Event):
|
||||
if not self.canvas.winfo_exists(): return
|
||||
|
||||
Loading…
Reference in New Issue
Block a user