Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gsoc 2024 rebased multiple flight tracks #2577

Merged
merged 9 commits into from
Nov 28, 2024
67 changes: 65 additions & 2 deletions mslib/msui/mpl_pathinteractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ class PathPlotter:
def __init__(self, ax, mplpath=None,
facecolor='blue', edgecolor='yellow',
linecolor='blue', markerfacecolor='red',
marker='o', label_waypoints=True):
marker='o', label_waypoints=True, line_thickness=2, line_style="Solid", line_transparency=1.0):
"""The constructor initializes the path patches, overlying line
plot and connects matplotlib signals.

Expand Down Expand Up @@ -367,11 +367,20 @@ def __init__(self, ax, mplpath=None,
self.pathpatch = pathpatch
self.pathpatch.set_animated(True) # ensure correct redrawing

# Initialize line style options
self.line_style_dict = {
"Solid": '-',
"Dashed": '--',
"Dotted": ':',
"Dash-dot": '-.'
}

# Draw the line representing flight track or profile (correct
# vertices handling for the line needs to be ensured in subclasses).
x, y = list(zip(*self.pathpatch.get_path().vertices))
self.line, = self.ax.plot(x, y, color=linecolor,
marker=marker, linewidth=2,
marker=marker, linewidth=line_thickness, linestyle=self.line_style_dict[line_style],
alpha=line_transparency,
markerfacecolor=markerfacecolor,
animated=True)

Expand All @@ -384,6 +393,26 @@ def __init__(self, ax, mplpath=None,
canvas.mpl_connect('draw_event', self.draw_callback)
self.canvas = canvas

def get_line_style_dict(self):
"""return the line style dict so other class can access it"""
return self.line_style_dict

def set_line_thickness(self, thickness):
"""Set the line thickness of the flight track."""
self.line.set_linewidth(thickness)
self.canvas.draw()

def set_line_style(self, style):
"""Set the line style of the flight track."""
if style in self.line_style_dict:
self.line.set_linestyle(self.line_style_dict[style])
self.canvas.draw()

def set_line_transparency(self, transparency):
"""Set the line transparency of the flight track."""
self.line.set_alpha(transparency)
self.canvas.draw()

def draw_callback(self, event):
"""Called when the figure is redrawn. Stores background data (for later
restoration) and draws artists.
Expand Down Expand Up @@ -932,6 +961,23 @@ def __init__(self, ax, waypoints, redraw_xaxis=None, clear_figure=None, numintpo
self.clear_figure = clear_figure
super().__init__(plotter=plotter, waypoints=waypoints)

def set_line_thickness(self, thickness):
"""Set the thickness of the line representing the flight track."""
self.plotter.line.set_linewidth(thickness)
self.redraw_figure()

def set_line_style(self, style):
"""Set the style of the line representing the flight track."""
line_style_dict = self.plotter.get_line_style_dict()
if style in line_style_dict:
self.plotter.set_line_style(style)
self.redraw_figure()

def set_line_transparency(self, transparency):
"""Set the transparency of the line representing the flight track."""
self.plotter.line.set_alpha(transparency)
self.redraw_figure()

def redraw_figure(self):
"""For the side view, changes in the horizontal position of a waypoint
(including moved waypoints, new or deleted waypoints) make a complete
Expand Down Expand Up @@ -1129,6 +1175,23 @@ def __init__(self, mplmap, waypoints,
super().__init__(plotter=plotter, waypoints=waypoints)
self.redraw_path()

def set_line_thickness(self, thickness):
"""Set the thickness of the line representing the flight track."""
self.plotter.line.set_linewidth(thickness)
self.redraw_path()

def set_line_style(self, style):
"""Set the style of the line representing the flight track."""
line_style_dict = self.plotter.get_line_style_dict()
if style in line_style_dict:
self.plotter.set_line_style(style)
self.redraw_path()

def set_line_transparency(self, transparency):
"""Set the transparency of the line representing the flight track."""
self.plotter.line.set_alpha(transparency)
self.redraw_path()

def appropriate_epsilon(self, px=5):
"""Determine an epsilon value appropriate for the current projection and
figure size.
Expand Down
72 changes: 71 additions & 1 deletion mslib/msui/mpl_qtwidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT, FigureCanvasQTAgg
import matplotlib.backend_bases
from PyQt5 import QtCore, QtWidgets, QtGui
from matplotlib.lines import Line2D

from mslib.utils.thermolib import convert_pressure_to_vertical_axis_measure
from mslib.utils import thermolib, FatalUserError
Expand Down Expand Up @@ -348,6 +349,36 @@ def draw_legend(self, img):
self.legimg = self.legax.imshow(img, origin=PIL_IMAGE_ORIGIN, aspect="equal", interpolation="nearest")
self.ax.figure.canvas.draw()

def draw_flightpath_legend(self, flightpath_dict):
"""
Draw the flight path legend on the plot, attached to the upper-left corner.
"""
# Clear any existing legend
if self.ax.get_legend() is not None:
self.ax.get_legend().remove()

if not flightpath_dict:
self.ax.figure.canvas.draw()
return

# Create legend handles
legend_handles = []
for name, (color, linestyle) in flightpath_dict.items():
line = Line2D([0], [0], color=color, linestyle=linestyle, linewidth=2)
legend_handles.append((line, name))

# Add legend directly to the main axis, attached to the upper-left corner
self.ax.legend(
[handle for handle, _ in legend_handles],
[name for _, name in legend_handles],
loc='upper left',
bbox_to_anchor=(0, 1), # (x, y) coordinates relative to the figure
bbox_transform=self.fig.transFigure, # Use figure coordinates
frameon=False
)

self.ax.figure.canvas.draw_idle()


class SideViewPlotter(ViewPlotter):
_pres_maj = np.concatenate([np.arange(top * 10, top, -top) for top in (10000, 1000, 100, 10)] + [[10]])
Expand Down Expand Up @@ -1280,6 +1311,17 @@ def update_ceiling(self, visible, color):
def set_settings(self, settings, save=False):
"""Apply settings to view.
"""
if settings is None:
settings = self.plotter.get_settings()
settings.setdefault("line_thickness", 2)
settings.setdefault("line_style", "Solid")
settings.setdefault("line_transparency", 1.0)
settings.setdefault("colour_ft_vertices", "blue")
settings.setdefault("colour_ft_waypoints", "red")
settings.setdefault("draw_marker", True)
settings.setdefault("draw_flighttrack", True)
settings.setdefault("label_flighttrack", True)

old_vertical_lines = self.plotter.settings["draw_verticals"]
if settings is not None:
self.plotter.set_settings(settings, save)
Expand All @@ -1303,6 +1345,11 @@ def set_settings(self, settings, save=False):
patch_facecolor=settings["colour_ft_fill"])
wpi_plotter.set_patch_visible(settings["fill_flighttrack"])
wpi_plotter.set_labels_visible(settings["label_flighttrack"])
wpi_plotter.set_line_thickness(settings["line_thickness"])
wpi_plotter.set_line_style(settings["line_style"])
wpi_plotter.set_line_transparency(
settings["line_transparency"] / 100.0 if settings["line_transparency"] > 1 else settings[
"line_transparency"]) # Normalize the (transparency) value

