Source code for sec_interp.gui.main_dialog_tools
from __future__ import annotations
"""Map tool management module for SecInterp main dialog.
This module handles the initialization and orchestration of map tools
(pan, measure) used in the preview canvas.
"""
from typing import TYPE_CHECKING, Any
from qgis.gui import QgsMapTool, QgsMapToolPan
from .tools.interpretation_tool import ProfileInterpretationTool
from .tools.measure_tool import ProfileMeasureTool
if TYPE_CHECKING:
from .main_dialog import SecInterpDialog
[docs]
class DialogToolManager:
"""Manages map tools and related event handling for the preview canvas."""
[docs]
def __init__(
self,
dialog: SecInterpDialog,
pan_tool: Optional[QgsMapTool] = None,
measure_tool: Optional[ProfileMeasureTool] = None,
interpretation_tool: Optional[ProfileInterpretationTool] = None,
):
"""Initialize tool manager with reference to parent dialog.
Args:
dialog: The :class:`sec_interp.gui.main_dialog.SecInterpDialog` instance
pan_tool: Optional pan tool for injection
measure_tool: Optional measure tool for injection
interpretation_tool: Optional interpretation tool for injection
"""
self.dialog = dialog
self.pan_tool = pan_tool
self.measure_tool = measure_tool
self.interpretation_tool = interpretation_tool
[docs]
def initialize_tools(self) -> None:
"""Create and configure map tools if not already provided."""
if not self.pan_tool:
self.pan_tool = QgsMapToolPan(self.dialog.preview_widget.canvas)
if not self.measure_tool:
self.measure_tool = ProfileMeasureTool(self.dialog.preview_widget.canvas)
if not self.interpretation_tool:
self.interpretation_tool = ProfileInterpretationTool(self.dialog.preview_widget.canvas)
# Connect polygonFinished signal to dialog handler
self.interpretation_tool.polygonFinished.connect(self.dialog.on_interpretation_finished)
self.dialog.preview_widget.canvas.setMapTool(self.pan_tool)
[docs]
def toggle_measure_tool(self, checked: bool) -> None:
"""Toggle between measurement and pan tools.
Args:
checked: True to activate measure tool, False for pan tool.
"""
if checked:
# Reset any previous measurement when starting new one
self.measure_tool.reset()
self.dialog.preview_widget.canvas.setMapTool(self.measure_tool)
self.measure_tool.activate()
# Show finalize button when measurement tool is active
self.dialog.preview_widget.btn_finalize.setVisible(True)
else:
self.dialog.preview_widget.canvas.setMapTool(self.pan_tool)
self.pan_tool.activate()
# Hide finalize button when measurement tool is inactive
self.dialog.preview_widget.btn_finalize.setVisible(False)
[docs]
def activate_default_tool(self) -> None:
"""Set the default (pan) tool."""
self.dialog.preview_widget.canvas.setMapTool(self.pan_tool)
self.pan_tool.activate()
[docs]
def toggle_interpretation_tool(self, checked: bool) -> None:
"""Toggle between interpretation and pan tools.
Args:
checked: True to activate interpretation tool, False for pan tool.
"""
if checked:
# Deactivate measure tool if active
self.dialog.preview_widget.btn_measure.setChecked(False)
# Reset and activate interpretation tool
self.interpretation_tool.reset()
self.dialog.preview_widget.canvas.setMapTool(self.interpretation_tool)
self.interpretation_tool.activate()
else:
self.dialog.preview_widget.canvas.setMapTool(self.pan_tool)
self.pan_tool.activate()
[docs]
def update_measurement_display(self, metrics: dict[str, Any]) -> None:
"""Display measurement results from multi-point tool.
Args:
metrics: Dictionary containing measurement data.
"""
if not metrics or metrics.get("point_count", 0) < 2:
return
total_dist = metrics.get("total_distance", 0)
horiz_dist = metrics.get("horizontal_distance", 0)
elev_change = metrics.get("elevation_change", 0)
avg_slope = metrics.get("avg_slope", 0)
seg_count = metrics.get("segment_count", 0)
point_count = metrics.get("point_count", 0)
# Format result text with HTML for better presentation
msg = (
f"<b>{self.dialog.tr('Multi-Point Measurement')}</b><br>"
f"<b>{self.dialog.tr('Points')}:</b> {point_count} | <b>{self.dialog.tr('Segments')}:</b> {seg_count}<br>"
f"<b>{self.dialog.tr('Total Distance')}:</b> {total_dist:.2f} m<br>"
f"<b>{self.dialog.tr('Horizontal Distance')}:</b> {horiz_dist:.2f} m<br>"
f"<b>{self.dialog.tr('Elevation Change')}:</b> {elev_change:+.2f} m<br>"
f"<b>{self.dialog.tr('Average Slope')}:</b> {avg_slope:.1f}°"
)
self.dialog.preview_widget.results_text.setHtml(msg)
# Ensure results group is expanded
self.dialog.preview_widget.results_group.setCollapsed(False)