diff --git a/src/Model/BoundaryCondition/BoundaryCondition.py b/src/Model/BoundaryCondition/BoundaryCondition.py index eddc52b1f80210f8d5c1eeb3e9855a1c85aadda7..265e8b2fbe7228bf7eff2f9bb6ebea52ec86892f 100644 --- a/src/Model/BoundaryCondition/BoundaryCondition.py +++ b/src/Model/BoundaryCondition/BoundaryCondition.py @@ -371,3 +371,15 @@ class BoundaryCondition(SQLSubModel): d = self._data d[index], d[prev] = d[prev], d[index] self._status.modified() + + def reach(self, river): + edges = [] + if self._node != None: + if river != None: + for edge in river.edges(): + if edge.node1.name == self._node.name: + edges.append(edge.reach) + if edge.node2.name == self._node.name: + edges.append(edge.reach) + + return edges diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py index 0e29c8c3130bb3c0eb9f5d804a51d3c851a0294e..911ae89044afd638a13ad6bdedd08ce1c7a5a816 100644 --- a/src/Model/Geometry/ProfileXYZ.py +++ b/src/Model/Geometry/ProfileXYZ.py @@ -436,8 +436,6 @@ class ProfileXYZ(Profile, SQLSubModel): area += poly.area return area - return poly.area - def wet_radius(self, z): p = self.wet_perimeter(z) a = self.wet_area(z) @@ -482,14 +480,15 @@ class ProfileXYZ(Profile, SQLSubModel): if zz[i] < z: line.append([station[i], zz[i]]) - if zz[i] <= z and zz[i+1] > z: + if zz[i] <= z and zz[i+1] >= z: y = np.interp( z, [zz[i], zz[i+1]], [station[i], station[i+1]] ) line.append([y, z]) - lines.append(geometry.LineString(line)) + if len(line) > 2: + lines.append(geometry.LineString(line)) line = [] return lines diff --git a/src/View/BoundaryCondition/Edit/Table.py b/src/View/BoundaryCondition/Edit/Table.py index d4a9f8a6aa335e608538b64707c10ee2dc74570e..c5f268a73146fb81959a24a529bd740bcde4f29c 100644 --- a/src/View/BoundaryCondition/Edit/Table.py +++ b/src/View/BoundaryCondition/Edit/Table.py @@ -48,6 +48,7 @@ from Model.BoundaryCondition.BoundaryConditionTypes import ( from View.BoundaryCondition.Edit.UndoCommand import ( SetDataCommand, AddCommand, DelCommand, SortCommand, MoveCommand, PasteCommand, + ReplaceDataCommand, ) _translate = QCoreApplication.translate @@ -200,3 +201,14 @@ class TableModel(PamhyrTableModel): def update(self): # self.auto_sort() self.layoutChanged.emit() + + def replace_data(self, data1, data2): + self.layoutAboutToBeChanged.emit() + self._undo.push( + ReplaceDataCommand( + self._data, data1, data2 + ) + ) + self.layoutAboutToBeChanged.emit() + self.update() + diff --git a/src/View/BoundaryCondition/Edit/UndoCommand.py b/src/View/BoundaryCondition/Edit/UndoCommand.py index 02e0a48ed0ed63f6a2bf832317b9291cc49cee11..d7ef26710a38493cfb55533952d0a4ac9a1c85db 100644 --- a/src/View/BoundaryCondition/Edit/UndoCommand.py +++ b/src/View/BoundaryCondition/Edit/UndoCommand.py @@ -181,3 +181,29 @@ class PasteCommand(QUndoCommand): def redo(self): for bc in self._bcs: self._data.insert(self._row, bc) + +class ReplaceDataCommand(QUndoCommand): + def __init__(self, data, data1, data2): + QUndoCommand.__init__(self) + self._data = data + self._old_rows = len(data) + self._data1 = data1 + self._data2 = data2 + self._rows = len(data1) + + self._old_bc = [] + for row in range(self._old_rows): + self._old_bc.append((row, self._data.get_i(row))) + self._old_bc.sort() + + def undo(self): + self._data.delete_i(list(range(self._rows))) + for row, el in self._old_bc: + self._data.insert(row, el) + + def redo(self): + self._data.delete_i(list(range(self._old_rows))) + for row in range(self._rows): + self._data.add(row) + self._data._set_i_c_v(row, 0, self._data1[row]) + self._data._set_i_c_v(row, 1, self._data2[row]) diff --git a/src/View/BoundaryCondition/Edit/Window.py b/src/View/BoundaryCondition/Edit/Window.py index 94557ddd57bc451f0e768ecdcb43b7bd7942ff58..e6b53f237874f2ec472303b1e3cd212b6a6abffb 100644 --- a/src/View/BoundaryCondition/Edit/Window.py +++ b/src/View/BoundaryCondition/Edit/Window.py @@ -20,6 +20,8 @@ import logging from tools import timer, trace +from numpy import sqrt + from View.Tools.PamhyrWindow import PamhyrWindow from View.Tools.PamhyrWidget import PamhyrWidget from View.Tools.PamhyrDelegate import PamhyrExTimeDelegate @@ -104,6 +106,7 @@ class EditBoundaryConditionWindow(PamhyrWindow): self._data = data trad = BCETranslate() self._long_types = trad.get_dict("long_types") + self._study = study name = trad[self._pamhyr_name] if self._data is not None: @@ -193,6 +196,14 @@ class EditBoundaryConditionWindow(PamhyrWindow): self.find(QAction, "action_add").triggered.connect(self.add) self.find(QAction, "action_del").triggered.connect(self.delete) self.find(QAction, "action_sort").triggered.connect(self.sort) + self.find(QAction, "action_generate_uniform").triggered.connect(self.generate_uniform) + self.find(QAction, "action_generate_critical").triggered.connect(self.generate_critical) + if self._data.bctype != "ZD" or not self._data.has_node: + self.find(QAction, "action_generate_uniform").setVisible(False) + self.find(QAction, "action_generate_critical").setVisible(False) + else: + self.find(QAction, "action_generate_uniform").setVisible(True) + self.find(QAction, "action_generate_critical").setVisible(True) self._table.dataChanged.connect(self.update) self._table.layoutChanged.connect(self.update) @@ -311,3 +322,37 @@ class EditBoundaryConditionWindow(PamhyrWindow): self._table.redo() self.plot.update() self.widget_update() + + def generate_uniform(self): + if self._data.has_node: + node = self._data.node + reach = self._data.reach(self._study.river)[0] + profile = reach.profiles[-1] + incline = reach.get_incline_median_mean() + z_min = profile.z_min() + z_max = profile.z_max() + strickler = 25 + height = [(i)*(z_max-z_min)/50 for i in range(51)] + q = [((profile.wet_width(z_min + h) * 0.8) * strickler + * (h ** (5/3)) + * (abs(incline) ** (0.5))) + for h in height + ] + self._table.replace_data(height, q) + + return + + def generate_critical(self): + if self._data.has_node: + node = self._data.node + reach = self._data.reach(self._study.river)[0] + profile = reach.profiles[-1] + incline = reach.get_incline_median_mean() + z_min = profile.z_min() + z_max = profile.z_max() + height = [(i)*(z_max-z_min)/50 for i in range(51)] + q = [sqrt(9.81 * (profile.wet_area(z_min + h) ** 3) / profile.wet_width(z_min + h)) + for h in height + ] + self._table.replace_data(height, q) + return diff --git a/src/View/ui/EditBoundaryConditions.ui b/src/View/ui/EditBoundaryConditions.ui index b27232d2c2f3bde34c7d14af190c895608b7e767..c2c8137818d02ca34fe432a4fd2d32e43fec7fc9 100644 --- a/src/View/ui/EditBoundaryConditions.ui +++ b/src/View/ui/EditBoundaryConditions.ui @@ -73,6 +73,8 @@ <addaction name="action_add"/> <addaction name="action_del"/> <addaction name="action_sort"/> + <addaction name="action_generate_uniform"/> + <addaction name="action_generate_critical"/> </widget> <action name="action_add"> <property name="checkable"> @@ -119,6 +121,25 @@ <string>Sort points</string> </property> </action> + <action name="action_generate_uniform"> + <property name="text"> + <string>Generate uniform</string> + </property> + <property name="iconText"> + <string>Generate uniform</string> + </property> + <property name="toolTip"> + <string>Generate rating curve from Manning law</string> + </property> + </action> + <action name="action_generate_critical"> + <property name="text"> + <string>Generate critical</string> + </property> + <property name="toolTip"> + <string>Generate rating curve as Q(z) = Sqrt(g*S(z)^3/L(z))</string> + </property> + </action> </widget> <resources/> <connections/>