Merge branch 'split_reach' into dev_dylan

new_design_pol
Dylan Jeannin 2026-08-18 16:59:32 +02:00
commit 82b6cbfd72
17 changed files with 174 additions and 16 deletions

View File

@ -275,3 +275,44 @@ class D90AdisTS(SQLSubModel):
x.set_as_not_deleted() x.set_as_not_deleted()
self.modified() 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()

View File

@ -61,6 +61,10 @@ class D90AdisTSList(PamhyrModelList):
self._status.modified() self._status.modified()
return n return n
def split_reach(self, reach, profile, reach1, reach2):
for d90 in self.lst:
d90.split_reach(reach, profile, reach1, reach2)
@property @property
def D90_AdisTS_List(self): def D90_AdisTS_List(self):
return self.lst return self.lst

View File

@ -261,3 +261,13 @@ class D90AdisTSSpec(SQLSubModel):
def enabled(self, enabled): def enabled(self, enabled):
self._enabled = enabled self._enabled = enabled
self.modified() 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

View File

@ -329,3 +329,44 @@ class DIFAdisTS(SQLSubModel):
x.set_as_not_deleted() x.set_as_not_deleted()
self.modified() 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()

View File

@ -61,6 +61,10 @@ class DIFAdisTSList(PamhyrModelList):
self._status.modified() self._status.modified()
return n return n
def split_reach(self, reach, profile, reach1, reach2):
for dif in self.lst:
dif.split_reach(reach, profile, reach1, reach2)
@property @property
def DIF_AdisTS_List(self): def DIF_AdisTS_List(self):
return self.lst return self.lst

View File

@ -293,3 +293,15 @@ class DIFAdisTSSpec(SQLSubModel):
def enabled(self, enabled): def enabled(self, enabled):
self._enabled = enabled self._enabled = enabled
self._status.modified() 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

View File

@ -109,16 +109,22 @@ class FrictionList(PamhyrModelList):
((999 ** 100), -(999 ** 100)) ((999 ** 100), -(999 ** 100))
) )
frictions = list( for friction in self.lst:
filter( lower, upper = sorted((friction.begin_rk, friction.end_rk))
lambda f: ((rk_min <= f.begin_rk <= rk_max) or clipped_lower = max(lower, rk_min)
(rk_min <= f.end_rk <= rk_max)), clipped_upper = min(upper, rk_max)
self._lst)) if clipped_lower >= clipped_upper:
continue
for ind, friction in enumerate(frictions):
n = friction.cloned_for(reach) 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() new._status.modified()
return new return new

View File

@ -391,7 +391,7 @@ class InitialConditionsAdisTS(SQLSubModel):
for new_reach, part_lower, part_upper in parts: for new_reach, part_lower, part_upper in parts:
clipped_lower = max(lower, part_lower) clipped_lower = max(lower, part_lower)
clipped_upper = min(upper, part_upper) clipped_upper = min(upper, part_upper)
if clipped_lower > clipped_upper: if clipped_lower >= clipped_upper:
continue continue
start_rk = clipped_upper if reverse else clipped_lower start_rk = clipped_upper if reverse else clipped_lower

View File

@ -254,7 +254,7 @@ class InitialConditionsTemperature(SQLSubModel):
for new_reach, part_lower, part_upper in parts: for new_reach, part_lower, part_upper in parts:
clipped_lower = max(lower, part_lower) clipped_lower = max(lower, part_lower)
clipped_upper = min(upper, part_upper) clipped_upper = min(upper, part_upper)
if clipped_lower > clipped_upper: if clipped_lower >= clipped_upper:
continue continue
start_rk = clipped_upper if reverse else clipped_lower start_rk = clipped_upper if reverse else clipped_lower

View File

