Merge branch 'split_reach' into dev_dylan

mesh_tab
Dylan Jeannin 2026-08-11 11:17:16 +02:00
commit cdbcb2b539
40 changed files with 905 additions and 93 deletions

View File

@ -277,3 +277,10 @@ class BasicHS(SQLSubModel):
def convert(self, new_type): def convert(self, new_type):
return new_type(id=self.id, name=self.name, status=self._status) return new_type(id=self.id, name=self.name, status=self._status)
def cloned(self):
new = type(self)(name=self._name, status=self._status)
new._enabled = self._enabled
new._data = [value.cloned() for value in self._data]
new.modified()
return new

View File

@ -208,3 +208,11 @@ class BHSValue(SQLSubModel):
def value(self, value): def value(self, value):
self._value = self._type(value) self._value = self._type(value)
self.modified() self.modified()
def cloned(self):
return BHSValue(
name=self._name,
type=self._type,
value=self._value,
status=self._status
)

View File

@ -427,6 +427,18 @@ class HydraulicStructure(SQLSubModel):
def basic_structures(self): def basic_structures(self):
return self.lst.copy() return self.lst.copy()
def cloned_for(self, input_reach, input_section,
output_reach, output_section):
new = HydraulicStructure(name=self._name, status=self._status)
new._enabled = self._enabled
new._input_reach = input_reach
new._input_section = input_section
new._output_reach = output_reach
new._output_section = output_section
new._data = [structure.cloned() for structure in self.lst]
new.modified()
return new
def basic_structure(self, index: int): def basic_structure(self, index: int):
if len(self._data) == 0: if len(self._data) == 0:
return None return None

View File

@ -61,6 +61,71 @@ class HydraulicStructureList(PamhyrModelList):
self.modified() self.modified()
return n return n
def split_reach(self, reach, profile, reach1, reach2):
profiles = reach.reach.profiles
split_index = profiles.index(profile)
sections1 = dict(zip(
profiles[:split_index + 1],
reach1.reach.profiles
))
sections2 = dict(zip(
profiles[split_index:],
reach2.reach.profiles
))
def split_endpoint(endpoint_reach, section):
if endpoint_reach is not reach:
return endpoint_reach, section
if section not in profiles:
return endpoint_reach, section
index = profiles.index(section)
if index < split_index:
return reach1, sections1[section]
return reach2, sections2[section]
structures = [
structure
for structure in self.lst
if (structure.input_reach is reach or
structure.output_reach is reach)
]
for structure in structures:
input_reach, input_section = split_endpoint(
structure.input_reach,
structure.input_section
)
output_reach, output_section = split_endpoint(
structure.output_reach,
structure.output_section
)
self._lst.append(structure.cloned_for(
input_reach,
input_section,
output_reach,
output_section
))
if len(structures) != 0:
self.modified()
@property
def enabled_reaches_list(self):
return [
structure
for structure in self.lst
if (structure.input_reach is None or
(not structure.input_reach.is_deleted() and
structure.input_reach.is_enable()))
]
def get_for_enabled_reaches(self, index):
structures = self.enabled_reaches_list
if not 0 <= index < len(structures):
return None
return structures[index]
def __copy__(self): def __copy__(self):
new = HydraulicStructureList() new = HydraulicStructureList()

View File

@ -256,6 +256,17 @@ class Data(SQLSubModel):
) )
return new return new
def cloned_for(self, reach, section):
return Data(
name=self._name,
comment=self._comment,
section=section,
discharge=self._discharge,
height=self._height,
reach=reach,
status=self._status,
)
@property @property
def name(self): def name(self):
return self._name return self._name
@ -505,6 +516,20 @@ class InitialConditions(SQLSubModel):
for data in self._data: for data in self._data:
data.set_as_deleted() data.set_as_deleted()
def _splited_for(self, reach, sections):
new = InitialConditions(reach=reach, status=self._status)
new._data = [
data.cloned_for(reach, sections[data["section"]])
for data in self.data
if data["section"] in sections
]
if len(new._data) != 0:
new.modified()
return new
def generate_growing_constant_depth(self, height: float, def generate_growing_constant_depth(self, height: float,
compute_discharge: bool): compute_discharge: bool):
profiles = self._reach.reach.profiles.copy() profiles = self._reach.reach.profiles.copy()

View File

@ -88,3 +88,28 @@ class InitialConditionsDict(PamhyrModelDict):
new = InitialConditions(reach=reach, status=self._status) new = InitialConditions(reach=reach, status=self._status)
self.set(reach, new) self.set(reach, new)
return new return new
def split_reach(self, reach, profile, reach1, reach2):
if reach not in self._dict:
return
profiles = reach.reach.profiles
split_index = profiles.index(profile)
sections1 = dict(zip(
profiles[:split_index + 1],
reach1.reach.profiles
))
sections2 = dict(zip(
profiles[split_index:],
reach2.reach.profiles
))
self.set(
reach1,
self._dict[reach]._splited_for(reach1, sections1)
)
self.set(
reach2,
self._dict[reach]._splited_for(reach2, sections2)
)

View File

