diff --git a/src/Model/D90AdisTS/D90AdisTS.py b/src/Model/D90AdisTS/D90AdisTS.py index 5c222f65..80ac1267 100644 --- a/src/Model/D90AdisTS/D90AdisTS.py +++ b/src/Model/D90AdisTS/D90AdisTS.py @@ -275,3 +275,44 @@ class D90AdisTS(SQLSubModel): x.set_as_not_deleted() self.modified() + + def split_reach(self, reach, profile, reach1, reach2): + split_rk = profile.rk + reach_rks = reach.reach.get_rk() + if len(reach_rks) == 0: + return + + parts = [ + (reach1.id, min(reach_rks), split_rk), + (reach2.id, split_rk, max(reach_rks)), + ] + specifications = [ + specification + for specification in self._data + if (not specification.is_deleted() and + specification.reach == reach.id) + ] + + for specification in specifications: + begin = specification.start_rk + end = specification.end_rk + if begin is None or end is None: + continue + + lower, upper = sorted((begin, end)) + reverse = begin > end + + for new_reach, part_lower, part_upper in parts: + clipped_lower = max(lower, part_lower) + clipped_upper = min(upper, part_upper) + if clipped_lower >= clipped_upper: + continue + + start_rk = clipped_upper if reverse else clipped_lower + end_rk = clipped_lower if reverse else clipped_upper + self._data.append(specification.cloned_for( + new_reach, start_rk, end_rk + )) + + if len(specifications) != 0: + self.modified() diff --git a/src/Model/D90AdisTS/D90AdisTSList.py b/src/Model/D90AdisTS/D90AdisTSList.py index ce4f6ef6..89a0353d 100644 --- a/src/Model/D90AdisTS/D90AdisTSList.py +++ b/src/Model/D90AdisTS/D90AdisTSList.py @@ -61,6 +61,10 @@ class D90AdisTSList(PamhyrModelList): self._status.modified() return n + def split_reach(self, reach, profile, reach1, reach2): + for d90 in self.lst: + d90.split_reach(reach, profile, reach1, reach2) + @property def D90_AdisTS_List(self): return self.lst diff --git a/src/Model/D90AdisTS/D90AdisTSSpec.py b/src/Model/D90AdisTS/D90AdisTSSpec.py index 8d8252bb..4da6b1bf 100644 --- a/src/Model/D90AdisTS/D90AdisTSSpec.py +++ b/src/Model/D90AdisTS/D90AdisTSSpec.py @@ -261,3 +261,13 @@ class D90AdisTSSpec(SQLSubModel): def enabled(self, enabled): self._enabled = enabled self.modified() + + def cloned_for(self, reach, start_rk, end_rk): + new = D90AdisTSSpec(name=self._name_section, status=self._status) + new._reach = reach + new._start_rk = start_rk + new._end_rk = end_rk + new._d90 = self._d90 + new._enabled = self._enabled + new.modified() + return new diff --git a/src/Model/DIFAdisTS/DIFAdisTS.py b/src/Model/DIFAdisTS/DIFAdisTS.py index b642f7d6..f907a40e 100644 --- a/src/Model/DIFAdisTS/DIFAdisTS.py +++ b/src/Model/DIFAdisTS/DIFAdisTS.py @@ -329,3 +329,44 @@ class DIFAdisTS(SQLSubModel): x.set_as_not_deleted() self.modified() + + def split_reach(self, reach, profile, reach1, reach2): + split_rk = profile.rk + reach_rks = reach.reach.get_rk() + if len(reach_rks) == 0: + return + + parts = [ + (reach1.id, min(reach_rks), split_rk), + (reach2.id, split_rk, max(reach_rks)), + ] + specifications = [ + specification + for specification in self._data + if (not specification.is_deleted() and + specification.reach == reach.id) + ] + + for specification in specifications: + begin = specification.start_rk + end = specification.end_rk + if begin is None or end is None: + continue + + lower, upper = sorted((begin, end)) + reverse = begin > end + + for new_reach, part_lower, part_upper in parts: + clipped_lower = max(lower, part_lower) + clipped_upper = min(upper, part_upper) + if clipped_lower >= clipped_upper: + continue + + start_rk = clipped_upper if reverse else clipped_lower + end_rk = clipped_lower if reverse else clipped_upper + self._data.append(specification.cloned_for( + new_reach, start_rk, end_rk + )) + + if len(specifications) != 0: + self.modified() diff --git a/src/Model/DIFAdisTS/DIFAdisTSList.py b/src/Model/DIFAdisTS/DIFAdisTSList.py index a765547c..d80fabc1 100644 --- a/src/Model/DIFAdisTS/DIFAdisTSList.py +++ b/src/Model/DIFAdisTS/DIFAdisTSList.py @@ -61,6 +61,10 @@ class DIFAdisTSList(PamhyrModelList): self._status.modified() return n + def split_reach(self, reach, profile, reach1, reach2): + for dif in self.lst: + dif.split_reach(reach, profile, reach1, reach2) + @property def DIF_AdisTS_List(self): return self.lst diff --git a/src/Model/DIFAdisTS/DIFAdisTSSpec.py b/src/Model/DIFAdisTS/DIFAdisTSSpec.py index fe185dfa..83daa989 100644 --- a/src/Model/DIFAdisTS/DIFAdisTSSpec.py +++ b/src/Model/DIFAdisTS/DIFAdisTSSpec.py @@ -293,3 +293,15 @@ class DIFAdisTSSpec(SQLSubModel): def enabled(self, enabled): self._enabled = enabled self._status.modified() + + def cloned_for(self, reach, start_rk, end_rk): + new = DIFAdisTSSpec(method=self._method, status=self._status) + new._reach = reach + new._start_rk = start_rk + new._end_rk = end_rk + new._dif = self._dif + new._b = self._b + new._c = self._c + new._enabled = self._enabled + new.modified() + return new diff --git a/src/Model/Friction/FrictionList.py b/src/Model/Friction/FrictionList.py index 963c3316..df4573b8 100644 --- a/src/Model/Friction/FrictionList.py +++ b/src/Model/Friction/FrictionList.py @@ -109,16 +109,22 @@ class FrictionList(PamhyrModelList): ((999 ** 100), -(999 ** 100)) ) - frictions = list( - filter( - lambda f: ((rk_min <= f.begin_rk <= rk_max) or - (rk_min <= f.end_rk <= rk_max)), - self._lst)) + for friction in self.lst: + lower, upper = sorted((friction.begin_rk, friction.end_rk)) + clipped_lower = max(lower, rk_min) + clipped_upper = min(upper, rk_max) + if clipped_lower >= clipped_upper: + continue - for ind, friction in enumerate(frictions): n = friction.cloned_for(reach) + if friction.begin_rk > friction.end_rk: + n.begin_rk = clipped_upper + n.end_rk = clipped_lower + else: + n.begin_rk = clipped_lower + n.end_rk = clipped_upper - new._lst.insert(ind, n) + new._lst.append(n) new._status.modified() return new diff --git a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py index 65a72e90..903fe877 100644 --- a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py +++ b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py @@ -391,7 +391,7 @@ class InitialConditionsAdisTS(SQLSubModel): for new_reach, part_lower, part_upper in parts: clipped_lower = max(lower, part_lower) clipped_upper = min(upper, part_upper) - if clipped_lower > clipped_upper: + if clipped_lower >= clipped_upper: continue start_rk = clipped_upper if reverse else clipped_lower diff --git a/src/Model/InitialConditionsTemperature/InitialConditionsTemperature.py b/src/Model/InitialConditionsTemperature/InitialConditionsTemperature.py index 33e2c99e..986e603e 100644 --- a/src/Model/InitialConditionsTemperature/InitialConditionsTemperature.py +++ b/src/Model/InitialConditionsTemperature/InitialConditionsTemperature.py @@ -254,7 +254,7 @@ class InitialConditionsTemperature(SQLSubModel): for new_reach, part_lower, part_upper in parts: clipped_lower = max(lower, part_lower) clipped_upper = min(upper, part_upper) - if clipped_lower > clipped_upper: + if clipped_lower >= clipped_upper: continue start_rk = clipped_upper if reverse else clipped_lower diff --git a/src/Model/LateralContribution/LateralContributionList.py b/src/Model/LateralContribution/LateralContributionList.py index c6aa7162..803d2c27 100644 --- a/src/Model/LateralContribution/LateralContributionList.py +++ b/src/Model/LateralContribution/LateralContributionList.py @@ -117,7 +117,7 @@ class LateralContributionList(PamhyrModelListWithTab): for new_reach, part_lower, part_upper, sections in parts: clipped_lower = max(lower, part_lower) clipped_upper = min(upper, part_upper) - if clipped_lower > clipped_upper: + if clipped_lower >= clipped_upper: continue begin_index = ( diff --git a/src/Model/LateralContributionsAdisTS/LateralContributionsAdisTSList.py b/src/Model/LateralContributionsAdisTS/LateralContributionsAdisTSList.py index ad9d2783..05bc07f1 100644 --- a/src/Model/LateralContributionsAdisTS/LateralContributionsAdisTSList.py +++ b/src/Model/LateralContributionsAdisTS/LateralContributionsAdisTSList.py @@ -95,7 +95,7 @@ class LateralContributionsAdisTSList(PamhyrModelList): for new_reach, part_lower, part_upper in parts: clipped_lower = max(lower, part_lower) clipped_upper = min(upper, part_upper) - if clipped_lower > clipped_upper: + if clipped_lower >= clipped_upper: continue begin_rk = clipped_upper if reverse else clipped_lower diff --git a/src/Model/River.py b/src/Model/River.py index 35e4416f..eecdb4b8 100644 --- a/src/Model/River.py +++ b/src/Model/River.py @@ -963,6 +963,12 @@ Last export at: @date.""" self._results[solv_type] = results def _split_reach(self, reach, profile): + profiles = reach.reach.profiles + if not profiles or profile not in profiles[1:-1]: + raise ValueError( + "A reach cannot be split at its first or last profile" + ) + node1 = reach.node1 node2 = reach.node2 @@ -1000,5 +1006,11 @@ Last export at: @date.""" self._WeatherParameters.split_reach( reach, profile, r1, r2 ) + self._D90AdisTS.split_reach( + reach, profile, r1, r2 + ) + self._DIFAdisTS.split_reach( + reach, profile, r1, r2 + ) return r1, r2 diff --git a/src/Model/WeatherParameters/WeatherParametersList.py b/src/Model/WeatherParameters/WeatherParametersList.py index 399308ff..8669e34f 100644 --- a/src/Model/WeatherParameters/WeatherParametersList.py +++ b/src/Model/WeatherParameters/WeatherParametersList.py @@ -204,7 +204,7 @@ class WeatherParametersList(PamhyrModelList): for new_reach, part_lower, part_upper, sections in parts: clipped_lower = max(lower, part_lower) clipped_upper = min(upper, part_upper) - if clipped_lower > clipped_upper: + if clipped_lower >= clipped_upper: continue begin_index = clipped_upper if reverse else clipped_lower diff --git a/src/View/D90AdisTS/Table.py b/src/View/D90AdisTS/Table.py index 0e2b21d0..f875c6ba 100644 --- a/src/View/D90AdisTS/Table.py +++ b/src/View/D90AdisTS/Table.py @@ -123,9 +123,16 @@ class D90TableModel(PamhyrTableModel): self._undo.indexChanged.connect(lambda _: self.update()) def _setup_lst(self): + enabled_reaches = { + reach.id for reach in self._river.enable_edges() + } self._lst = list( filter( - lambda d90: d90._deleted is False, + lambda d90: ( + d90._deleted is False + and (d90.reach in (None, -1) + or d90.reach in enabled_reaches) + ), self._data._data ) ) diff --git a/src/View/DIFAdisTS/Table.py b/src/View/DIFAdisTS/Table.py index 2a8fce12..3a41d379 100644 --- a/src/View/DIFAdisTS/Table.py +++ b/src/View/DIFAdisTS/Table.py @@ -125,9 +125,16 @@ class DIFTableModel(PamhyrTableModel): self._undo.indexChanged.connect(lambda _: self.update()) def _setup_lst(self): + enabled_reaches = { + reach.id for reach in self._river.enable_edges() + } self._lst = list( filter( - lambda dif: dif._deleted is False, + lambda dif: ( + dif._deleted is False + and (dif.reach in (None, -1) + or dif.reach in enabled_reaches) + ), self._data._data ) ) diff --git a/src/View/Network/GraphWidget.py b/src/View/Network/GraphWidget.py index 6d6daa4c..31b0fcdd 100644 --- a/src/View/Network/GraphWidget.py +++ b/src/View/Network/GraphWidget.py @@ -32,6 +32,7 @@ from PyQt5.QtGui import ( from PyQt5.QtWidgets import ( QApplication, QGraphicsScene, QGraphicsView, QGraphicsItem, QGraphicsTextItem, QMenu, + QMessageBox, ) from Model.Network.Node import Node @@ -724,6 +725,16 @@ class GraphWidget(QGraphicsView): def split_edge(self, item): edge = item.edge + if len(edge.reach.profiles) < 3: + QMessageBox.information( + self, + self._trad["menu_split_edge"], + _translate( + "Network", + "No profile is available to split this reach." + ) + ) + return dlg = SelectProfileDialog( study=self.parent._study, diff --git a/src/View/Network/ProfileDialog.py b/src/View/Network/ProfileDialog.py index 28caa99d..66abccaf 100644 --- a/src/View/Network/ProfileDialog.py +++ b/src/View/Network/ProfileDialog.py @@ -73,7 +73,10 @@ class SelectProfileDialog(PamhyrDialog): list( map( lambda p: p.display_name(), - self._reach.reach.profiles))) + self._reach.reach.profiles[1:-1] + ) + ) + ) def accept(self): profile = self.get_combobox_text("comboBox") @@ -81,7 +84,7 @@ class SelectProfileDialog(PamhyrDialog): self._profile = next( filter( lambda p: p.display_name() == profile, - self._reach.reach.profiles + self._reach.reach.profiles[1:-1] ) )