@ -117,7 +117,7 @@ class LateralContributionList(PamhyrModelListWithTab):
for new_reach, part_lower, part_upper, sections in parts: for new_reach, part_lower, part_upper, sections in parts:
clipped_lower = max(lower, part_lower) clipped_lower = max(lower, part_lower)
clipped_upper = min(upper, part_upper) clipped_upper = min(upper, part_upper)
if clipped_lower > clipped_upper: if clipped_lower >= clipped_upper:
continue continue
begin_index = ( begin_index = (

View File

@ -95,7 +95,7 @@ class LateralContributionsAdisTSList(PamhyrModelList):
for new_reach, part_lower, part_upper in parts: for new_reach, part_lower, part_upper in parts:
clipped_lower = max(lower, part_lower) clipped_lower = max(lower, part_lower)
clipped_upper = min(upper, part_upper) clipped_upper = min(upper, part_upper)
if clipped_lower > clipped_upper: if clipped_lower >= clipped_upper:
continue continue
begin_rk = clipped_upper if reverse else clipped_lower begin_rk = clipped_upper if reverse else clipped_lower

View File

@ -963,6 +963,12 @@ Last export at: @date."""
self._results[solv_type] = results self._results[solv_type] = results
def _split_reach(self, reach, profile): 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 node1 = reach.node1
node2 = reach.node2 node2 = reach.node2
@ -1000,5 +1006,11 @@ Last export at: @date."""
self._WeatherParameters.split_reach( self._WeatherParameters.split_reach(
reach, profile, r1, r2 reach, profile, r1, r2
) )
self._D90AdisTS.split_reach(
reach, profile, r1, r2
)
self._DIFAdisTS.split_reach(
reach, profile, r1, r2
)
return r1, r2 return r1, r2

View File

@ -204,7 +204,7 @@ class WeatherParametersList(PamhyrModelList):
for new_reach, part_lower, part_upper, sections in parts: for new_reach, part_lower, part_upper, sections in parts:
clipped_lower = max(lower, part_lower) clipped_lower = max(lower, part_lower)
clipped_upper = min(upper, part_upper) clipped_upper = min(upper, part_upper)
if clipped_lower > clipped_upper: if clipped_lower >= clipped_upper:
continue continue
begin_index = clipped_upper if reverse else clipped_lower begin_index = clipped_upper if reverse else clipped_lower

View File

@ -123,9 +123,16 @@ class D90TableModel(PamhyrTableModel):
self._undo.indexChanged.connect(lambda _: self.update()) self._undo.indexChanged.connect(lambda _: self.update())
def _setup_lst(self): def _setup_lst(self):
enabled_reaches = {
reach.id for reach in self._river.enable_edges()
}
self._lst = list( self._lst = list(
filter( 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 self._data._data
) )
) )

View File

@ -125,9 +125,16 @@ class DIFTableModel(PamhyrTableModel):
self._undo.indexChanged.connect(lambda _: self.update()) self._undo.indexChanged.connect(lambda _: self.update())
def _setup_lst(self): def _setup_lst(self):
enabled_reaches = {
reach.id for reach in self._river.enable_edges()
}
self._lst = list( self._lst = list(
filter( 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 self._data._data
) )
) )

View File

@ -32,6 +32,7 @@ from PyQt5.QtGui import (
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QApplication, QGraphicsScene, QGraphicsView, QApplication, QGraphicsScene, QGraphicsView,
QGraphicsItem, QGraphicsTextItem, QMenu, QGraphicsItem, QGraphicsTextItem, QMenu,
QMessageBox,
) )
from Model.Network.Node import Node from Model.Network.Node import Node
@ -724,6 +725,16 @@ class GraphWidget(QGraphicsView):
def split_edge(self, item): def split_edge(self, item):
edge = item.edge 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( dlg = SelectProfileDialog(
study=self.parent._study, study=self.parent._study,

View File

@ -73,7 +73,10 @@ class SelectProfileDialog(PamhyrDialog):
list( list(
map( map(
lambda p: p.display_name(), lambda p: p.display_name(),
self._reach.reach.profiles))) self._reach.reach.profiles[1:-1]
)
)
)
def accept(self): def accept(self):
profile = self.get_combobox_text("comboBox") profile = self.get_combobox_text("comboBox")
@ -81,7 +84,7 @@ class SelectProfileDialog(PamhyrDialog):
self._profile = next( self._profile = next(
filter( filter(
lambda p: p.display_name() == profile, lambda p: p.display_name() == profile,
self._reach.reach.profiles self._reach.reach.profiles[1:-1]
) )
) )