Compare commits

..
6 Commits
9 changed files with 139 additions and 58 deletions

No files matched your search

+6 -1
View File
@@ -17,6 +17,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import queue import queue
import types
import random import random
import logging import logging
import numpy as np import numpy as np
@@ -806,7 +807,11 @@ class ProfileXYZ(Profile, SQLSubModel):
return poly return poly
def wet_points(self, z): def wet_points(self, z):
left, right = self.get_water_limits(z) limits = self.get_water_limits(z)
if isinstance(limits, types.GeneratorType):
limits = next(limits)
left, right = limits
points = list(filter(lambda p: p.z < z, self._points)) points = list(filter(lambda p: p.z < z, self._points))
points = [left] + points + [right] points = [left] + points + [right]
+1 -1
View File
@@ -54,7 +54,7 @@ class Plot(PamhyrPlot):
self._isometric_axis = False self._isometric_axis = False
self._auto_relim_update = True self._auto_relim_update = True
self._autoscale_update = False self._autoscale_update = True
def custom_ticks(self): def custom_ticks(self):
if self.data.header[0] != "time": if self.data.header[0] != "time":
+4 -1
View File
@@ -185,7 +185,10 @@ class EditBoundaryConditionWindow(PamhyrWindow):
self.canvas = MplCanvas(width=5, height=4, dpi=100) self.canvas = MplCanvas(width=5, height=4, dpi=100)
self.canvas.setObjectName("canvas") self.canvas.setObjectName("canvas")
self.toolbar = PamhyrPlotToolbar( self.toolbar = PamhyrPlotToolbar(
self.canvas, self self.canvas, self, items=[
"home", "move", "zoom", "save",
"iso", "back/forward"
]
) )
self.verticalLayout.addWidget(self.toolbar) self.verticalLayout.addWidget(self.toolbar)
self.verticalLayout.addWidget(self.canvas) self.verticalLayout.addWidget(self.canvas)
+1 -1
View File
@@ -42,7 +42,7 @@ class PlotAC(PamhyrPlot):
self._isometric_axis = False self._isometric_axis = False
self._auto_relim_update = True self._auto_relim_update = True
self._autoscale_update = False self._autoscale_update = True
@property @property
def river(self): def river(self):
+36 -9
View File
@@ -30,6 +30,14 @@ _translate = QCoreApplication.translate
class PlotRKC(PamhyrPlot): class PlotRKC(PamhyrPlot):
# Class attributes: PlotRKZ (frictions) does not call this __init__
_selected = None # Selected hydraulic structure, in blue
profile = None
line_rk_zmin = None
line_rk_zmin_zmax = None
hs_vlines = None
_hs_drawn = [] # Structures of hs_vlines, in order
def __init__(self, canvas=None, trad=None, toolbar=None, def __init__(self, canvas=None, trad=None, toolbar=None,
river=None, reach=None, profile=None, river=None, reach=None, profile=None,
parent=None): parent=None):
@@ -133,19 +141,14 @@ class PlotRKC(PamhyrPlot):
vymin = [] vymin = []
vymax = [] vymax = []
self.anotate_lst = [] self.anotate_lst = []
self._hs_drawn = []
hs_color = [] hs_color = []
index = self.parent.tableView.selectedIndexes() for hs in lhs:
for i, hs in enumerate(lhs):
section = hs.input_section section = hs.input_section
if section is None: if section is None:
continue continue
if i == index[0].row(): color = self._hs_color(hs)
color = "blue"
elif hs.enabled:
color = "red"
else:
color = "darkgrey"
x = section.rk x = section.rk
if x is not None: if x is not None:
@@ -163,6 +166,7 @@ class PlotRKC(PamhyrPlot):
vymin.append(min(z_min)) vymin.append(min(z_min))
vymax.append(max(z_max)) vymax.append(max(z_max))
hs_color.append(color) hs_color.append(color)
self._hs_drawn.append(hs)
self.hs_vlines = self.canvas.axes.vlines( self.hs_vlines = self.canvas.axes.vlines(
x=vx, ymin=vymin, ymax=vymax, x=vx, ymin=vymin, ymax=vymax,
@@ -171,6 +175,28 @@ class PlotRKC(PamhyrPlot):
color=hs_color, color=hs_color,
) )
def _hs_color(self, hs):
if hs is self._selected:
return "blue"
if hs.enabled:
return "red"
return "darkgrey"
def set_selected(self, hs):
"""Draw the selected structure in blue, without redrawing the
plot (the view is kept)"""
self._selected = hs
if self.hs_vlines is None:
return
colors = [self._hs_color(h) for h in self._hs_drawn]
if colors:
self.hs_vlines.set_color(colors)
for annotation, color in zip(self.anotate_lst, colors):
annotation.set_color(color)
self.canvas.figure.canvas.draw_idle()
def color_highlight(self, highlight): def color_highlight(self, highlight):
reach = self._current_reach reach = self._current_reach
@@ -254,7 +280,8 @@ class PlotRKC(PamhyrPlot):
closest = self._closest_profile(event) closest = self._closest_profile(event)
index = self.parent.tableView.selectedIndexes() index = self.parent.tableView.selectedIndexes()
if self.parent._table is not None: # Moves the selected structure: nothing to do without selection
if self.parent._table is not None and len(index) > 2:
self.parent._table.setData(index[2], closest) self.parent._table.setData(index[2], closest)
return return
+2 -1
View File
@@ -96,7 +96,8 @@ class ComboBoxDelegate(QItemDelegate):
reach = self._data.hydraulic_structures\ reach = self._data.hydraulic_structures\
.get(index.row())\ .get(index.row())\
.input_reach .input_reach
profiles = list( # No reach selected yet: no profile to choose from
profiles = [] if reach is None else list(
filter( filter(
lambda p: p.display_name() == text, lambda p: p.display_name() == text,
reach.reach.profiles reach.reach.profiles
+62 -39
View File
@@ -130,11 +130,13 @@ class HydraulicStructuresWindow(PamhyrWindow):
self._checkbox = self.find(QCheckBox, f"checkBox") self._checkbox = self.find(QCheckBox, f"checkBox")
self._set_checkbox_state() self._set_checkbox_state()
_toolbar_items = ["home", "move", "zoom", "save", "iso", "back/forward"]
def setup_plots(self): def setup_plots(self):
self.canvas = MplCanvas(width=5, height=4, dpi=100) self.canvas = MplCanvas(width=5, height=4, dpi=100)
self.canvas.setObjectName("canvas") self.canvas.setObjectName("canvas")
self.toolbar = PamhyrPlotToolbar( self.toolbar = PamhyrPlotToolbar(
self.canvas, self self.canvas, self, items=self._toolbar_items
) )
self.plot_layout = self.find(QVBoxLayout, "verticalLayout") self.plot_layout = self.find(QVBoxLayout, "verticalLayout")
self.plot_layout.addWidget(self.toolbar) self.plot_layout.addWidget(self.toolbar)
@@ -143,7 +145,7 @@ class HydraulicStructuresWindow(PamhyrWindow):
self.plot_rkc = PlotRKC( self.plot_rkc = PlotRKC(
canvas=self.canvas, canvas=self.canvas,
river=self._study.river, river=self._study.river,
reach=None, reach=self._displayed_reach(None),
profile=None, profile=None,
trad=self._trad, trad=self._trad,
toolbar=self.toolbar, toolbar=self.toolbar,
@@ -154,7 +156,7 @@ class HydraulicStructuresWindow(PamhyrWindow):
self.canvas_2 = MplCanvas(width=5, height=4, dpi=100) self.canvas_2 = MplCanvas(width=5, height=4, dpi=100)
self.canvas_2.setObjectName("canvas_2") self.canvas_2.setObjectName("canvas_2")
self.toolbar_2 = PamhyrPlotToolbar( self.toolbar_2 = PamhyrPlotToolbar(
self.canvas_2, self self.canvas_2, self, items=self._toolbar_items
) )
self.plot_layout_2 = self.find(QVBoxLayout, "verticalLayout_2") self.plot_layout_2 = self.find(QVBoxLayout, "verticalLayout_2")
self.plot_layout_2.addWidget(self.toolbar_2) self.plot_layout_2.addWidget(self.toolbar_2)
@@ -183,7 +185,7 @@ class HydraulicStructuresWindow(PamhyrWindow):
table = self.find(QTableView, "tableView") table = self.find(QTableView, "tableView")
table.selectionModel()\ table.selectionModel()\
.selectionChanged\ .selectionChanged\
.connect(self.update) .connect(self.update_selection)
self._table.dataChanged.connect(self.update) self._table.dataChanged.connect(self.update)
self._table.layoutChanged.connect(self.update) self._table.layoutChanged.connect(self.update)
@@ -282,44 +284,65 @@ class HydraulicStructuresWindow(PamhyrWindow):
) )
def update(self): def update(self):
"""Data changed: plots redrawn, fitted to their data"""
self._set_checkbox_state() self._set_checkbox_state()
self._update_clear_plot() self._update_plots(redraw=True)
def _update_clear_plot(self): def update_selection(self):
"""Selection changed: the selected structure is drawn in blue,
the view is kept (unless its reach is another one)"""
self._set_checkbox_state()
self._update_plots(redraw=False)
def _selected_structure(self):
rows = self.index_selected_rows() rows = self.index_selected_rows()
if len(rows) == 0 or len(self._hs_lst) == 0: if len(rows) == 0 or len(self._hs_lst) == 0:
self._update_clear_all() return None
return self._hs_lst.get(rows[0])
def _displayed_reach(self, selected):
"""Reach of the selected structure; otherwise the reach already
shown, the reach of the first structure, or the first reach"""
edges = self._study.river.enable_edges()
if selected is not None and selected.input_reach in edges:
return selected.input_reach
current = getattr(self, "plot_rkc", None)
if current is not None and current._current_reach in edges:
return current._current_reach
for hs in self._hs_lst.lst:
if hs.input_reach in edges:
return hs.input_reach
return edges[0] if len(edges) > 0 else None
def _update_plots(self, redraw=True):
selected = self._selected_structure()
reach = self._displayed_reach(selected)
self.plot_rkc._selected = selected
if redraw or reach is not self.plot_rkc._current_reach:
self.plot_rkc.set_reach(reach)
else:
self.plot_rkc.set_selected(selected)
self._update_profile_plot(selected, reach)
def _update_profile_plot(self, selected, reach):
profile = None
if (selected is not None and reach is not None
and selected.input_section is not None):
profiles = reach.reach.get_profiles_from_rk(
float(selected.input_section.rk)
)
if profiles:
profile = profiles[0]
if profile is None:
self.plot_ac.clear()
self.plot_ac.update_idle()
return return
reach = self._hs_lst.get(rows[0]).input_reach self.plot_ac.set_reach(reach)
if reach is not None: self.plot_ac.set_profile(profile)
self.plot_rkc.set_reach(reach)
self.plot_ac.set_reach(reach)
profile = self._hs_lst.get(rows[0]).input_section
if profile is not None:
profiles = reach.reach\
.get_profiles_from_rk(
float(profile.rk)
)
if len(profiles) != 0 and profiles is not None:
profile = profiles[0]
self.plot_rkc.set_profile(profile)
self.plot_ac.set_profile(profile)
else:
self._update_clear_profile()
else:
self._update_clear_profile()
else:
self._update_clear_all()
def _update_clear_all(self):
self.plot_rkc.clear()
self.plot_ac.clear()
def _update_clear_profile(self):
self.plot_ac.clear()
self.plot_rkc.clear_profile()
+10
View File
@@ -376,9 +376,19 @@ class InitialConditionTableModel(PamhyrTableModel):
self.layoutChanged.emit() self.layoutChanged.emit()
def generate(self, generator, param, option): def generate(self, generator, param, option):
self.layoutAboutToBeChanged.emit()
self._undo.beginMacro(f"generate {generator}")
self._undo.push( self._undo.push(
GenerateCommand( GenerateCommand(
self._lst, generator, param, option self._lst, generator, param, option
) )
) )
self._undo.push(
SortCommand(
self._lst, False
)
)
self._undo.endMacro()
self.layoutChanged.emit() self.layoutChanged.emit()
+17 -5
View File
@@ -100,15 +100,19 @@ class SortCommand(QUndoCommand):
self._indexes = None self._indexes = None
def undo(self): def undo(self):
ll = self._ics.data order = {
id(x): self._indexes[i]
for i, x in enumerate(self._ics.data)
}
self._ics.sort( self._ics.sort(
key=lambda x: self._indexes[ll.index(x)] key=lambda x: order.get(id(x), len(order))
) )
def redo(self): def redo(self):
self._ics.sort( self._ics.sort(
reverse=self._reverse, reverse=self._reverse,
key=lambda x: x["rk"].rk key=lambda x: ((x["rk"] is None),
0.0 if x["rk"] is None else x["rk"].rk)
) )
if self._indexes is None: if self._indexes is None:
self._indexes = list( self._indexes = list(
@@ -182,11 +186,19 @@ class GenerateCommand(QUndoCommand):
self._ics = ics self._ics = ics
self._param = param self._param = param
self._option = option self._option = option
self._copy = self._ics.data # All the rows, with their deleted flag: the generation marks the
# previous rows as deleted (clear_data)
self._copy = list(self._ics._data)
self._deleted = [d.is_deleted() for d in self._copy]
self._generator = generator self._generator = generator
def undo(self): def undo(self):
self._ics.data = self._copy for data, deleted in zip(self._copy, self._deleted):
if deleted:
data.set_as_deleted()
else:
data.set_as_not_deleted()
self._ics.data = list(self._copy)
def redo(self): def redo(self):
if self._generator == "growing": if self._generator == "growing":