if self.waypoints_model is not None \
and settings["draw_verticals"] != old_vertical_lines:
Expand Down Expand Up @@ -1623,6 +1670,13 @@ def draw_legend(self, img):
# required so that it is actually drawn...
QtWidgets.QApplication.processEvents()

def update_flightpath_legend(self, flightpath_dict):
"""
Update the flight path legend.
flightpath_dict: Dictionary where keys are flighttrack names, and values are tuples with (color, linestyle).
"""
self.plotter.draw_flightpath_legend(flightpath_dict)

def plot_satellite_overpass(self, segments):
"""Plots a satellite track on top of the map.
"""
Expand Down Expand Up @@ -1653,6 +1707,18 @@ def set_settings(self, settings, save=False):

If settings is None, apply default settings.
"""
if settings is None:
# Default value if not present
settings = self.plotter.get_settings()
settings.setdefault("line_thickness", 2)
settings.setdefault("line_style", "Solid")
settings.setdefault("line_transparency", 1.0)
settings.setdefault("colour_ft_vertices", "blue")
settings.setdefault("colour_ft_waypoints", "red")
settings.setdefault("draw_marker", True)
settings.setdefault("draw_flighttrack", True)
settings.setdefault("label_flighttrack", True)

self.plotter.set_settings(settings, save)
settings = self.get_settings()
if self.waypoints_interactor is not None:
Expand All @@ -1662,7 +1728,11 @@ def set_settings(self, settings, save=False):
wpi_plotter.show_marker = settings["draw_marker"]
wpi_plotter.set_vertices_visible(settings["draw_flighttrack"])
wpi_plotter.set_labels_visible(settings["label_flighttrack"])

wpi_plotter.set_line_thickness(settings["line_thickness"])
wpi_plotter.set_line_style(settings["line_style"])
wpi_plotter.set_line_transparency(
settings["line_transparency"] / 100.0 if settings["line_transparency"] > 1 else settings[
"line_transparency"]) # Normalize the (transparency) value
self.draw()

def set_remote_sensing_appearance(self, settings):
Expand Down
Loading
Loading