@ -359,3 +359,60 @@ class InitialConditionsAdisTS(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
lower_reach_rk = min(reach_rks)
upper_reach_rk = max(reach_rks)
parts = [
(reach1.id, lower_reach_rk, split_rk),
(reach2.id, split_rk, upper_reach_rk),
]
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()
def get_specs_for_enabled_reaches(self, reaches):
enabled_reaches = {
reach.id
for reach in reaches
if not reach.is_deleted() and reach.is_enable()
}
return [
specification
for specification in self._data
if (not specification.is_deleted() and
(specification.reach in (None, -1) or
specification.reach in enabled_reaches))
]

View File

@ -62,6 +62,12 @@ class InitialConditionsAdisTSList(PamhyrModelList):
self._status.modified() self._status.modified()
return n return n
def split_reach(self, reach, profile, reach1, reach2):
for initial_condition in self.lst:
initial_condition.split_reach(
reach, profile, reach1, reach2
)
@property @property
def Initial_Conditions_List(self): def Initial_Conditions_List(self):
return self.lst return self.lst

View File

@ -31,10 +31,12 @@ class ICAdisTSSpec(SQLSubModel):
_sub_classes = [] _sub_classes = []
def __init__(self, id: int = -1, name: str = "", def __init__(self, id: int = -1, name: str = "",
status=None, owner_scenario=None): status=None, owner_scenario=-1):
super(ICAdisTSSpec, self).__init__() super(ICAdisTSSpec, self).__init__(
id=id,
self._status = status status=status,
owner_scenario=owner_scenario
)
self._name_section = name self._name_section = name
self._reach = None self._reach = None
@ -234,7 +236,7 @@ class ICAdisTSSpec(SQLSubModel):
@name.setter @name.setter
def name(self, name): def name(self, name):
self._name_section = name self._name_section = name
self._status.modified() self.modified()
@property @property
def reach(self): def reach(self):
@ -243,7 +245,7 @@ class ICAdisTSSpec(SQLSubModel):
@reach.setter @reach.setter
def reach(self, reach): def reach(self, reach):
self._reach = reach self._reach = reach
self._status.modified() self.modified()
@property @property
def start_rk(self): def start_rk(self):
@ -252,7 +254,7 @@ class ICAdisTSSpec(SQLSubModel):
@start_rk.setter @start_rk.setter
def start_rk(self, start_rk): def start_rk(self, start_rk):
self._start_rk = start_rk self._start_rk = start_rk
self._status.modified() self.modified()
@property @property
def end_rk(self): def end_rk(self):
@ -261,7 +263,7 @@ class ICAdisTSSpec(SQLSubModel):
@end_rk.setter @end_rk.setter
def end_rk(self, end_rk): def end_rk(self, end_rk):
self._end_rk = end_rk self._end_rk = end_rk
self._status.modified() self.modified()
@property @property
def concentration(self): def concentration(self):
@ -270,7 +272,7 @@ class ICAdisTSSpec(SQLSubModel):
@concentration.setter @concentration.setter
def concentration(self, concentration): def concentration(self, concentration):
self._concentration = concentration self._concentration = concentration
self._status.modified() self.modified()
@property @property
def eg(self): def eg(self):
@ -279,7 +281,7 @@ class ICAdisTSSpec(SQLSubModel):
@eg.setter @eg.setter
def eg(self, eg): def eg(self, eg):
self._eg = eg self._eg = eg
self._status.modified() self.modified()
@property @property
def em(self): def em(self):
@ -288,7 +290,7 @@ class ICAdisTSSpec(SQLSubModel):
@em.setter @em.setter
def em(self, em): def em(self, em):
self._em = em self._em = em
self._status.modified() self.modified()
@property @property
def ed(self): def ed(self):
@ -297,7 +299,7 @@ class ICAdisTSSpec(SQLSubModel):
@ed.setter @ed.setter
def ed(self, ed): def ed(self, ed):
self._ed = ed self._ed = ed
self._status.modified() self.modified()
@property @property
def rate(self): def rate(self):
@ -306,7 +308,7 @@ class ICAdisTSSpec(SQLSubModel):
@rate.setter @rate.setter
def rate(self, rate): def rate(self, rate):
self._rate = rate self._rate = rate
self._status.modified() self.modified()
@property @property
def enabled(self): def enabled(self):
@ -315,4 +317,18 @@ class ICAdisTSSpec(SQLSubModel):
@enabled.setter @enabled.setter
def enabled(self, enabled): def enabled(self, enabled):
self._enabled = enabled self._enabled = enabled
self._status.modified() self.modified()
def cloned_for(self, reach, start_rk, end_rk):
new = ICAdisTSSpec(name=self._name_section, status=self._status)
new._reach = reach
new._start_rk = start_rk
new._end_rk = end_rk
new._concentration = self._concentration
new._eg = self._eg
new._em = self._em
new._ed = self._ed
new._rate = self._rate
new._enabled = self._enabled
new.modified()
return new

View File

@ -227,3 +227,42 @@ class InitialConditionsTemperature(SQLSubModel):
x.set_as_not_deleted() x.set_as_not_deleted()
self.modified() self.modified()
def split_reach(self, reach, profile, reach1, reach2):
parts = []
for new_reach in (reach1, reach2):
rks = new_reach.reach.get_rk()
if rks:
parts.append((new_reach.id, min(rks), max(rks)))
specifications = [
specification
for specification in self._data
if (not specification.is_deleted() and
specification.reach == reach.id)
]
clones = []
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
clones.append(specification.cloned_for(
new_reach, start_rk, end_rk
))
if clones:
self._data.extend(clones)
self.modified()

View File

@ -62,6 +62,12 @@ class InitialConditionsTemperatureList(PamhyrModelList):
self._status.modified() self._status.modified()
return n return n
def split_reach(self, reach, profile, reach1, reach2):
for initial_condition in self.lst:
initial_condition.split_reach(
reach, profile, reach1, reach2
)
@property @property
def Initial_Conditions_List(self): def Initial_Conditions_List(self):
return self.lst return self.lst

View File

@ -200,3 +200,15 @@ class ICTemperatureSpec(SQLSubModel):
def temperature(self, temperature): def temperature(self, temperature):
self._temperature = temperature self._temperature = temperature
self._status.modified() self._status.modified()
def cloned_for(self, reach, start_rk, end_rk):
new = ICTemperatureSpec(
name=self._name_section,
status=self._status
)
new._reach = reach
new._start_rk = start_rk
new._end_rk = end_rk
new._temperature = self._temperature
new.modified()
return new

View File

@ -196,6 +196,13 @@ class Data(SQLSubModel):
def __setitem__(self, key, value): def __setitem__(self, key, value):
self._data[key] = self._types[key](value) self._data[key] = self._types[key](value)
def cloned(self):
return Data(
self[0], self[1],
types=self._types,
status=self._status
)
class LateralContribution(SQLSubModel): class LateralContribution(SQLSubModel):
_sub_classes = [Data] _sub_classes = [Data]
@ -511,6 +518,15 @@ class LateralContribution(SQLSubModel):
def has_reach(self): def has_reach(self):
return self._reach is not None return self._reach is not None
def cloned_for(self, reach, begin_section, end_section):
new = type(self)(name=self._name, status=self._status)
new._reach = reach
new._begin_section = begin_section
new._end_section = end_section
new._data = [data.cloned() for data in self.data]
new.modified()
return new
@property @property
def begin_rk(self): def begin_rk(self):
if self._begin_section is None: if self._begin_section is None:

View File

@ -71,6 +71,89 @@ class LateralContributionList(PamhyrModelListWithTab):
self._status.modified() self._status.modified()
return n return n
def split_reach(self, reach, profile, reach1, reach2):
profiles = reach.reach.profiles
split_index = profiles.index(profile)
parts = [
(
reach1,
0,
split_index,
dict(zip(
profiles[:split_index + 1],
reach1.reach.profiles
))
),
(
reach2,
split_index,
len(profiles) - 1,
dict(zip(
profiles[split_index:],
reach2.reach.profiles
))
),
]
for tab in self._tabs:
contributions = [
contribution
for contribution in self.get_tab(tab)
if contribution.reach is reach
]
for contribution in contributions:
if (contribution.begin_section not in profiles or
contribution.end_section not in profiles):
continue
begin = profiles.index(contribution.begin_section)
end = profiles.index(contribution.end_section)
lower, upper = sorted((begin, end))
reverse = begin > end
clones = []
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:
continue
begin_index = (
clipped_upper if reverse else clipped_lower
)
end_index = (
clipped_lower if reverse else clipped_upper
)
clones.append(contribution.cloned_for(
new_reach,
sections[profiles[begin_index]],
sections[profiles[end_index]]
))
if len(clones) == 0:
continue
self._tabs[tab].extend(clones)
self._status.modified()
def get_tab_for_enabled_reaches(self, tab):
return [
contribution
for contribution in self.get_tab(tab)
if (contribution.reach is None or
(not contribution.reach.is_deleted() and
contribution.reach.is_enable()))
]
def get_for_enabled_reaches(self, tab, index):
contributions = self.get_tab_for_enabled_reaches(tab)
if not 0 <= index < len(contributions):
return None
return contributions[index]
def __copy__(self): def __copy__(self):
new = LateralContributionList() new = LateralContributionList()

View File

@ -192,6 +192,13 @@ class Data(SQLSubModel):
def __setitem__(self, key, value): def __setitem__(self, key, value):
self._data[key] = self._types[key](value) self._data[key] = self._types[key](value)
def cloned(self):
return Data(
self[0], self[1],
types=self._types,
status=self._status
)
class LateralContributionAdisTS(SQLSubModel): class LateralContributionAdisTS(SQLSubModel):
_sub_classes = [Data] _sub_classes = [Data]
@ -477,6 +484,18 @@ class LateralContributionAdisTS(SQLSubModel):
self._end_rk = end_rk self._end_rk = end_rk
self.modified() self.modified()
def cloned_for(self, reach, begin_rk, end_rk):
new = LateralContributionAdisTS(
pollutant=self._pollutant,
status=self._status
)
new._reach = reach
new._begin_rk = begin_rk
new._end_rk = end_rk
new._data = [data.cloned() for data in self.data]
new.modified()
return new
@property @property
def _default_0(self): def _default_0(self):
return self._types[0](0) return self._types[0](0)

View File

@ -68,6 +68,46 @@ class LateralContributionsAdisTSList(PamhyrModelList):
self._status.modified() self._status.modified()
return n return n
def split_reach(self, reach, profile, reach1, reach2):
parts = []
for new_reach in (reach1, reach2):
rks = new_reach.reach.get_rk()
if len(rks) == 0:
continue
parts.append((new_reach.id, min(rks), max(rks)))
contributions = [
contribution
for contribution in self.lst
if contribution.reach == reach.id
]
clones = []
for contribution in contributions:
begin = contribution.begin_rk
end = contribution.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
begin_rk = clipped_upper if reverse else clipped_lower
end_rk = clipped_lower if reverse else clipped_upper
clones.append(contribution.cloned_for(
new_reach, begin_rk, end_rk
))
if len(clones) != 0:
self._lst.extend(clones)
self._status.modified()
@property @property
def Lat_Cont_List(self): def Lat_Cont_List(self):
return self.lst return self.lst

View File

@ -979,4 +979,26 @@ Last export at: @date."""
self._add_edge(r1) self._add_edge(r1)
self._add_edge(r2) self._add_edge(r2)
self._initial_conditions.split_reach(
reach, profile, r1, r2
)
self._lateral_contribution.split_reach(
reach, profile, r1, r2
)
self._hydraulic_structures.split_reach(
reach, profile, r1, r2
)
self._InitialConditionsAdisTS.split_reach(
reach, profile, r1, r2
)
self._LateralContributionsAdisTS.split_reach(
reach, profile, r1, r2
)
self._InitialConditionsTemperature.split_reach(
reach, profile, r1, r2
)
self._WeatherParameters.split_reach(
reach, profile, r1, r2
)
return r1, r2 return r1, r2

View File

@ -153,6 +153,13 @@ class Data(SQLSubModel):
def __setitem__(self, key, value): def __setitem__(self, key, value):
self._data[key] = self._types[key](value) self._data[key] = self._types[key](value)
def cloned(self):
return Data(
self[0], self[1],
types=self._types,
status=self._status
)
class WeatherParametersDefault(SQLSubModel): class WeatherParametersDefault(SQLSubModel):
def __init__(self, type: str, value: float = 0.0, def __init__(self, type: str, value: float = 0.0,
@ -580,6 +587,15 @@ class WeatherParameters(SQLSubModel):
self._end_section = section self._end_section = section
self.modified() self.modified()
def cloned_for(self, reach, begin_section, end_section):
new = type(self)(name=self._name, status=self._status)
new._reach = reach
new._begin_section = begin_section
new._end_section = end_section
new._data = [data.cloned() for data in self.data]
new.modified()
return new
@property @property
def header(self): def header(self):
return self._header.copy() return self._header.copy()

View File

@ -161,6 +161,64 @@ class WeatherParametersList(PamhyrModelList):
self._status.modified() self._status.modified()
return n return n
def split_reach(self, reach, profile, reach1, reach2):
profiles = reach.reach.profiles
split_index = profiles.index(profile)
parts = [
(
reach1,
0,
split_index,
dict(zip(
profiles[:split_index + 1],
reach1.reach.profiles
))
),
(
reach2,
split_index,
len(profiles) - 1,
dict(zip(
profiles[split_index:],
reach2.reach.profiles
))
),
]
weather_parameters = [
weather_parameter
for weather_parameter in self.lst
if weather_parameter.reach is reach
]
clones = []
for weather_parameter in weather_parameters:
if (weather_parameter.begin_section not in profiles or
weather_parameter.end_section not in profiles):
continue
begin = profiles.index(weather_parameter.begin_section)
end = profiles.index(weather_parameter.end_section)
lower, upper = sorted((begin, end))
reverse = begin > end
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:
continue
begin_index = clipped_upper if reverse else clipped_lower
end_index = clipped_lower if reverse else clipped_upper
clones.append(weather_parameter.cloned_for(
new_reach,
sections[profiles[begin_index]],
sections[profiles[end_index]]
))
if clones:
self._lst.extend(clones)
self._status.modified()
@property @property
def Weather_Parameters_List(self): def Weather_Parameters_List(self):
return self.lst return self.lst

View File

@ -23,6 +23,8 @@ import tempfile
from Model.Status import StudyStatus from Model.Status import StudyStatus
from Model.Study import Study from Model.Study import Study
from Model.River import River from Model.River import River
from Model.LateralContribution.LateralContributionTypes import LateralContrib
from Model.HydraulicStructures.Basic.Types import DischargeWeir
class StudyTestCase(unittest.TestCase): class StudyTestCase(unittest.TestCase):
@ -287,3 +289,89 @@ class RiverTestCase(unittest.TestCase):
edges = river.edges() edges = river.edges()
self.assertEqual(edges[0], e0) self.assertEqual(edges[0], e0)
self.assertEqual(edges[1], e1) self.assertEqual(edges[1], e1)
def test_split_reach_splits_initial_conditions(self):
status = StudyStatus()
river = River(status=status)
node1 = river.add_node()
node2 = river.add_node(x=40.0)
reach = river.add_edge(node1, node2)
profiles = []
for index in range(5):
profile = reach.reach.insert(index)
profile.rk = index * 10.0
profile.insert(0)
profiles.append(profile)
initial_conditions = river.initial_conditions.get(reach)
for index, profile in enumerate(profiles):
data = initial_conditions.new_from_data(
profile.rk,
discharge=100.0 + index,
elevation=10.0 + index,
)
initial_conditions.insert(index, data)
reach1, reach2 = river._split_reach(reach, profiles[2])
conditions1 = river.initial_conditions.get(reach1).data
conditions2 = river.initial_conditions.get(reach2).data
self.assertEqual(
[data["discharge"] for data in conditions1],
[100.0, 101.0, 102.0]
)
self.assertEqual(
[data["discharge"] for data in conditions2],
[102.0, 103.0, 104.0]
)
self.assertEqual(
[data["section"] for data in conditions1],
reach1.reach.profiles
)
self.assertEqual(
[data["section"] for data in conditions2],
reach2.reach.profiles
)
self.assertTrue(all(
data._reach is reach1 for data in conditions1
))
self.assertTrue(all(
data._reach is reach2 for data in conditions2
))
def test_split_reach_keeps_partial_initial_conditions_in_scope(self):
status = StudyStatus()
river = River(status=status)
node1 = river.add_node()
node2 = river.add_node(x=40.0)
reach = river.add_edge(node1, node2)
profiles = []
for index in range(5):
profile = reach.reach.insert(index)
profile.rk = index * 10.0
profile.insert(0)
profiles.append(profile)
initial_conditions = river.initial_conditions.get(reach)
for index in (1, 3):
data = initial_conditions.new_from_data(
profiles[index].rk,
discharge=100.0 + index,
elevation=10.0 + index,
)
initial_conditions.insert(len(initial_conditions.data), data)
reach1, reach2 = river._split_reach(reach, profiles[2])
self.assertEqual(
[data["discharge"]
for data in river.initial_conditions.get(reach1).data],
[101.0]
)
self.assertEqual(
[data["discharge"]
for data in river.initial_conditions.get(reach2).data],
[103.0]
)

View File

@ -549,7 +549,7 @@ class AdisTSwc(AdisTS):
for LC in POL_LC: for LC in POL_LC:
reach = next(( reach = next((
edge for edge in study.river.enable_edges() edge for edge in study.river.enable_edges()
if edge.id == LC.edge if edge.id == LC.reach
), None) ), None)
if reach is None: if reach is None:
continue continue

View File

@ -935,7 +935,8 @@ class AdisTTwc(AdisTT):
for weather_parameter in study.river.weather_parameters.lst: for weather_parameter in study.river.weather_parameters.lst:
config = self._weather_files.get(weather_parameter.type) config = self._weather_files.get(weather_parameter.type)
if (config is None or weather_parameter.reach is None if (config is None or weather_parameter.reach is None
or weather_parameter.reach.is_deleted()): or weather_parameter.reach.is_deleted()
or not weather_parameter.reach.is_enable()):
continue continue
_, extension = config _, extension = config
exported = self._export_weather_file( exported = self._export_weather_file(

View File

@ -78,7 +78,7 @@ class ComboBoxDelegate(QItemDelegate):
else: else:
val = list( val = list(
map( map(
lambda n: n.name, self._data.edges() lambda n: n.name, self._data.enable_edges()
) )
) )

View File

@ -80,7 +80,7 @@ class ComboBoxDelegate(QItemDelegate):
else: else:
val = list( val = list(
map( map(
lambda n: n.name, self._data.edges() lambda n: n.name, self._data.enable_edges()
) )
) )

View File

@ -61,7 +61,7 @@ class ComboBoxDelegate(QItemDelegate):
val = [] val = []
if self._mode == "rk": if self._mode == "rk":
reach = self._data.hydraulic_structures\ reach = self._data.hydraulic_structures\
.get(index.row())\ .get_for_enabled_reaches(index.row())\
.input_reach .input_reach
if reach is not None: if reach is not None:
val = list( val = list(
@ -73,7 +73,7 @@ class ComboBoxDelegate(QItemDelegate):
else: else:
val = list( val = list(
map( map(
lambda n: n.name, self._data.edges() lambda n: n.name, self._data.enable_edges()
) )
) )
@ -94,7 +94,7 @@ class ComboBoxDelegate(QItemDelegate):
if self._mode == "rk": if self._mode == "rk":
reach = self._data.hydraulic_structures\ reach = self._data.hydraulic_structures\
.get(index.row())\ .get_for_enabled_reaches(index.row())\
.input_reach .input_reach
profiles = list( profiles = list(
filter( filter(
@ -128,20 +128,22 @@ class TableModel(PamhyrTableModel):
self._lst = self._data._hydraulic_structures self._lst = self._data._hydraulic_structures
def get_true_data_row(self, row): def get_true_data_row(self, row):
hs = self._lst.get(row) hs = self._lst.get_for_enabled_reaches(row)
if hs is None:
return len(self._lst.lst)
return next( return next(
map( map(
lambda e: e[0], lambda e: e[0],
filter( filter(
lambda e: e[1] == hs, lambda e: e[1] == hs,
enumerate(self._lst._lst) enumerate(self._lst.lst)
) )
), 0 ), 0
) )
def rowCount(self, parent): def rowCount(self, parent):
return len(self._lst) return len(self._lst.enabled_reaches_list)
def data(self, index, role): def data(self, index, role):
if role != Qt.ItemDataRole.DisplayRole: if role != Qt.ItemDataRole.DisplayRole:
@ -149,16 +151,17 @@ class TableModel(PamhyrTableModel):
row = index.row() row = index.row()
column = index.column() column = index.column()
structure = self._lst.get_for_enabled_reaches(row)
if self._headers[column] == "name": if self._headers[column] == "name":
return self._lst.get(row).name return structure.name
elif self._headers[column] == "reach": elif self._headers[column] == "reach":
n = self._lst.get(row).input_reach n = structure.input_reach
if n is None: if n is None:
return self._trad['not_associated'] return self._trad['not_associated']
return n.name return n.name
elif self._headers[column] == "rk": elif self._headers[column] == "rk":
n = self._lst.get(row).input_section n = structure.input_section
if n is None: if n is None:
return self._trad['not_associated'] return self._trad['not_associated']
return n.display_name() return n.display_name()
@ -174,6 +177,7 @@ class TableModel(PamhyrTableModel):
row = index.row() row = index.row()
column = index.column() column = index.column()
row = self.get_true_data_row(row)
na = self._trad['not_associated'] na = self._trad['not_associated']
try: try:

View File

@ -220,7 +220,7 @@ class HydraulicStructuresWindow(PamhyrWindow):
def add(self): def add(self):
rows = self.index_selected_rows() rows = self.index_selected_rows()
if len(self._hs_lst) == 0 or len(rows) == 0: if len(self._hs_lst.enabled_reaches_list) == 0 or len(rows) == 0:
self._table.add(0) self._table.add(0)
else: else:
self._table.add(rows[0]) self._table.add(rows[0])
@ -247,7 +247,7 @@ class HydraulicStructuresWindow(PamhyrWindow):
def edit(self): def edit(self):
rows = self.index_selected_rows() rows = self.index_selected_rows()
for row in rows: for row in rows:
data = self._hs_lst.get(row) data = self._hs_lst.get_for_enabled_reaches(row)
if self.sub_window_exists( if self.sub_window_exists(
BasicHydraulicStructuresWindow, BasicHydraulicStructuresWindow,
@ -269,7 +269,8 @@ class HydraulicStructuresWindow(PamhyrWindow):
self._checkbox.setChecked(True) self._checkbox.setChecked(True)
else: else:
self._checkbox.setEnabled(True) self._checkbox.setEnabled(True)
self._checkbox.setChecked(self._hs_lst.get(row).enabled) structure = self._hs_lst.get_for_enabled_reaches(row)
self._checkbox.setChecked(structure.enabled)
def _set_structure_state(self): def _set_structure_state(self):
rows = self.index_selected_rows() rows = self.index_selected_rows()
@ -288,16 +289,18 @@ class HydraulicStructuresWindow(PamhyrWindow):
def _update_clear_plot(self): def _update_clear_plot(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.enabled_reaches_list) == 0):
self._update_clear_all() self._update_clear_all()
return return
reach = self._hs_lst.get(rows[0]).input_reach structure = self._hs_lst.get_for_enabled_reaches(rows[0])
reach = structure.input_reach
if reach is not None: if reach is not None:
self.plot_rkc.set_reach(reach) self.plot_rkc.set_reach(reach)
self.plot_ac.set_reach(reach) self.plot_ac.set_reach(reach)
profile = self._hs_lst.get(rows[0]).input_section profile = structure.input_section
if profile is not None: if profile is not None:
profiles = reach.reach\ profiles = reach.reach\
.get_profiles_from_rk( .get_profiles_from_rk(

View File

@ -55,17 +55,27 @@ class ComboBoxDelegate(QItemDelegate):
self._trad = trad self._trad = trad
self._ic_spec_lst = ic_spec_lst self._ic_spec_lst = ic_spec_lst
def _specifications(self):
if hasattr(
self._ic_spec_lst,
"get_specs_for_enabled_reaches"
):
return self._ic_spec_lst.get_specs_for_enabled_reaches(
self._data.edges()
)
return self._ic_spec_lst
def createEditor(self, parent, option, index): def createEditor(self, parent, option, index):
self.editor = QComboBox(parent) self.editor = QComboBox(parent)
val = [] val = []
if self._mode == "rk": if self._mode == "rk":
reach_id = self._ic_spec_lst[index.row()].reach reach_id = self._specifications()[index.row()].reach
reach = next(filter(lambda edge: edge.id == reach_id, reach = next(filter(lambda edge: edge.id == reach_id,
self._data.edges()), None) self._data.edges()), None)
if reach_id is not None: if reach is not None:
val = list( val = list(
map( map(
lambda rk: str(rk), reach.reach.get_rk() lambda rk: str(rk), reach.reach.get_rk()
@ -74,7 +84,7 @@ class ComboBoxDelegate(QItemDelegate):
else: else:
val = list( val = list(
map( map(
lambda n: n.name, self._data.edges() lambda n: n.name, self._data.enable_edges()
) )
) )
@ -117,11 +127,8 @@ class InitialConditionTableModel(PamhyrTableModel):
self._data = data self._data = data
def _setup_lst(self): def _setup_lst(self):
self._lst = list( self._lst = self._data.get_specs_for_enabled_reaches(
filter( self._river.edges()
lambda ica: ica._deleted is False,
self._data._data
)
) )
def rowCount(self, parent): def rowCount(self, parent):

View File

@ -152,14 +152,14 @@ class InitialConditionsAdisTSWindow(PamhyrWindow):
self._delegate_reach = ComboBoxDelegate( self._delegate_reach = ComboBoxDelegate(
trad=self._trad, trad=self._trad,
data=self._study.river, data=self._study.river,
ic_spec_lst=self._data[0]._data, ic_spec_lst=self._data[0],
parent=self, parent=self,
mode="reaches" mode="reaches"
) )
self._delegate_rk = ComboBoxDelegate( self._delegate_rk = ComboBoxDelegate(
trad=self._trad, trad=self._trad,
data=self._study.river, data=self._study.river,
ic_spec_lst=self._data[0]._data, ic_spec_lst=self._data[0],
parent=self, parent=self,
mode="rk" mode="rk"
) )
@ -308,7 +308,10 @@ class InitialConditionsAdisTSWindow(PamhyrWindow):
def add(self): def add(self):
rows = self.index_selected_rows() rows = self.index_selected_rows()
if len(self._data[0]._data) == 0 or len(rows) == 0: visible = self._data[0].get_specs_for_enabled_reaches(
self._study.river.edges()
)
if len(visible) == 0 or len(rows) == 0:
self._table_spec.add(0) self._table_spec.add(0)
else: else:
self._table_spec.add(rows[0]) self._table_spec.add(rows[0])

View File

@ -75,7 +75,7 @@ class ComboBoxDelegate(QItemDelegate):
else: else:
val = list( val = list(
map( map(
lambda n: n.name, self._data.edges() lambda n: n.name, self._data.enable_edges()
) )
) )
@ -140,13 +140,30 @@ class InitialConditionTableModel(PamhyrTableModel):
self._data = data self._data = data
def _setup_lst(self): def _setup_lst(self):
enabled_reach_ids = {
reach.id
for reach in self._river.enable_edges()
}
self._lst = list( self._lst = list(
filter( filter(
lambda ica: ica._deleted is False, lambda ica: (
ica._deleted is False and
(
ica.reach in (None, -1) or
ica.reach in enabled_reach_ids
)
),
self._data._data self._data._data
) )
) )
def refresh(self):
self.beginResetModel()
try:
self._setup_lst()
finally:
self.endResetModel()
def rowCount(self, parent): def rowCount(self, parent):
return len(self._lst) return len(self._lst)
@ -221,19 +238,30 @@ class InitialConditionTableModel(PamhyrTableModel):
) )
) )
else: else:
new_value = value
if self._headers[column] == "reach":
reach = self._river.edge(value)
rks = reach.reach.get_rk()
if not rks:
return False
new_value = (reach.id, min(rks))
self._undo.push( self._undo.push(
SetCommandSpec( SetCommandSpec(
self._lst, row, self._headers[column], self._lst, row, self._headers[column],
(self._river.edge(value).id new_value
if self._headers[column] == "reach"
else value
)
) )
) )
except Exception as e: except Exception as e:
logger.info(e) logger.info(e)
logger.debug(traceback.format_exc()) logger.debug(traceback.format_exc())
if self._headers[column] == "reach":
rk_index = self.index(
row, self._headers.index("rk")
)
self.dataChanged.emit(index, rk_index)
else:
self.dataChanged.emit(index, index) self.dataChanged.emit(index, index)
return True return True

View File

@ -73,6 +73,8 @@ class SetCommandSpec(QUndoCommand):
self._old = self._data[self._row].name self._old = self._data[self._row].name
elif self._column == "reach": elif self._column == "reach":
self._old = self._data[self._row].reach self._old = self._data[self._row].reach
self._old_start_rk = self._data[self._row].start_rk
self._old_end_rk = self._data[self._row].end_rk
elif self._column == "rk": elif self._column == "rk":
self._old = self._data[self._row].start_rk self._old = self._data[self._row].start_rk
elif self._column == "temperature": elif self._column == "temperature":
@ -84,6 +86,10 @@ class SetCommandSpec(QUndoCommand):
elif column == "reach": elif column == "reach":
_type = int _type = int
if column == "reach":
self._new = _type(new_value[0])
self._new_rk = float(new_value[1])
else:
self._new = _type(new_value) self._new = _type(new_value)
def undo(self): def undo(self):
@ -91,6 +97,8 @@ class SetCommandSpec(QUndoCommand):
self._data[self._row].name = self._old self._data[self._row].name = self._old
elif self._column == "reach": elif self._column == "reach":
self._data[self._row].reach = self._old self._data[self._row].reach = self._old
self._data[self._row].start_rk = self._old_start_rk
self._data[self._row].end_rk = self._old_end_rk
elif self._column == "rk": elif self._column == "rk":
self._data[self._row].start_rk = self._old self._data[self._row].start_rk = self._old
self._data[self._row].end_rk = self._old self._data[self._row].end_rk = self._old
@ -102,6 +110,8 @@ class SetCommandSpec(QUndoCommand):
self._data[self._row].name = self._new self._data[self._row].name = self._new
elif self._column == "reach": elif self._column == "reach":
self._data[self._row].reach = self._new self._data[self._row].reach = self._new
self._data[self._row].start_rk = self._new_rk
self._data[self._row].end_rk = self._new_rk
elif self._column == "rk": elif self._column == "rk":
self._data[self._row].start_rk = self._new self._data[self._row].start_rk = self._new
self._data[self._row].end_rk = self._new self._data[self._row].end_rk = self._new

View File

@ -309,3 +309,10 @@ class InitialConditionsTemperatureWindow(PamhyrWindow):
if len(rows) == 0: if len(rows) == 0:
return return
self._table_spec.delete(rows) self._table_spec.delete(rows)
def _propagated_update(self, key=Modules(0)):
if Modules.NETWORK not in key:
return
self._table_spec.refresh()
self.table_spec.clearSelection()

View File

@ -103,7 +103,10 @@ class ComboBoxDelegate(QItemDelegate):
else: else:
self.editor.addItems( self.editor.addItems(
[self._trad['not_associated']] + [self._trad['not_associated']] +
self._data.edges_names() [
reach.name
for reach in self._data.enable_edges()
]
) )
self.editor.setCurrentText(index.data(Qt.DisplayRole)) self.editor.setCurrentText(index.data(Qt.DisplayRole))
@ -154,7 +157,9 @@ class TableModel(PamhyrTableModel):
self._long_types = self._trad.get_dict("long_types") self._long_types = self._trad.get_dict("long_types")
def get_true_data_row(self, row): def get_true_data_row(self, row):
lc = self._lst.get(self._tab, row) lc = self._lst.get_for_enabled_reaches(self._tab, row)
if lc is None:
return len(self._lst.get_tab(self._tab))
return next( return next(
map( map(
@ -167,7 +172,7 @@ class TableModel(PamhyrTableModel):
) )
def rowCount(self, parent): def rowCount(self, parent):
return self._lst.len(self._tab) return len(self._lst.get_tab_for_enabled_reaches(self._tab))
def data(self, index, role): def data(self, index, role):
if role != Qt.ItemDataRole.DisplayRole: if role != Qt.ItemDataRole.DisplayRole:
@ -175,21 +180,22 @@ class TableModel(PamhyrTableModel):
row = index.row() row = index.row()
column = index.column() column = index.column()
contribution = self._lst.get_for_enabled_reaches(self._tab, row)
if self._headers[column] == "name": if self._headers[column] == "name":
return self._lst.get(self._tab, row).name return contribution.name
elif self._headers[column] == "type": elif self._headers[column] == "type":
t = self._lst.get(self._tab, row).lctype t = contribution.lctype
return self._long_types[t] return self._long_types[t]
elif self._headers[column] == "edge": elif self._headers[column] == "edge":
n = self._lst.get(self._tab, row).reach n = contribution.reach
if n is None: if n is None:
return self._trad['not_associated'] return self._trad['not_associated']
return n.name return n.name
elif self._headers[column] == "begin_rk": elif self._headers[column] == "begin_rk":
return str(self._lst.get(self._tab, row).begin_rk) return str(contribution.begin_rk)
elif self._headers[column] == "end_rk": elif self._headers[column] == "end_rk":
return str(self._lst.get(self._tab, row).end_rk) return str(contribution.end_rk)
return QVariant() return QVariant()
@ -202,6 +208,8 @@ class TableModel(PamhyrTableModel):
row = index.row() row = index.row()
column = index.column() column = index.column()
contribution = self._lst.get_for_enabled_reaches(self._tab, row)
row = self.get_true_data_row(row)
try: try:
if self._headers[column] == "name": if self._headers[column] == "name":
@ -225,7 +233,7 @@ class TableModel(PamhyrTableModel):
) )
) )
elif self._headers[column] == "begin_rk": elif self._headers[column] == "begin_rk":
_edge = self._lst.get(self._tab, row).reach _edge = contribution.reach
_begin_rk = next( _begin_rk = next(
p for p in _edge.reach.profiles p for p in _edge.reach.profiles
if p.pamhyr_id == value if p.pamhyr_id == value
@ -236,7 +244,7 @@ class TableModel(PamhyrTableModel):
) )
) )
elif self._headers[column] == "end_rk": elif self._headers[column] == "end_rk":
_edge = self._lst.get(self._tab, row).reach _edge = contribution.reach
_end_rk = next( _end_rk = next(
p for p in _edge.reach.profiles p for p in _edge.reach.profiles
if p.pamhyr_id == value if p.pamhyr_id == value

View File

@ -213,11 +213,11 @@ class LateralContributionWindow(PamhyrWindow):
if len(rows) > 0: if len(rows) > 0:
edge = self._study.river\ edge = self._study.river\
.lateral_contribution\ .lateral_contribution\
.get(tab, rows[0])\ .get_for_enabled_reaches(tab, rows[0])\
.reach .reach
if edge: if edge:
data = edge.reach data = edge.reach
lc = self._lcs.get(tab, rows[0]) lc = self._lcs.get_for_enabled_reaches(tab, rows[0])
highlight = (lc.begin_rk, lc.end_rk) highlight = (lc.begin_rk, lc.end_rk)
for delegate in self._delegate_rk: for delegate in self._delegate_rk:
@ -236,7 +236,8 @@ class LateralContributionWindow(PamhyrWindow):
def add(self): def add(self):
tab = self.current_tab() tab = self.current_tab()
rows = self.index_selected_rows() rows = self.index_selected_rows()
if self._lcs.len(tab) == 0 or len(rows) == 0: visible = self._lcs.get_tab_for_enabled_reaches(tab)
if len(visible) == 0 or len(rows) == 0:
self._table[tab].add(0) self._table[tab].add(0)
else: else:
self._table[tab].add(rows[0]) self._table[tab].add(rows[0])
@ -291,7 +292,7 @@ class LateralContributionWindow(PamhyrWindow):
tab = self.current_tab() tab = self.current_tab()
rows = self.index_selected_rows() rows = self.index_selected_rows()
for row in rows: for row in rows:
data = self._lcs.get(tab, row) data = self._lcs.get_for_enabled_reaches(tab, row)
if self.sub_window_exists( if self.sub_window_exists(
EditLateralContributionWindow, EditLateralContributionWindow,

View File

@ -81,7 +81,10 @@ class ComboBoxDelegate(QItemDelegate):
else: else:
self.editor.addItems( self.editor.addItems(
[self._trad['not_associated']] + [self._trad['not_associated']] +
self._data.edges_names() [
reach.name
for reach in self._data.enable_edges()
]
) )
self.editor.setCurrentText(index.data(Qt.DisplayRole)) self.editor.setCurrentText(index.data(Qt.DisplayRole))
@ -119,6 +122,11 @@ class TableModel(PamhyrTableModel):
self._setup_lst() self._setup_lst()
def _setup_lst(self): def _setup_lst(self):
enabled_reach_ids = {
reach.id
for reach in self._data.enable_edges()
}
if self._lcs_list is not None: if self._lcs_list is not None:
self._lcs_pol_list = [ self._lcs_pol_list = [
lcs for lcs in self._lcs_list._lst lcs for lcs in self._lcs_list._lst
@ -127,7 +135,13 @@ class TableModel(PamhyrTableModel):
self._lst = list( self._lst = list(
filter( filter(
lambda x: x._deleted is False, lambda x: (
x._deleted is False and
(
x.reach in (None, -1) or
x.reach in enabled_reach_ids
)
),
self._lcs_pol_list self._lcs_pol_list
) )
) )
@ -137,6 +151,18 @@ class TableModel(PamhyrTableModel):
def rowCount(self, parent): def rowCount(self, parent):
return len(self._lst) return len(self._lst)
def get(self, row):
if 0 <= row < len(self._lst):
return self._lst[row]
return None
def refresh(self):
self.beginResetModel()
try:
self._setup_lst()
finally:
self.endResetModel()
def data(self, index, role): def data(self, index, role):
if role != Qt.ItemDataRole.DisplayRole: if role != Qt.ItemDataRole.DisplayRole:
return QVariant() return QVariant()
@ -170,11 +196,18 @@ class TableModel(PamhyrTableModel):
try: try:
if self._headers[column] == "reach": if self._headers[column] == "reach":
reach = self._data.reach(value)
rks = reach.reach.get_rk()
if len(rks) == 0:
return False
self._undo.push( self._undo.push(
SetReachCommand( SetReachCommand(
self._lcs_list, self._lst, self._lcs_list, self._lst,
row, row,
self._data.reach(value).id reach.id,
min(rks),
max(rks)
) )
) )
elif self._headers[column] == "begin_rk": elif self._headers[column] == "begin_rk":
@ -193,6 +226,12 @@ class TableModel(PamhyrTableModel):
logger.info(e) logger.info(e)
logger.debug(traceback.format_exc()) logger.debug(traceback.format_exc())
if self._headers[column] == "reach":
end_index = self.index(
row, self._headers.index("end_rk")
)
self.dataChanged.emit(index, end_index)
else:
self.dataChanged.emit(index, index) self.dataChanged.emit(index, index)
return True return True

View File

@ -64,20 +64,30 @@ class SetEndCommand(QUndoCommand):
class SetReachCommand(QUndoCommand): class SetReachCommand(QUndoCommand):
def __init__(self, lcs, lcs_lst, index, reach): def __init__(self, lcs, lcs_lst, index, reach, begin_rk, end_rk):
QUndoCommand.__init__(self) QUndoCommand.__init__(self)
self._lcs = lcs self._lcs = lcs
self._lcs_lst = lcs_lst self._lcs_lst = lcs_lst
self._index = index self._index = index
self._old = self._lcs_lst[self._index].reach self._old = self._lcs_lst[self._index].reach
self._old_begin_rk = self._lcs_lst[self._index].begin_rk
self._old_end_rk = self._lcs_lst[self._index].end_rk
self._new = reach self._new = reach
self._new_begin_rk = begin_rk
self._new_end_rk = end_rk
def undo(self): def undo(self):
self._lcs_lst[self._index].reach = self._old contribution = self._lcs_lst[self._index]
contribution.reach = self._old
contribution.begin_rk = self._old_begin_rk
contribution.end_rk = self._old_end_rk
def redo(self): def redo(self):
self._lcs_lst[self._index].reach = self._new contribution = self._lcs_lst[self._index]
contribution.reach = self._new
contribution.begin_rk = self._new_begin_rk
contribution.end_rk = self._new_end_rk
class AddCommand(QUndoCommand): class AddCommand(QUndoCommand):

View File

@ -20,6 +20,7 @@ import logging
from tools import trace, timer from tools import trace, timer
from Modules import Modules
from View.Tools.PamhyrWindow import PamhyrWindow from View.Tools.PamhyrWindow import PamhyrWindow
from PyQt5.QtGui import ( from PyQt5.QtGui import (
@ -187,12 +188,13 @@ class LateralContributionAdisTSWindow(PamhyrWindow):
data = None data = None
highlight = None highlight = None
tab = "liquid"
if len(rows) > 0: if len(rows) > 0:
reach_id = self._study.river\ contribution = self._table.get(rows[0])
.lateral_contributions_adists.lst[rows[0]]\ reach_id = (
.reach contribution.reach
if contribution is not None
else None
)
if reach_id: if reach_id:
reach = next( reach = next(
@ -201,8 +203,10 @@ class LateralContributionAdisTSWindow(PamhyrWindow):
self._study.river.reachs())) self._study.river.reachs()))
data = reach.reach data = reach.reach
lc = self._lcs.lst[rows[0]] highlight = (
highlight = (lc.begin_rk, lc.end_rk) contribution.begin_rk,
contribution.end_rk
)
for delegate in self._delegate_rk: for delegate in self._delegate_rk:
delegate.data = reach delegate.data = reach
@ -254,13 +258,23 @@ class LateralContributionAdisTSWindow(PamhyrWindow):
self._table.redo() self._table.redo()
self._set_current_reach() self._set_current_reach()
def _propagated_update(self, key=Modules(0)):
if Modules.NETWORK not in key:
return
self._table.refresh()
self.find(QTableView, "tableView").clearSelection()
self._set_current_reach()
def edit(self): def edit(self):
rows = self.index_selected_rows() rows = self.index_selected_rows()
if not rows: if not rows:
return return
for row in rows: for row in rows:
data = self._lcs.lst[row] data = self._table.get(row)
if data is None:
continue
if self.sub_window_exists( if self.sub_window_exists(
EditLateralContributionAdisTSWindow, EditLateralContributionAdisTSWindow,

View File

@ -1526,6 +1526,16 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
sl.show() sl.show()
def open_reach_sediment_layers(self): def open_reach_sediment_layers(self):
if self._study is None:
logger.debug(
"No study open for reach sediment layers edition..."
)
return
if not self._study.river.has_current_reach():
self.msg_select_reach()
return
reach = self._study.river.current_reach().reach reach = self._study.river.current_reach().reach
if self.sub_window_exists( if self.sub_window_exists(
@ -2307,11 +2317,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
logger.debug("No study open for sql debuging...") logger.debug("No study open for sql debuging...")
return return
# todo : gérer le cas où le dossier a un espace dans le nom
# (ne veut pas ouvrir sqlitebrowser)
file = self._study.filename file = self._study.filename
_ = subprocess.Popen( _ = subprocess.Popen(
f"sqlitebrowser {file}", ["sqlitebrowser", file]
shell=True
) )

View File

@ -87,7 +87,10 @@ class ComboBoxDelegate(QItemDelegate):
else: else:
self.editor.addItems( self.editor.addItems(
[self._trad['not_associated']] + [self._trad['not_associated']] +
self._data.edges_names() [
reach.name
for reach in self._data.enable_edges()
]
) )
self.editor.setCurrentText(str(index.data(Qt.DisplayRole))) self.editor.setCurrentText(str(index.data(Qt.DisplayRole)))
@ -144,8 +147,28 @@ class WeatherParametersTableModel(PamhyrTableModel):
if self._type == "ND" or self._data is None: if self._type == "ND" or self._data is None:
self._lst = [] self._lst = []
return return
enabled_reach_ids = {
reach.id
for reach in self._river.enable_edges()
}
self._lst = self._data.lst self._lst = self._data.lst
self._lst = list(filter(lambda wp: wp.type == self._type, self._lst)) self._lst = list(filter(
lambda wp: (
wp.type == self._type and
(
wp.reach is None or
wp.reach.id in enabled_reach_ids
)
),
self._lst
))
def refresh(self):
self.beginResetModel()
try:
self._setup_lst()
finally:
self.endResetModel()
def update_tab_spec(self, type="ND", enabled=True): def update_tab_spec(self, type="ND", enabled=True):
if enabled: if enabled:
@ -239,15 +262,24 @@ class WeatherParametersTableModel(PamhyrTableModel):
) )
) )
elif self._headers[column] == "reach": elif self._headers[column] == "reach":
edge = self._river.edge(value)
if not edge.reach.profiles:
return False
self._undo.push( self._undo.push(
SetEdgeCommand( SetEdgeCommand(
self._data, global_row, self._river.edge(value) self._data, global_row, edge
) )
) )
except Exception as e: except Exception as e:
logger.info(e) logger.info(e)
logger.debug(traceback.format_exc()) logger.debug(traceback.format_exc())
if self._headers[column] == "reach":
end_index = self.index(
row, self._headers.index("end_rk")
)
self.dataChanged.emit(index, end_index)
else:
self.dataChanged.emit(index, index) self.dataChanged.emit(index, index)
return True return True

View File

@ -125,14 +125,26 @@ class SetEdgeCommand(QUndoCommand):
self._wps = wps self._wps = wps
self._index = index self._index = index
self._old = self._wps.get(self._index).reach weather_parameter = self._wps.get(self._index)
self._old = weather_parameter.reach
self._old_begin = weather_parameter.begin_section
self._old_end = weather_parameter.end_section
self._new = edge self._new = edge
profiles = edge.reach.profiles
self._new_begin = min(profiles, key=lambda profile: profile.rk)
self._new_end = max(profiles, key=lambda profile: profile.rk)
def undo(self): def undo(self):
self._wps.get(self._index).reach = self._old weather_parameter = self._wps.get(self._index)
weather_parameter.reach = self._old
weather_parameter.begin_section = self._old_begin
weather_parameter.end_section = self._old_end
def redo(self): def redo(self):
self._wps.get(self._index).reach = self._new weather_parameter = self._wps.get(self._index)
weather_parameter.reach = self._new
weather_parameter.begin_section = self._new_begin
weather_parameter.end_section = self._new_end
class AddCommand(QUndoCommand): class AddCommand(QUndoCommand):

View File

@ -439,3 +439,10 @@ class WeatherParametersWindow(PamhyrWindow):
parent=self parent=self
) )
win.show() win.show()
def _propagated_update(self, key=Modules(0)):
if Modules.NETWORK not in key:
return
self._table_spec.refresh()
self.table_spec.clearSelection()