mirror of https://gitlab.com/pamhyr/pamhyr2
Scenarios: Merge remote-tracking branch 'origin/master'.
commit
e43c20c1e6
|
|
@ -1334,7 +1334,7 @@ https://gitlab.irstea.fr/theophile.terraz/pamhyr
|
||||||
|
|
||||||
You can improve or add translation for the project. To contribute to
|
You can improve or add translation for the project. To contribute to
|
||||||
Pamhyr2 translate, you need to use Qt Linguist[fn:qt-linguist]. Open
|
Pamhyr2 translate, you need to use Qt Linguist[fn:qt-linguist]. Open
|
||||||
Qt-linguist and edite the translation ({{{file(.ts)}}}) file, finally,
|
Qt-linguist and edit the translation ({{{file(.ts)}}}) file, finally,
|
||||||
commit the new version of file and make a merge request.
|
commit the new version of file and make a merge request.
|
||||||
|
|
||||||
If you want add a new language, edit the script
|
If you want add a new language, edit the script
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -411,7 +411,7 @@ class MeshingWithMageMailleurTT(AMeshingTool):
|
||||||
str,
|
str,
|
||||||
[
|
[
|
||||||
st_file, m_file,
|
st_file, m_file,
|
||||||
"update_rk", step,
|
"update_kp", step,
|
||||||
limites[0], limites[1],
|
limites[0], limites[1],
|
||||||
directrices[0], directrices[1],
|
directrices[0], directrices[1],
|
||||||
orientation, lm, linear, origin, origin_value
|
orientation, lm, linear, origin, origin_value
|
||||||
|
|
|
||||||
|
|
@ -509,3 +509,15 @@ class BoundaryCondition(SQLSubModel):
|
||||||
d = self._data
|
d = self._data
|
||||||
d[index], d[prev] = d[prev], d[index]
|
d[index], d[prev] = d[prev], d[index]
|
||||||
self._status.modified()
|
self._status.modified()
|
||||||
|
|
||||||
|
def reach(self, river):
|
||||||
|
r = []
|
||||||
|
if self._node is not None:
|
||||||
|
if river is not None:
|
||||||
|
for edge in river.edges():
|
||||||
|
if edge.node1.name == self._node.name:
|
||||||
|
r.append(edge.reach)
|
||||||
|
if edge.node2.name == self._node.name:
|
||||||
|
r.append(edge.reach)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ from tools import trace, timer
|
||||||
from Model.Tools.PamhyrDB import SQLSubModel
|
from Model.Tools.PamhyrDB import SQLSubModel
|
||||||
from Model.Scenario import Scenario
|
from Model.Scenario import Scenario
|
||||||
|
|
||||||
|
from numpy import interp
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -290,3 +292,17 @@ class Friction(SQLSubModel):
|
||||||
def end_strickler(self, strickler):
|
def end_strickler(self, strickler):
|
||||||
self._end_strickler = strickler
|
self._end_strickler = strickler
|
||||||
self._status.modified()
|
self._status.modified()
|
||||||
|
|
||||||
|
def get_friction(self, rk):
|
||||||
|
if not self.contains_rk(rk):
|
||||||
|
return None
|
||||||
|
minor = interp(rk,
|
||||||
|
[self.begin_rk, self.end_rk],
|
||||||
|
[self.begin_strickler.minor,
|
||||||
|
self.end_strickler.minor])
|
||||||
|
medium = interp(rk,
|
||||||
|
[self.begin_rk, self.end_rk],
|
||||||
|
[self.begin_strickler.medium,
|
||||||
|
self.end_strickler.medium])
|
||||||
|
|
||||||
|
return minor, medium
|
||||||
|
|
|
||||||
|
|
@ -332,8 +332,17 @@ class Profile(object):
|
||||||
def wet_points(self, z):
|
def wet_points(self, z):
|
||||||
raise NotImplementedMethodeError(self, self.wet_point)
|
raise NotImplementedMethodeError(self, self.wet_point)
|
||||||
|
|
||||||
|
def wet_width(self, z):
|
||||||
|
raise NotImplementedMethodeError(self, self.wet_width)
|
||||||
|
|
||||||
def wet_perimeter(self, z):
|
def wet_perimeter(self, z):
|
||||||
raise NotImplementedMethodeError(self, self.wet_perimeter)
|
raise NotImplementedMethodeError(self, self.wet_perimeter)
|
||||||
|
|
||||||
def wet_area(self, z):
|
def wet_area(self, z):
|
||||||
raise NotImplementedMethodeError(self, self.wet_area)
|
raise NotImplementedMethodeError(self, self.wet_area)
|
||||||
|
|
||||||
|
def wet_radius(self, z):
|
||||||
|
raise NotImplementedMethodeError(self, self.wet_radius)
|
||||||
|
|
||||||
|
def get_nb_wet_areas(self, z):
|
||||||
|
raise NotImplementedMethodeError(self, self.get_nb_wet_areas)
|
||||||
|
|
|
||||||
|
|
@ -486,31 +486,125 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||||
|
|
||||||
return abs(rg.dist(rd))
|
return abs(rg.dist(rd))
|
||||||
|
|
||||||
def wet_perimeter(self, z):
|
def wet_width(self, z):
|
||||||
poly = self.wet_polygon(z)
|
start, end = self.get_all_water_limits_ac(z)
|
||||||
|
|
||||||
if poly is None:
|
if len(start) == 0:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return poly.length
|
length = 0.0
|
||||||
|
for s, e in zip(start, end):
|
||||||
|
length += abs(s - e)
|
||||||
|
return length
|
||||||
|
|
||||||
|
def wet_perimeter(self, z):
|
||||||
|
lines = self.wet_lines(z)
|
||||||
|
|
||||||
|
if lines is None:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
length = 0.0
|
||||||
|
for line in lines:
|
||||||
|
length += line.length
|
||||||
|
return length
|
||||||
|
|
||||||
def wet_area(self, z):
|
def wet_area(self, z):
|
||||||
poly = self.wet_polygon(z)
|
lines = self.wet_lines(z)
|
||||||
|
|
||||||
if poly is None:
|
if lines is None:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return poly.area
|
area = 0.0
|
||||||
|
for line in lines:
|
||||||
|
if len(line.coords) > 2:
|
||||||
|
poly = geometry.Polygon(line)
|
||||||
|
area += poly.area
|
||||||
|
return area
|
||||||
|
|
||||||
|
def wet_radius(self, z):
|
||||||
|
p = self.wet_perimeter(z)
|
||||||
|
a = self.wet_area(z)
|
||||||
|
|
||||||
|
if p == 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return a/p
|
||||||
|
|
||||||
|
def wet_line(self, z):
|
||||||
|
points = self.wet_points(z)
|
||||||
|
if len(points) < 3:
|
||||||
|
return None
|
||||||
|
|
||||||
|
zz = map(lambda p: p.z, points)
|
||||||
|
station = self._get_station(points)
|
||||||
|
|
||||||
|
line = geometry.LineString(list(zip(station, zz)))
|
||||||
|
return line
|
||||||
|
|
||||||
|
def wet_lines(self, z):
|
||||||
|
points = self._points
|
||||||
|
if len(points) < 3:
|
||||||
|
return None
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
zz = list(map(lambda p: p.z, points))
|
||||||
|
station = self._get_station(points)
|
||||||
|
|
||||||
|
line = []
|
||||||
|
for i in range(self.number_points-1):
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
|
if zz[i] < z:
|
||||||
|
line.append([station[i], zz[i]])
|
||||||
|
|
||||||
|
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])
|
||||||
|
if len(line) > 2:
|
||||||
|
lines.append(geometry.LineString(line))
|
||||||
|
line = []
|
||||||
|
|
||||||
|
if zz[self.number_points-1] < z:
|
||||||
|
line.append([station[self.number_points-1], z])
|
||||||
|
if len(line) > 2:
|
||||||
|
lines.append(geometry.LineString(line))
|
||||||
|
line = []
|
||||||
|
|
||||||
|
return lines
|
||||||
|
|
||||||
|
def max_water_depth(self, z):
|
||||||
|
return z - self.z_min()
|
||||||
|
|
||||||
|
def mean_water_depth(self, z):
|
||||||
|
a = self.wet_area(z)
|
||||||
|
w = self.wet_width(z)
|
||||||
|
|
||||||
|
if w == 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return a/w
|
||||||
|
|
||||||
def wet_polygon(self, z):
|
def wet_polygon(self, z):
|
||||||
points = self.wet_points(z)
|
points = self.wet_points(z)
|
||||||
if len(points) < 3:
|
if len(points) < 3:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
z = map(lambda p: p.z, points)
|
zz = map(lambda p: p.z, points)
|
||||||
station = self._get_station(points)
|
station = self._get_station(points)
|
||||||
|
|
||||||
poly = geometry.Polygon(list(zip(station, z)))
|
poly = geometry.Polygon(list(zip(station, zz)))
|
||||||
return poly
|
return poly
|
||||||
|
|
||||||
def wet_points(self, z):
|
def wet_points(self, z):
|
||||||
|
|
@ -522,6 +616,63 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||||
|
|
||||||
return points
|
return points
|
||||||
|
|
||||||
|
def get_nb_wet_areas(self, z):
|
||||||
|
|
||||||
|
n_zones = 0
|
||||||
|
points = self._points
|
||||||
|
if points[0].z <= z:
|
||||||
|
n_zones += 1
|
||||||
|
|
||||||
|
for i in range(self.number_points-1):
|
||||||
|
if points[i].z > z and points[i+1].z <= z:
|
||||||
|
n_zones += 1
|
||||||
|
|
||||||
|
return n_zones
|
||||||
|
|
||||||
|
def get_all_water_limits_ac(self, z):
|
||||||
|
"""
|
||||||
|
Determine all water limits for z elevation.
|
||||||
|
"""
|
||||||
|
|
||||||
|
points = self._points
|
||||||
|
if len(points) < 3:
|
||||||
|
return None
|
||||||
|
|
||||||
|
zz = list(map(lambda p: p.z, points))
|
||||||
|
station = self._get_station(points)
|
||||||
|
|
||||||
|
start = []
|
||||||
|
if points[0].z <= z:
|
||||||
|
start.append(station[0])
|
||||||
|
|
||||||
|
for i in range(self.number_points-1):
|
||||||
|
if zz[i] > z and zz[i+1] <= z:
|
||||||
|
y = np.interp(
|
||||||
|
z,
|
||||||
|
[zz[i], zz[i+1]],
|
||||||
|
[station[i], station[i+1]]
|
||||||
|
)
|
||||||
|
start.append(y)
|
||||||
|
|
||||||
|
end = []
|
||||||
|
if points[-1].z <= z:
|
||||||
|
end.append(station[-1])
|
||||||
|
|
||||||
|
for i in reversed(range(self.number_points-1)):
|
||||||
|
if zz[i] <= z and zz[i+1] > z:
|
||||||
|
y = np.interp(
|
||||||
|
z,
|
||||||
|
[zz[i], zz[i+1]],
|
||||||
|
[station[i], station[i+1]]
|
||||||
|
)
|
||||||
|
end.append(y)
|
||||||
|
|
||||||
|
if len(start) != len(end):
|
||||||
|
logger.error(f"ERROR in get_all_water_limits_ac")
|
||||||
|
return [], []
|
||||||
|
|
||||||
|
return start, list(reversed(end))
|
||||||
|
|
||||||
def get_water_limits(self, z):
|
def get_water_limits(self, z):
|
||||||
"""
|
"""
|
||||||
Determine left and right limits of water elevation.
|
Determine left and right limits of water elevation.
|
||||||
|
|
@ -585,8 +736,8 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||||
Returns:
|
Returns:
|
||||||
Projection of the points of the profile on a plane.
|
Projection of the points of the profile on a plane.
|
||||||
"""
|
"""
|
||||||
if self.nb_points < 3:
|
if self.nb_points < 2:
|
||||||
return None
|
return [0.0]
|
||||||
else:
|
else:
|
||||||
return self._get_station(self.points)
|
return self._get_station(self.points)
|
||||||
|
|
||||||
|
|
@ -718,3 +869,9 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||||
self.point(i),
|
self.point(i),
|
||||||
self.point(i+1)
|
self.point(i+1)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def shift(self, x, y, z):
|
||||||
|
for p in self.points:
|
||||||
|
p.x = p.x + x
|
||||||
|
p.y = p.y + y
|
||||||
|
p.z = p.z + z
|
||||||
|
|
|
||||||
|
|
@ -479,8 +479,14 @@ class InitialConditions(SQLSubModel):
|
||||||
logger.debug(f"incline = {incline}")
|
logger.debug(f"incline = {incline}")
|
||||||
self._data = []
|
self._data = []
|
||||||
for profile in profiles:
|
for profile in profiles:
|
||||||
width = profile.width_approximation()
|
width = profile.wet_width(profile.z_min() + height)
|
||||||
strickler = 25
|
frictions = self._reach.frictions.frictions
|
||||||
|
strickler = None
|
||||||
|
for f in frictions:
|
||||||
|
if f.contains_rk(profile.rk):
|
||||||
|
strickler = f.get_friction(profile.rk)[0]
|
||||||
|
if strickler is None:
|
||||||
|
strickler = 25.0
|
||||||
|
|
||||||
if not compute_discharge:
|
if not compute_discharge:
|
||||||
discharge = data_discharge[profile.rk]
|
discharge = data_discharge[profile.rk]
|
||||||
|
|
@ -533,7 +539,13 @@ class InitialConditions(SQLSubModel):
|
||||||
self._data = []
|
self._data = []
|
||||||
for profile in profiles:
|
for profile in profiles:
|
||||||
width = profile.width_approximation()
|
width = profile.width_approximation()
|
||||||
strickler = 25
|
frictions = self._reach.frictions.frictions
|
||||||
|
strickler = None
|
||||||
|
for f in frictions:
|
||||||
|
if f.contains_rk(profile.rk):
|
||||||
|
strickler = f.get_friction(profile.rk)[0]
|
||||||
|
if strickler is None:
|
||||||
|
strickler = 25.0
|
||||||
|
|
||||||
if not compute_height:
|
if not compute_height:
|
||||||
height = data_height[profile.rk]
|
height = data_height[profile.rk]
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,7 @@ class Mage(CommandLineSolver):
|
||||||
if t in ["HYD", "QSO", "LIM"]:
|
if t in ["HYD", "QSO", "LIM"]:
|
||||||
v0 /= 60 # Convert first column to minute
|
v0 /= 60 # Convert first column to minute
|
||||||
|
|
||||||
f.write(f"{v0:10}{v1:10}\n")
|
f.write(f"{v0:9} {v1:9} \n")
|
||||||
|
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
# GenerateDialog.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from View.Tools.PamhyrWindow import PamhyrDialog
|
||||||
|
|
||||||
|
from PyQt5.QtGui import (
|
||||||
|
QKeySequence,
|
||||||
|
)
|
||||||
|
|
||||||
|
from PyQt5.QtCore import (
|
||||||
|
Qt, QVariant, QAbstractTableModel,
|
||||||
|
)
|
||||||
|
|
||||||
|
from PyQt5.QtWidgets import (
|
||||||
|
QDialogButtonBox, QComboBox, QUndoStack, QShortcut,
|
||||||
|
QDoubleSpinBox, QCheckBox, QPushButton
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class GenerateDialog(PamhyrDialog):
|
||||||
|
_pamhyr_ui = "BoundaryConditionsDialogGenerator"
|
||||||
|
_pamhyr_name = "Boundary Condition Options"
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
value,
|
||||||
|
reach,
|
||||||
|
title="Boundary Condition Options",
|
||||||
|
trad=None,
|
||||||
|
parent=None):
|
||||||
|
super(GenerateDialog, self).__init__(
|
||||||
|
title=trad[self._pamhyr_name],
|
||||||
|
options=[],
|
||||||
|
trad=trad,
|
||||||
|
parent=parent
|
||||||
|
)
|
||||||
|
|
||||||
|
self.value = value
|
||||||
|
self.find(QDoubleSpinBox, "doubleSpinBox").setValue(self.value)
|
||||||
|
self.reach = reach
|
||||||
|
self.find(QPushButton, "EstimateButton").clicked.connect(
|
||||||
|
self.estimate
|
||||||
|
)
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
self.value = self.find(QDoubleSpinBox, "doubleSpinBox").value()
|
||||||
|
super().accept()
|
||||||
|
|
||||||
|
def reject(self):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def estimate(self):
|
||||||
|
self.value = abs(self.reach.get_incline_median_mean())
|
||||||
|
self.find(QDoubleSpinBox, "doubleSpinBox").setValue(self.value)
|
||||||
|
|
@ -48,6 +48,7 @@ from Model.BoundaryCondition.BoundaryConditionTypes import (
|
||||||
from View.BoundaryCondition.Edit.UndoCommand import (
|
from View.BoundaryCondition.Edit.UndoCommand import (
|
||||||
SetDataCommand, AddCommand, DelCommand,
|
SetDataCommand, AddCommand, DelCommand,
|
||||||
SortCommand, MoveCommand, PasteCommand,
|
SortCommand, MoveCommand, PasteCommand,
|
||||||
|
ReplaceDataCommand,
|
||||||
)
|
)
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
@ -200,3 +201,13 @@ class TableModel(PamhyrTableModel):
|
||||||
def update(self):
|
def update(self):
|
||||||
# self.auto_sort()
|
# self.auto_sort()
|
||||||
self.layoutChanged.emit()
|
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()
|
||||||
|
|
|
||||||
|
|
@ -181,3 +181,30 @@ class PasteCommand(QUndoCommand):
|
||||||
def redo(self):
|
def redo(self):
|
||||||
for bc in self._bcs:
|
for bc in self._bcs:
|
||||||
self._data.insert(self._row, bc)
|
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])
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ import logging
|
||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
|
|
||||||
|
from numpy import sqrt
|
||||||
|
|
||||||
from View.Tools.PamhyrWindow import PamhyrWindow
|
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||||
from View.Tools.PamhyrWidget import PamhyrWidget
|
from View.Tools.PamhyrWidget import PamhyrWidget
|
||||||
from View.Tools.PamhyrDelegate import PamhyrExTimeDelegate
|
from View.Tools.PamhyrDelegate import PamhyrExTimeDelegate
|
||||||
|
|
@ -48,6 +50,7 @@ from View.BoundaryCondition.Edit.translate import BCETranslate
|
||||||
from View.BoundaryCondition.Edit.UndoCommand import SetMetaDataCommand
|
from View.BoundaryCondition.Edit.UndoCommand import SetMetaDataCommand
|
||||||
from View.BoundaryCondition.Edit.Table import TableModel
|
from View.BoundaryCondition.Edit.Table import TableModel
|
||||||
from View.BoundaryCondition.Edit.Plot import Plot
|
from View.BoundaryCondition.Edit.Plot import Plot
|
||||||
|
from View.BoundaryCondition.Edit.GenerateDialog import GenerateDialog
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|
@ -104,6 +107,7 @@ class EditBoundaryConditionWindow(PamhyrWindow):
|
||||||
self._data = data
|
self._data = data
|
||||||
trad = BCETranslate()
|
trad = BCETranslate()
|
||||||
self._long_types = trad.get_dict("long_types")
|
self._long_types = trad.get_dict("long_types")
|
||||||
|
self._study = study
|
||||||
|
|
||||||
name = trad[self._pamhyr_name]
|
name = trad[self._pamhyr_name]
|
||||||
if self._data is not None:
|
if self._data is not None:
|
||||||
|
|
@ -200,6 +204,18 @@ class EditBoundaryConditionWindow(PamhyrWindow):
|
||||||
self.find(QAction, "action_del").triggered.connect(self.delete)
|
self.find(QAction, "action_del").triggered.connect(self.delete)
|
||||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
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.dataChanged.connect(self.update)
|
||||||
self._table.layoutChanged.connect(self.update)
|
self._table.layoutChanged.connect(self.update)
|
||||||
|
|
||||||
|
|
@ -320,3 +336,46 @@ class EditBoundaryConditionWindow(PamhyrWindow):
|
||||||
self._table.redo()
|
self._table.redo()
|
||||||
self.plot.update()
|
self.plot.update()
|
||||||
self.widget_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 = abs(reach.get_incline_median_mean())
|
||||||
|
dlg = GenerateDialog(incline,
|
||||||
|
reach,
|
||||||
|
trad=self._trad,
|
||||||
|
parent=self)
|
||||||
|
if dlg.exec():
|
||||||
|
incline = dlg.value
|
||||||
|
frictions = reach._parent.frictions.frictions
|
||||||
|
z_min = profile.z_min()
|
||||||
|
z_max = profile.z_max()
|
||||||
|
strickler = None
|
||||||
|
for f in frictions:
|
||||||
|
if f.contains_rk(profile.rk):
|
||||||
|
strickler = f.get_friction(profile.rk)[0]
|
||||||
|
if strickler is None:
|
||||||
|
strickler = 25.0
|
||||||
|
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]
|
||||||
|
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
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ class BCETranslate(BCTranslate):
|
||||||
self._dict["Edit Boundary Conditions"] = _translate(
|
self._dict["Edit Boundary Conditions"] = _translate(
|
||||||
"BoundaryCondition", "Edit boundary conditions"
|
"BoundaryCondition", "Edit boundary conditions"
|
||||||
)
|
)
|
||||||
|
self._dict["Boundary Condition Options"] = _translate(
|
||||||
|
"BoundaryCondition", "Boundary Condition Options")
|
||||||
|
|
||||||
self._sub_dict["table_headers"] = {
|
self._sub_dict["table_headers"] = {
|
||||||
"x": _translate("BoundaryCondition", "X"),
|
"x": _translate("BoundaryCondition", "X"),
|
||||||
|
|
|
||||||
|
|
@ -313,10 +313,6 @@ class Plot(PamhyrPlot):
|
||||||
x_carto = self.data.x()
|
x_carto = self.data.x()
|
||||||
y_carto = self.data.y()
|
y_carto = self.data.y()
|
||||||
|
|
||||||
if (len(x_carto) < 3 or len(y_carto) < 3 or len(x) < 3):
|
|
||||||
# Noting to do in this case
|
|
||||||
return
|
|
||||||
|
|
||||||
self.profile_line2D, = self.canvas.axes.plot(
|
self.profile_line2D, = self.canvas.axes.plot(
|
||||||
x, y, color=self.color_plot,
|
x, y, color=self.color_plot,
|
||||||
lw=1.5, markersize=7, marker='+',
|
lw=1.5, markersize=7, marker='+',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
# ShiftDialog.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from View.Tools.PamhyrWindow import PamhyrDialog
|
||||||
|
|
||||||
|
|
||||||
|
class ShiftDialog(PamhyrDialog):
|
||||||
|
_pamhyr_ui = "GeometryReachShift"
|
||||||
|
_pamhyr_name = "Shift"
|
||||||
|
|
||||||
|
def __init__(self, trad=None, parent=None):
|
||||||
|
super(ShiftDialog, self).__init__(
|
||||||
|
title=trad[self._pamhyr_name],
|
||||||
|
trad=trad,
|
||||||
|
options=[],
|
||||||
|
parent=parent
|
||||||
|
)
|
||||||
|
|
||||||
|
self._init_default_values()
|
||||||
|
|
||||||
|
def _init_default_values(self):
|
||||||
|
self._dx = 0.0
|
||||||
|
self._dy = 0.0
|
||||||
|
self._dz = 0.0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dx(self):
|
||||||
|
return self._dx
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dy(self):
|
||||||
|
return self._dy
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dz(self):
|
||||||
|
return self._dz
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
self._dx = self.get_double_spin_box("doubleSpinBox_X")
|
||||||
|
self._dy = self.get_double_spin_box("doubleSpinBox_Y")
|
||||||
|
self._dz = self.get_double_spin_box("doubleSpinBox_Z")
|
||||||
|
super().accept()
|
||||||
|
|
||||||
|
def reject(self):
|
||||||
|
self.close()
|
||||||
|
|
@ -267,3 +267,12 @@ class GeometryReachTableModel(PamhyrTableModel):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
|
def shift(self, rows, dx, dy, dz):
|
||||||
|
|
||||||
|
self._undo.push(
|
||||||
|
ShiftCommand(
|
||||||
|
self._data, rows, dx, dy, dz
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.layoutChanged.emit()
|
||||||
|
|
|
||||||
|
|
@ -82,3 +82,12 @@ class GeometryTranslate(MainTranslate):
|
||||||
self._dict["Meshing"] = _translate(
|
self._dict["Meshing"] = _translate(
|
||||||
"Geometry", "Meshing"
|
"Geometry", "Meshing"
|
||||||
)
|
)
|
||||||
|
self._dict["UpdateRK"] = _translate(
|
||||||
|
"Geometry", "UpdateRK"
|
||||||
|
)
|
||||||
|
self._dict["Purge"] = _translate(
|
||||||
|
"Geometry", "Purge"
|
||||||
|
)
|
||||||
|
self._dict["Shift"] = _translate(
|
||||||
|
"Geometry", "Shift"
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -281,3 +281,32 @@ class PurgeCommand(QUndoCommand):
|
||||||
def redo(self):
|
def redo(self):
|
||||||
for profile in self._reach._profiles:
|
for profile in self._reach._profiles:
|
||||||
profile.purge(self._np_purge)
|
profile.purge(self._np_purge)
|
||||||
|
|
||||||
|
|
||||||
|
class ShiftCommand(QUndoCommand):
|
||||||
|
def __init__(self, reach, rows, dx, dy, dz):
|
||||||
|
QUndoCommand.__init__(self)
|
||||||
|
|
||||||
|
self._reach = reach
|
||||||
|
self._rows = rows
|
||||||
|
self._dx = dx
|
||||||
|
self._dy = dy
|
||||||
|
self._dz = dz
|
||||||
|
|
||||||
|
self._old = []
|
||||||
|
for profile in self._reach.profiles:
|
||||||
|
self._old.append(profile.points.copy())
|
||||||
|
|
||||||
|
def undo(self):
|
||||||
|
for i in self._rows:
|
||||||
|
profile = self._reach.profiles[i]
|
||||||
|
self._reach.profiles[i].shift(-self._dx,
|
||||||
|
-self._dy,
|
||||||
|
-self._dz)
|
||||||
|
|
||||||
|
def redo(self):
|
||||||
|
for i in self._rows:
|
||||||
|
profile = self._reach.profiles[i]
|
||||||
|
self._reach.profiles[i].shift(self._dx,
|
||||||
|
self._dy,
|
||||||
|
self._dz)
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ from View.Geometry.PlotRKZ import PlotRKZ
|
||||||
from View.Geometry.MeshingDialog import MeshingDialog
|
from View.Geometry.MeshingDialog import MeshingDialog
|
||||||
from View.Geometry.UpdateRKDialog import UpdateRKDialog
|
from View.Geometry.UpdateRKDialog import UpdateRKDialog
|
||||||
from View.Geometry.PurgeDialog import PurgeDialog
|
from View.Geometry.PurgeDialog import PurgeDialog
|
||||||
|
from View.Geometry.ShiftDialog import ShiftDialog
|
||||||
from View.Geometry.Translate import GeometryTranslate
|
from View.Geometry.Translate import GeometryTranslate
|
||||||
from View.Geometry.Profile.Window import ProfileWindow
|
from View.Geometry.Profile.Window import ProfileWindow
|
||||||
|
|
||||||
|
|
@ -205,6 +206,7 @@ class GeometryWindow(PamhyrWindow):
|
||||||
"action_meshing": self.edit_meshing,
|
"action_meshing": self.edit_meshing,
|
||||||
"action_update_rk": self.update_rk,
|
"action_update_rk": self.update_rk,
|
||||||
"action_purge": self.purge,
|
"action_purge": self.purge,
|
||||||
|
"action_shift": self.shift,
|
||||||
}
|
}
|
||||||
|
|
||||||
for action in actions:
|
for action in actions:
|
||||||
|
|
@ -511,10 +513,6 @@ class GeometryWindow(PamhyrWindow):
|
||||||
self._table.move_down(row)
|
self._table.move_down(row)
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
|
|
||||||
def purge(self):
|
|
||||||
self._table.purge()
|
|
||||||
self.update_redraw()
|
|
||||||
|
|
||||||
def purge(self):
|
def purge(self):
|
||||||
try:
|
try:
|
||||||
dlg = PurgeDialog(
|
dlg = PurgeDialog(
|
||||||
|
|
@ -527,6 +525,28 @@ class GeometryWindow(PamhyrWindow):
|
||||||
logger_exception(e)
|
logger_exception(e)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def shift(self):
|
||||||
|
rows = sorted(
|
||||||
|
list(
|
||||||
|
set(
|
||||||
|
[index.row() for index in self.tableView.selectedIndexes()]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
dlg = ShiftDialog(
|
||||||
|
trad=self._trad,
|
||||||
|
parent=self
|
||||||
|
)
|
||||||
|
if dlg.exec():
|
||||||
|
self._table.shift(rows,
|
||||||
|
dlg.dx,
|
||||||
|
dlg.dy,
|
||||||
|
dlg.dz)
|
||||||
|
except Exception as e:
|
||||||
|
logger_exception(e)
|
||||||
|
return
|
||||||
|
|
||||||
def duplicate(self):
|
def duplicate(self):
|
||||||
rows = [
|
rows = [
|
||||||
row.row() for row in
|
row.row() for row in
|
||||||
|
|
@ -615,7 +635,7 @@ class GeometryWindow(PamhyrWindow):
|
||||||
QSettings.UserScope, 'MyOrg'
|
QSettings.UserScope, 'MyOrg'
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._study.filename != "" or self._study.filename is not None:
|
if self._study.filename != "" and self._study.filename is not None:
|
||||||
default_directory = os.path.basename(self._study.filename)
|
default_directory = os.path.basename(self._study.filename)
|
||||||
current_dir = settings.value(
|
current_dir = settings.value(
|
||||||
'current_directory',
|
'current_directory',
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ class InitialConditionsWindow(PamhyrWindow):
|
||||||
return rows[0].row()
|
return rows[0].row()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.update(propagate=False)
|
self._update(propagate=False)
|
||||||
|
|
||||||
def _update(self, propagate=True):
|
def _update(self, propagate=True):
|
||||||
self._update_plot()
|
self._update_plot()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import logging
|
||||||
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from numpy import sqrt
|
||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Tools.PamhyrPlot import PamhyrPlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
@ -32,6 +33,11 @@ unit = {
|
||||||
"elevation": "0-meter",
|
"elevation": "0-meter",
|
||||||
"water_elevation": "0-meter",
|
"water_elevation": "0-meter",
|
||||||
"discharge": "1-m3s",
|
"discharge": "1-m3s",
|
||||||
|
"velocity": "2-ms",
|
||||||
|
"depth": "3-meter",
|
||||||
|
"mean_depth": "3-meter",
|
||||||
|
"froude": "4-dimensionless",
|
||||||
|
"wet_area": "5-m2",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -76,74 +82,155 @@ class CustomPlot(PamhyrPlot):
|
||||||
reach = results.river.reach(self._reach)
|
reach = results.river.reach(self._reach)
|
||||||
rk = reach.geometry.get_rk()
|
rk = reach.geometry.get_rk()
|
||||||
z_min = reach.geometry.get_z_min()
|
z_min = reach.geometry.get_z_min()
|
||||||
|
q = list(
|
||||||
|
map(
|
||||||
|
lambda p: p.get_ts_key(self._timestamp, "Q"),
|
||||||
|
reach.profiles
|
||||||
|
)
|
||||||
|
)
|
||||||
|
z = list(
|
||||||
|
map(
|
||||||
|
lambda p: p.get_ts_key(self._timestamp, "Z"),
|
||||||
|
reach.profiles
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# self.canvas.axes.set_xlim(
|
shift = 0
|
||||||
# left=min(rk), right=max(rk)
|
compt = 0
|
||||||
# )
|
for ax in sorted(self._axes):
|
||||||
|
if compt == 0:
|
||||||
meter_axes = self.canvas.axes
|
self._axes[ax].spines['left'].set_position(('outward', shift))
|
||||||
m3S_axes = self.canvas.axes
|
compt += 1
|
||||||
if "0-meter" in self._y_axes and "1-m3s" in self._y_axes:
|
else:
|
||||||
m3s_axes = self._axes["1-m3s"]
|
self._axes[ax].spines['right'].set_position(('outward', shift))
|
||||||
|
shift += 60
|
||||||
|
|
||||||
lines = {}
|
lines = {}
|
||||||
if "elevation" in self._y:
|
if "elevation" in self._y:
|
||||||
# meter_axes.set_ylim(
|
|
||||||
# bottom=min(0, min(z_min)),
|
|
||||||
# top=max(z_min) + 1
|
|
||||||
# )
|
|
||||||
|
|
||||||
line = meter_axes.plot(
|
ax = self._axes[unit["elevation"]]
|
||||||
|
line = ax.plot(
|
||||||
rk, z_min,
|
rk, z_min,
|
||||||
color='grey', lw=1.,
|
color='grey', lw=1.,
|
||||||
)
|
)
|
||||||
lines["elevation"] = line
|
lines["elevation"] = line
|
||||||
|
|
||||||
if "water_elevation" in self._y:
|
if "water_elevation" in self._y:
|
||||||
# Water elevation
|
|
||||||
water_z = list(
|
|
||||||
map(
|
|
||||||
lambda p: p.get_ts_key(self._timestamp, "Z"),
|
|
||||||
reach.profiles
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# meter_axes.set_ylim(
|
ax = self._axes[unit["water_elevation"]]
|
||||||
# bottom=min(0, min(z_min)),
|
line = ax.plot(
|
||||||
# top=max(water_z) + 1
|
rk, z, lw=1.,
|
||||||
# )
|
|
||||||
|
|
||||||
line = meter_axes.plot(
|
|
||||||
rk, water_z, lw=1.,
|
|
||||||
color='blue',
|
color='blue',
|
||||||
)
|
)
|
||||||
lines["water_elevation"] = line
|
lines["water_elevation"] = line
|
||||||
|
|
||||||
if "elevation" in self._y:
|
if "elevation" in self._y:
|
||||||
meter_axes.fill_between(
|
ax.fill_between(
|
||||||
rk, z_min, water_z,
|
rk, z_min, z,
|
||||||
color='blue', alpha=0.5, interpolate=True
|
color='blue', alpha=0.5, interpolate=True
|
||||||
)
|
)
|
||||||
|
|
||||||
if "discharge" in self._y:
|
if "discharge" in self._y:
|
||||||
q = list(
|
|
||||||
map(
|
|
||||||
lambda p: p.get_ts_key(self._timestamp, "Q"),
|
|
||||||
reach.profiles
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# m3s_axes.set_ylim(
|
ax = self._axes[unit["discharge"]]
|
||||||
# bottom=min(0, min(q)),
|
line = ax.plot(
|
||||||
# top=max(q) + 1
|
|
||||||
# )
|
|
||||||
|
|
||||||
line = m3s_axes.plot(
|
|
||||||
rk, q, lw=1.,
|
rk, q, lw=1.,
|
||||||
color='r',
|
color='r',
|
||||||
)
|
)
|
||||||
lines["discharge"] = line
|
lines["discharge"] = line
|
||||||
|
|
||||||
|
if "velocity" in self._y:
|
||||||
|
|
||||||
|
ax = self._axes[unit["velocity"]]
|
||||||
|
v = list(
|
||||||
|
map(
|
||||||
|
lambda p: p.geometry.speed(
|
||||||
|
p.get_ts_key(self._timestamp, "Q"),
|
||||||
|
p.get_ts_key(self._timestamp, "Z")),
|
||||||
|
reach.profiles
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
line = ax.plot(
|
||||||
|
rk, v, lw=1.,
|
||||||
|
color='g',
|
||||||
|
)
|
||||||
|
lines["velocity"] = line
|
||||||
|
|
||||||
|
if "depth" in self._y:
|
||||||
|
|
||||||
|
ax = self._axes[unit["depth"]]
|
||||||
|
d = list(
|
||||||
|
map(
|
||||||
|
lambda p: p.geometry.max_water_depth(
|
||||||
|
p.get_ts_key(self._timestamp, "Z")),
|
||||||
|
reach.profiles
|
||||||
|
)
|
||||||
|
)
|
||||||
|
line = ax.plot(
|
||||||
|
rk, d,
|
||||||
|
color='brown', lw=1.,
|
||||||
|
)
|
||||||
|
lines["depth"] = line
|
||||||
|
|
||||||
|
if "mean_depth" in self._y:
|
||||||
|
|
||||||
|
ax = self._axes[unit["mean_depth"]]
|
||||||
|
d = list(
|
||||||
|
map(
|
||||||
|
lambda p: p.geometry.mean_water_depth(
|
||||||
|
p.get_ts_key(self._timestamp, "Z")),
|
||||||
|
reach.profiles
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
line = ax.plot(
|
||||||
|
rk, d,
|
||||||
|
color='orange', lw=1.,
|
||||||
|
)
|
||||||
|
lines["mean_depth"] = line
|
||||||
|
|
||||||
|
if "froude" in self._y:
|
||||||
|
|
||||||
|
ax = self._axes[unit["froude"]]
|
||||||
|
fr = list(
|
||||||
|
map(
|
||||||
|
lambda p:
|
||||||
|
p.geometry.speed(
|
||||||
|
p.get_ts_key(self._timestamp, "Q"),
|
||||||
|
p.get_ts_key(self._timestamp, "Z")) /
|
||||||
|
sqrt(9.81 * (
|
||||||
|
p.geometry.wet_area(
|
||||||
|
p.get_ts_key(self._timestamp, "Z")) /
|
||||||
|
p.geometry.wet_width(
|
||||||
|
p.get_ts_key(self._timestamp, "Z"))
|
||||||
|
)),
|
||||||
|
reach.profiles
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
line = ax.plot(
|
||||||
|
rk, fr, color='black', linestyle='--', lw=1.,
|
||||||
|
)
|
||||||
|
lines["froude"] = line
|
||||||
|
|
||||||
|
if "wet_area" in self._y:
|
||||||
|
|
||||||
|
ax = self._axes[unit["wet_area"]]
|
||||||
|
d = list(
|
||||||
|
map(
|
||||||
|
lambda p: p.geometry.wet_area(
|
||||||
|
p.get_ts_key(self._timestamp, "Z")),
|
||||||
|
reach.profiles
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
line = ax.plot(
|
||||||
|
rk, d,
|
||||||
|
color='blue', linestyle='--', lw=1.,
|
||||||
|
)
|
||||||
|
lines["wet_area"] = line
|
||||||
|
|
||||||
# Legend
|
# Legend
|
||||||
lns = reduce(
|
lns = reduce(
|
||||||
lambda acc, line: acc + line,
|
lambda acc, line: acc + line,
|
||||||
|
|
@ -151,7 +238,7 @@ class CustomPlot(PamhyrPlot):
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
labs = list(map(lambda line: self._trad[line], lines))
|
labs = list(map(lambda line: self._trad[line], lines))
|
||||||
self.canvas.axes.legend(lns, labs, loc="lower left")
|
self.canvas.axes.legend(lns, labs, loc="best")
|
||||||
|
|
||||||
def _customize_x_axes_time(self, ts, mode="time"):
|
def _customize_x_axes_time(self, ts, mode="time"):
|
||||||
# Custom time display
|
# Custom time display
|
||||||
|
|
@ -198,79 +285,137 @@ class CustomPlot(PamhyrPlot):
|
||||||
reach = results.river.reach(self._reach)
|
reach = results.river.reach(self._reach)
|
||||||
profile = reach.profile(self._profile)
|
profile = reach.profile(self._profile)
|
||||||
|
|
||||||
meter_axes = self.canvas.axes
|
shift = 0
|
||||||
m3S_axes = self.canvas.axes
|
compt = 0
|
||||||
if "0-meter" in self._y_axes and "1-m3s" in self._y_axes:
|
for ax in sorted(self._axes):
|
||||||
m3s_axes = self._axes["1-m3s"]
|
if compt == 0:
|
||||||
|
self._axes[ax].spines['left'].set_position(('outward', shift))
|
||||||
|
compt += 1
|
||||||
|
else:
|
||||||
|
self._axes[ax].spines['right'].set_position(('outward', shift))
|
||||||
|
shift += 60
|
||||||
|
|
||||||
ts = list(results.get("timestamps"))
|
ts = list(results.get("timestamps"))
|
||||||
ts.sort()
|
ts.sort()
|
||||||
|
|
||||||
# self.canvas.axes.set_xlim(
|
q = profile.get_key("Q")
|
||||||
# left=min(ts), right=max(ts)
|
z = profile.get_key("Z")
|
||||||
# )
|
z_min = profile.geometry.z_min()
|
||||||
|
ts_z_min = list(
|
||||||
|
map(
|
||||||
|
lambda ts: z_min,
|
||||||
|
ts
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
x = ts
|
|
||||||
lines = {}
|
lines = {}
|
||||||
if "elevation" in self._y:
|
if "elevation" in self._y:
|
||||||
# Z min is constant in time
|
# Z min is constant in time
|
||||||
z_min = profile.geometry.z_min()
|
|
||||||
ts_z_min = list(
|
|
||||||
map(
|
|
||||||
lambda ts: z_min,
|
|
||||||
ts
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
line = meter_axes.plot(
|
ax = self._axes[unit["elevation"]]
|
||||||
|
|
||||||
|
line = ax.plot(
|
||||||
ts, ts_z_min,
|
ts, ts_z_min,
|
||||||
color='grey', lw=1.
|
color='grey', lw=1.
|
||||||
)
|
)
|
||||||
lines["elevation"] = line
|
lines["elevation"] = line
|
||||||
|
|
||||||
if "water_elevation" in self._y:
|
if "water_elevation" in self._y:
|
||||||
# Water elevation
|
|
||||||
z = profile.get_key("Z")
|
|
||||||
|
|
||||||
# meter_axes.set_ylim(
|
ax = self._axes[unit["water_elevation"]]
|
||||||
# bottom=min(0, min(z)),
|
line = ax.plot(
|
||||||
# top=max(z) + 1
|
|
||||||
# )
|
|
||||||
|
|
||||||
line = meter_axes.plot(
|
|
||||||
ts, z, lw=1.,
|
ts, z, lw=1.,
|
||||||
color='b',
|
color='b',
|
||||||
)
|
)
|
||||||
lines["water_elevation"] = line
|
lines["water_elevation"] = line
|
||||||
|
|
||||||
if "elevation" in self._y:
|
if "elevation" in self._y:
|
||||||
z_min = profile.geometry.z_min()
|
|
||||||
ts_z_min = list(
|
|
||||||
map(
|
|
||||||
lambda ts: z_min,
|
|
||||||
ts
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
meter_axes.fill_between(
|
ax.fill_between(
|
||||||
ts, ts_z_min, z,
|
ts, ts_z_min, z,
|
||||||
color='blue', alpha=0.5, interpolate=True
|
color='blue', alpha=0.5, interpolate=True
|
||||||
)
|
)
|
||||||
|
|
||||||
if "discharge" in self._y:
|
if "discharge" in self._y:
|
||||||
q = profile.get_key("Q")
|
|
||||||
|
|
||||||
# m3s_axes.set_ylim(
|
ax = self._axes[unit["discharge"]]
|
||||||
# bottom=min(0, min(q)),
|
line = ax.plot(
|
||||||
# top=max(q) + 1
|
|
||||||
# )
|
|
||||||
|
|
||||||
line = m3s_axes.plot(
|
|
||||||
ts, q, lw=1.,
|
ts, q, lw=1.,
|
||||||
color='r',
|
color='r',
|
||||||
)
|
)
|
||||||
lines["discharge"] = line
|
lines["discharge"] = line
|
||||||
|
|
||||||
|
if "velocity" in self._y:
|
||||||
|
|
||||||
|
ax = self._axes[unit["velocity"]]
|
||||||
|
v = list(
|
||||||
|
map(
|
||||||
|
lambda q, z: profile.geometry.speed(q, z),
|
||||||
|
q, z
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
line = ax.plot(
|
||||||
|
ts, v, lw=1.,
|
||||||
|
color='g',
|
||||||
|
)
|
||||||
|
lines["velocity"] = line
|
||||||
|
|
||||||
|
if "depth" in self._y:
|
||||||
|
|
||||||
|
ax = self._axes[unit["depth"]]
|
||||||
|
d = list(
|
||||||
|
map(lambda z: profile.geometry.max_water_depth(z), z)
|
||||||
|
)
|
||||||
|
|
||||||
|
line = ax.plot(
|
||||||
|
ts, d,
|
||||||
|
color='brown', lw=1.,
|
||||||
|
)
|
||||||
|
lines["depth"] = line
|
||||||
|
|
||||||
|
if "mean_depth" in self._y:
|
||||||
|
|
||||||
|
ax = self._axes[unit["mean_depth"]]
|
||||||
|
d = list(
|
||||||
|
map(lambda z: profile.geometry.mean_water_depth(z), z)
|
||||||
|
)
|
||||||
|
|
||||||
|
line = ax.plot(
|
||||||
|
ts, d,
|
||||||
|
color='orange', lw=1.,
|
||||||
|
)
|
||||||
|
lines["depth"] = line
|
||||||
|
|
||||||
|
if "froude" in self._y:
|
||||||
|
|
||||||
|
ax = self._axes[unit["froude"]]
|
||||||
|
d = list(
|
||||||
|
map(lambda z, q:
|
||||||
|
profile.geometry.speed(q, z) /
|
||||||
|
sqrt(9.81 * (
|
||||||
|
profile.geometry.wet_area(z) /
|
||||||
|
profile.geometry.wet_width(z))
|
||||||
|
), z, q)
|
||||||
|
)
|
||||||
|
|
||||||
|
line = ax.plot(
|
||||||
|
ts, d, color='black', linestyle='--', lw=1.,
|
||||||
|
)
|
||||||
|
lines["froude"] = line
|
||||||
|
|
||||||
|
if "wet_area" in self._y:
|
||||||
|
|
||||||
|
ax = self._axes[unit["wet_area"]]
|
||||||
|
d = list(
|
||||||
|
map(lambda z: profile.geometry.wet_area(z), z)
|
||||||
|
)
|
||||||
|
|
||||||
|
line = ax.plot(
|
||||||
|
ts, d, color='blue', linestyle='--', lw=1.,
|
||||||
|
)
|
||||||
|
lines["wet_area"] = line
|
||||||
|
|
||||||
self._customize_x_axes_time(ts)
|
self._customize_x_axes_time(ts)
|
||||||
|
|
||||||
# Legend
|
# Legend
|
||||||
|
|
@ -280,7 +425,7 @@ class CustomPlot(PamhyrPlot):
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
labs = list(map(lambda line: self._trad[line], lines))
|
labs = list(map(lambda line: self._trad[line], lines))
|
||||||
self.canvas.axes.legend(lns, labs, loc="lower left")
|
self.canvas.axes.legend(lns, labs, loc="best")
|
||||||
|
|
||||||
@timer
|
@timer
|
||||||
def draw(self):
|
def draw(self):
|
||||||
|
|
@ -300,6 +445,7 @@ class CustomPlot(PamhyrPlot):
|
||||||
color='black', fontsize=10
|
color='black', fontsize=10
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._axes[self._y_axes[0]] = self.canvas.axes
|
||||||
for axes in self._y_axes[1:]:
|
for axes in self._y_axes[1:]:
|
||||||
if axes in self._axes:
|
if axes in self._axes:
|
||||||
self._axes[axes].clear()
|
self._axes[axes].clear()
|
||||||
|
|
@ -316,8 +462,22 @@ class CustomPlot(PamhyrPlot):
|
||||||
self._draw_rk()
|
self._draw_rk()
|
||||||
elif self._x == "time":
|
elif self._x == "time":
|
||||||
self._draw_time()
|
self._draw_time()
|
||||||
|
if self._x == "rk":
|
||||||
|
reach = self.data.river.reach(self._reach)
|
||||||
|
profile = reach.profile(self._profile)
|
||||||
|
x = profile.rk
|
||||||
|
elif self._x == "time":
|
||||||
|
x = self._timestamp
|
||||||
|
|
||||||
|
self._current, = self.canvas.axes.plot(
|
||||||
|
[x, x],
|
||||||
|
self.canvas.axes.get_ylim(),
|
||||||
|
# label=self.label_timestamp,
|
||||||
|
color='grey',
|
||||||
|
linestyle="dashed",
|
||||||
|
lw=1.,
|
||||||
|
)
|
||||||
|
|
||||||
self.canvas.figure.tight_layout()
|
|
||||||
self.canvas.figure.canvas.draw_idle()
|
self.canvas.figure.canvas.draw_idle()
|
||||||
if self.toolbar is not None:
|
if self.toolbar is not None:
|
||||||
self.toolbar.update()
|
self.toolbar.update()
|
||||||
|
|
@ -326,6 +486,7 @@ class CustomPlot(PamhyrPlot):
|
||||||
def update(self):
|
def update(self):
|
||||||
if not self._init:
|
if not self._init:
|
||||||
self.draw()
|
self.draw()
|
||||||
|
self.draw_current()
|
||||||
return
|
return
|
||||||
|
|
||||||
def set_reach(self, reach_id):
|
def set_reach(self, reach_id):
|
||||||
|
|
@ -339,9 +500,23 @@ class CustomPlot(PamhyrPlot):
|
||||||
|
|
||||||
if self._x != "rk":
|
if self._x != "rk":
|
||||||
self.update()
|
self.update()
|
||||||
|
else:
|
||||||
|
self.draw_current()
|
||||||
|
|
||||||
def set_timestamp(self, timestamp):
|
def set_timestamp(self, timestamp):
|
||||||
self._timestamp = timestamp
|
self._timestamp = timestamp
|
||||||
|
|
||||||
if self._x != "time":
|
if self._x != "time":
|
||||||
self.update()
|
self.update()
|
||||||
|
else:
|
||||||
|
self.draw_current()
|
||||||
|
|
||||||
|
def draw_current(self):
|
||||||
|
if self._x == "rk":
|
||||||
|
reach = self.data.river.reach(self._reach)
|
||||||
|
profile = reach.profile(self._profile)
|
||||||
|
x = profile.rk
|
||||||
|
elif self._x == "time":
|
||||||
|
x = self._timestamp
|
||||||
|
self._current.set_data([x, x], self.canvas.axes.get_ylim())
|
||||||
|
self.canvas.figure.canvas.draw_idle()
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,14 @@ class CustomPlotTranslate(ResultsTranslate):
|
||||||
self._dict['elevation'] = _translate(
|
self._dict['elevation'] = _translate(
|
||||||
"CustomPlot", "Bed elevation (m)"
|
"CustomPlot", "Bed elevation (m)"
|
||||||
)
|
)
|
||||||
|
self._dict['velocity'] = self._dict["unit_speed"]
|
||||||
|
self._dict['width'] = self._dict["unit_width"]
|
||||||
|
self._dict['max_depth'] = self._dict["unit_max_height"]
|
||||||
|
self._dict['mean_depth'] = self._dict["unit_mean_height"]
|
||||||
|
self._dict['wet_area'] = self._dict["unit_wet_area"]
|
||||||
|
self._dict['wet_perimeter'] = self._dict["unit_wet_perimeter"]
|
||||||
|
self._dict['hydraulic_radius'] = self._dict["unit_hydraulic_radius"]
|
||||||
|
self._dict['froude'] = self._dict["unit_froude"]
|
||||||
|
|
||||||
# Unit corresponding long name (plot axes display)
|
# Unit corresponding long name (plot axes display)
|
||||||
|
|
||||||
|
|
@ -47,6 +55,10 @@ class CustomPlotTranslate(ResultsTranslate):
|
||||||
"CustomPlot", "Bed elevation (m)"
|
"CustomPlot", "Bed elevation (m)"
|
||||||
)
|
)
|
||||||
self._dict['1-m3s'] = self._dict["unit_discharge"]
|
self._dict['1-m3s'] = self._dict["unit_discharge"]
|
||||||
|
self._dict['2-ms'] = self._dict["unit_speed"]
|
||||||
|
self._dict['3-meter'] = self._dict["unit_height"]
|
||||||
|
self._dict['4-dimensionless'] = self._dict["unit_froude"]
|
||||||
|
self._dict['5-m2'] = self._dict["wet_area"]
|
||||||
|
|
||||||
# SubDict
|
# SubDict
|
||||||
|
|
||||||
|
|
@ -58,4 +70,9 @@ class CustomPlotTranslate(ResultsTranslate):
|
||||||
"elevation": self._dict["elevation"],
|
"elevation": self._dict["elevation"],
|
||||||
"water_elevation": self._dict["water_elevation"],
|
"water_elevation": self._dict["water_elevation"],
|
||||||
"discharge": self._dict["discharge"],
|
"discharge": self._dict["discharge"],
|
||||||
|
"velocity": self._dict["velocity"],
|
||||||
|
"depth": self._dict["max_depth"],
|
||||||
|
"mean_depth": self._dict["mean_depth"],
|
||||||
|
"froude": self._dict["froude"],
|
||||||
|
"wet_area": self._dict["wet_area"],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,13 +88,14 @@ class PlotH(PamhyrPlot):
|
||||||
|
|
||||||
self.draw_max(reach)
|
self.draw_max(reach)
|
||||||
self.draw_data(reach, profile)
|
self.draw_data(reach, profile)
|
||||||
self.draw_current(reach, profile)
|
self.draw_current()
|
||||||
|
|
||||||
self.set_ticks_time_formater()
|
self.set_ticks_time_formater()
|
||||||
|
|
||||||
self.enable_legend()
|
self.enable_legend()
|
||||||
|
|
||||||
self.idle()
|
self.idle()
|
||||||
|
self.update_current()
|
||||||
self._init = True
|
self._init = True
|
||||||
|
|
||||||
def draw_data(self, reach, profile):
|
def draw_data(self, reach, profile):
|
||||||
|
|
@ -111,21 +112,12 @@ class PlotH(PamhyrPlot):
|
||||||
**self.plot_default_kargs
|
**self.plot_default_kargs
|
||||||
)
|
)
|
||||||
|
|
||||||
def draw_current(self, reach, profile):
|
def draw_current(self):
|
||||||
min_y, max_y = reduce(
|
|
||||||
lambda acc, p: (
|
|
||||||
acc[0] + [min(p.get_key("Q"))],
|
|
||||||
acc[1] + [max(p.get_key("Q"))]
|
|
||||||
),
|
|
||||||
reach.profiles,
|
|
||||||
([], [])
|
|
||||||
)
|
|
||||||
|
|
||||||
self._current, = self.canvas.axes.plot(
|
self._current, = self.canvas.axes.plot(
|
||||||
[self._current_timestamp, self._current_timestamp],
|
[self._current_timestamp, self._current_timestamp],
|
||||||
[min(min_y), max(max_y)],
|
self.canvas.axes.get_ylim(),
|
||||||
# label=self.label_timestamp,
|
# label=self.label_timestamp,
|
||||||
color=self.color_plot_river_bottom,
|
color="grey",
|
||||||
linestyle="dashed",
|
linestyle="dashed",
|
||||||
lw=1.,
|
lw=1.,
|
||||||
)
|
)
|
||||||
|
|
@ -162,14 +154,14 @@ class PlotH(PamhyrPlot):
|
||||||
|
|
||||||
def set_timestamp(self, timestamp):
|
def set_timestamp(self, timestamp):
|
||||||
self._current_timestamp = timestamp
|
self._current_timestamp = timestamp
|
||||||
self.update()
|
self.update_current()
|
||||||
|
self.update_idle()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
if not self._init:
|
if not self._init:
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
self.update_data()
|
self.update_data()
|
||||||
|
|
||||||
self.update_idle()
|
self.update_idle()
|
||||||
|
|
||||||
def update_data(self):
|
def update_data(self):
|
||||||
|
|
@ -181,8 +173,13 @@ class PlotH(PamhyrPlot):
|
||||||
|
|
||||||
self._line.set_data(x, y)
|
self._line.set_data(x, y)
|
||||||
|
|
||||||
_, min_max = self._current.get_data()
|
|
||||||
self._current.set_data(
|
self._current.set_data(
|
||||||
self._current_timestamp,
|
self._current_timestamp,
|
||||||
min_max
|
self.canvas.axes.get_ylim()
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_current(self):
|
||||||
|
self._current.set_data(
|
||||||
|
self._current_timestamp,
|
||||||
|
self.canvas.axes.get_ylim()
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
from numpy import sqrt
|
||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
|
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
|
|
@ -86,12 +88,46 @@ class TableModel(PamhyrTableModel):
|
||||||
elif self._headers[column] == "discharge":
|
elif self._headers[column] == "discharge":
|
||||||
v = self._lst[row].get_ts_key(self._timestamp, "Q")
|
v = self._lst[row].get_ts_key(self._timestamp, "Q")
|
||||||
return f"{v:.4f}"
|
return f"{v:.4f}"
|
||||||
elif self._headers[column] == "speed":
|
elif self._headers[column] == "velocity":
|
||||||
q = self._lst[row].get_ts_key(self._timestamp, "Q")
|
q = self._lst[row].get_ts_key(self._timestamp, "Q")
|
||||||
z = self._lst[row].get_ts_key(self._timestamp, "Z")
|
z = self._lst[row].get_ts_key(self._timestamp, "Z")
|
||||||
|
|
||||||
v = self._lst[row].geometry.speed(q, z)
|
v = self._lst[row].geometry.speed(q, z)
|
||||||
return f"{v:.4f}"
|
return f"{v:.4f}"
|
||||||
|
elif self._headers[column] == "width":
|
||||||
|
z = self._lst[row].get_ts_key(self._timestamp, "Z")
|
||||||
|
v = self._lst[row].geometry.wet_width(z)
|
||||||
|
return f"{v:.4f}"
|
||||||
|
elif self._headers[column] == "max_depth":
|
||||||
|
z = self._lst[row].get_ts_key(self._timestamp, "Z")
|
||||||
|
v = self._lst[row].geometry.max_water_depth(z)
|
||||||
|
return f"{v:.4f}"
|
||||||
|
elif self._headers[column] == "mean_depth":
|
||||||
|
z = self._lst[row].get_ts_key(self._timestamp, "Z")
|
||||||
|
v = self._lst[row].geometry.mean_water_depth(z)
|
||||||
|
return f"{v:.4f}"
|
||||||
|
elif self._headers[column] == "wet_area":
|
||||||
|
z = self._lst[row].get_ts_key(self._timestamp, "Z")
|
||||||
|
v = self._lst[row].geometry.wet_area(z)
|
||||||
|
return f"{v:.4f}"
|
||||||
|
elif self._headers[column] == "wet_perimeter":
|
||||||
|
z = self._lst[row].get_ts_key(self._timestamp, "Z")
|
||||||
|
v = self._lst[row].geometry.wet_perimeter(z)
|
||||||
|
return f"{v:.4f}"
|
||||||
|
elif self._headers[column] == "hydraulic_radius":
|
||||||
|
z = self._lst[row].get_ts_key(self._timestamp, "Z")
|
||||||
|
v = self._lst[row].geometry.wet_radius(z)
|
||||||
|
return f"{v:.4f}"
|
||||||
|
elif self._headers[column] == "froude":
|
||||||
|
q = self._lst[row].get_ts_key(self._timestamp, "Q")
|
||||||
|
z = self._lst[row].get_ts_key(self._timestamp, "Z")
|
||||||
|
v = self._lst[row].geometry.speed(q, z)
|
||||||
|
a = self._lst[row].geometry.wet_area(z)
|
||||||
|
b = self._lst[row].geometry.wet_width(z)
|
||||||
|
froude = v / sqrt(9.81 * (a / b))
|
||||||
|
return f"{froude:.4f}"
|
||||||
|
else:
|
||||||
|
v = 0.0
|
||||||
|
return f"{v:.4f}"
|
||||||
|
|
||||||
return QVariant()
|
return QVariant()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ from PyQt5.QtWidgets import (
|
||||||
QFileDialog, QTableView, QAbstractItemView,
|
QFileDialog, QTableView, QAbstractItemView,
|
||||||
QUndoStack, QShortcut, QAction, QItemDelegate,
|
QUndoStack, QShortcut, QAction, QItemDelegate,
|
||||||
QComboBox, QVBoxLayout, QHeaderView, QTabWidget,
|
QComboBox, QVBoxLayout, QHeaderView, QTabWidget,
|
||||||
QSlider, QLabel, QWidget, QGridLayout,
|
QSlider, QLabel, QWidget, QGridLayout, QTabBar
|
||||||
)
|
)
|
||||||
|
|
||||||
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
|
|
@ -108,9 +108,9 @@ class ResultsWindow(PamhyrWindow):
|
||||||
try:
|
try:
|
||||||
self._timestamps = sorted(list(self._results.get("timestamps")))
|
self._timestamps = sorted(list(self._results.get("timestamps")))
|
||||||
|
|
||||||
|
self.setup_slider()
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_plots()
|
self.setup_plots()
|
||||||
self.setup_slider()
|
|
||||||
self.setup_statusbar()
|
self.setup_statusbar()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -128,12 +128,11 @@ class ResultsWindow(PamhyrWindow):
|
||||||
undo=self._undo_stack,
|
undo=self._undo_stack,
|
||||||
opt_data=t
|
opt_data=t
|
||||||
)
|
)
|
||||||
|
self._table[t]._timestamp = self._timestamps[
|
||||||
|
self._slider_time.value()]
|
||||||
|
|
||||||
def setup_slider(self):
|
def setup_slider(self):
|
||||||
self._slider_profile = self.find(QSlider, f"verticalSlider_profile")
|
|
||||||
default_reach = self._results.river.reach(0)
|
default_reach = self._results.river.reach(0)
|
||||||
self._slider_profile.setMaximum(len(default_reach.profiles) - 1)
|
|
||||||
self._slider_profile.setValue(0)
|
|
||||||
|
|
||||||
self._slider_time = self.find(QSlider, f"horizontalSlider_time")
|
self._slider_time = self.find(QSlider, f"horizontalSlider_time")
|
||||||
self._slider_time.setMaximum(len(self._timestamps) - 1)
|
self._slider_time.setMaximum(len(self._timestamps) - 1)
|
||||||
|
|
@ -158,6 +157,12 @@ class ResultsWindow(PamhyrWindow):
|
||||||
|
|
||||||
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)
|
||||||
|
tab_widget = self.find(QTabWidget, f"tabWidget")
|
||||||
|
tab_widget.setTabsClosable(True)
|
||||||
|
tab_widget.tabCloseRequested.connect(self.delete_tab)
|
||||||
|
tab_widget.tabBar().setTabButton(0, QTabBar.RightSide, None)
|
||||||
|
tab_widget.tabBar().setTabButton(1, QTabBar.RightSide, None)
|
||||||
|
tab_widget.tabBar().setTabButton(2, QTabBar.RightSide, None)
|
||||||
self.canvas.setObjectName("canvas")
|
self.canvas.setObjectName("canvas")
|
||||||
self.toolbar = PamhyrPlotToolbar(
|
self.toolbar = PamhyrPlotToolbar(
|
||||||
self.canvas, self, items=[
|
self.canvas, self, items=[
|
||||||
|
|
@ -303,7 +308,8 @@ class ResultsWindow(PamhyrWindow):
|
||||||
actions = {
|
actions = {
|
||||||
"action_reload": self._reload,
|
"action_reload": self._reload,
|
||||||
"action_add": self._add_custom_plot,
|
"action_add": self._add_custom_plot,
|
||||||
"action_export": self.export,
|
# "action_export": self.export,
|
||||||
|
"action_export": self.export_current,
|
||||||
}
|
}
|
||||||
|
|
||||||
for action in actions:
|
for action in actions:
|
||||||
|
|
@ -327,8 +333,6 @@ class ResultsWindow(PamhyrWindow):
|
||||||
|
|
||||||
self._table[t].dataChanged.connect(fun[t])
|
self._table[t].dataChanged.connect(fun[t])
|
||||||
|
|
||||||
self._slider_profile.valueChanged.connect(
|
|
||||||
self._set_current_profile_slider)
|
|
||||||
self._slider_time.valueChanged.connect(self._set_current_timestamp)
|
self._slider_time.valueChanged.connect(self._set_current_timestamp)
|
||||||
self._button_play.setChecked(False)
|
self._button_play.setChecked(False)
|
||||||
self._button_play.clicked.connect(self._pause)
|
self._button_play.clicked.connect(self._pause)
|
||||||
|
|
@ -442,7 +446,6 @@ class ResultsWindow(PamhyrWindow):
|
||||||
|
|
||||||
ind = indexes[0].row()
|
ind = indexes[0].row()
|
||||||
self.update(profile_id=ind)
|
self.update(profile_id=ind)
|
||||||
self._slider_profile.setValue(ind)
|
|
||||||
|
|
||||||
def _set_current_profile_raw_data(self):
|
def _set_current_profile_raw_data(self):
|
||||||
table = self.find(QTableView, f"tableView_raw_data")
|
table = self.find(QTableView, f"tableView_raw_data")
|
||||||
|
|
@ -452,11 +455,6 @@ class ResultsWindow(PamhyrWindow):
|
||||||
|
|
||||||
ind = indexes[0].row()
|
ind = indexes[0].row()
|
||||||
self.update(profile_id=ind)
|
self.update(profile_id=ind)
|
||||||
self._slider_profile.setValue(ind)
|
|
||||||
|
|
||||||
def _set_current_profile_slider(self):
|
|
||||||
pid = self._slider_profile.value()
|
|
||||||
self.update(profile_id=pid)
|
|
||||||
|
|
||||||
def _set_current_timestamp(self):
|
def _set_current_timestamp(self):
|
||||||
timestamp = self._timestamps[self._slider_time.value()]
|
timestamp = self._timestamps[self._slider_time.value()]
|
||||||
|
|
@ -500,7 +498,7 @@ class ResultsWindow(PamhyrWindow):
|
||||||
tab_widget = self.find(QTabWidget, f"tabWidget")
|
tab_widget = self.find(QTabWidget, f"tabWidget")
|
||||||
|
|
||||||
# This plot already exists
|
# This plot already exists
|
||||||
if name in self._additional_plot:
|
if name in [tab_widget.tabText(i) for i in range(tab_widget.count())]:
|
||||||
tab_widget.setCurrentWidget(
|
tab_widget.setCurrentWidget(
|
||||||
tab_widget.findChild(QWidget, wname)
|
tab_widget.findChild(QWidget, wname)
|
||||||
)
|
)
|
||||||
|
|
@ -591,12 +589,15 @@ class ResultsWindow(PamhyrWindow):
|
||||||
)
|
)
|
||||||
|
|
||||||
def export_to(self, directory):
|
def export_to(self, directory):
|
||||||
|
timestamps = sorted(self._results.get("timestamps"))
|
||||||
for reach in self._results.river.reachs:
|
for reach in self._results.river.reachs:
|
||||||
self.export_reach(reach, directory)
|
self.export_reach(reach, directory, timestamps)
|
||||||
|
|
||||||
def export_reach(self, reach, directory):
|
def export_reach(self, reach, directory, timestamps):
|
||||||
name = reach.name
|
name = reach.name
|
||||||
name = name.replace(" ", "-")
|
name = name.replace(" ", "-")
|
||||||
|
if len(timestamps) == 1:
|
||||||
|
name = f"{name}_t{timestamps[0]}"
|
||||||
|
|
||||||
file_name = os.path.join(
|
file_name = os.path.join(
|
||||||
directory,
|
directory,
|
||||||
|
|
@ -606,28 +607,40 @@ class ResultsWindow(PamhyrWindow):
|
||||||
with open(file_name, 'w', newline='') as csvfile:
|
with open(file_name, 'w', newline='') as csvfile:
|
||||||
writer = csv.writer(csvfile, delimiter=',',
|
writer = csv.writer(csvfile, delimiter=',',
|
||||||
quotechar='|', quoting=csv.QUOTE_MINIMAL)
|
quotechar='|', quoting=csv.QUOTE_MINIMAL)
|
||||||
writer.writerow(["name", "rk", "data-file"])
|
if len(timestamps) > 1:
|
||||||
for profile in reach.profiles:
|
writer.writerow(["name", "rk", "data-file"])
|
||||||
p_file_name = os.path.join(
|
for profile in reach.profiles:
|
||||||
directory,
|
p_file_name = os.path.join(
|
||||||
f"cs_{profile.geometry.id}.csv"
|
directory,
|
||||||
)
|
f"cs_{profile.geometry.id}.csv"
|
||||||
|
)
|
||||||
|
|
||||||
writer.writerow([
|
writer.writerow([
|
||||||
profile.name,
|
profile.name,
|
||||||
profile.rk,
|
profile.rk,
|
||||||
p_file_name
|
p_file_name
|
||||||
])
|
])
|
||||||
|
|
||||||
self.export_profile(reach, profile, p_file_name)
|
self.export_profile(reach,
|
||||||
|
profile,
|
||||||
|
p_file_name,
|
||||||
|
timestamps)
|
||||||
|
else:
|
||||||
|
ts = timestamps[0]
|
||||||
|
writer.writerow(self._table["raw_data"]._headers)
|
||||||
|
for row in range(self._table["raw_data"].rowCount()):
|
||||||
|
line = []
|
||||||
|
for column in range(self._table["raw_data"].columnCount()):
|
||||||
|
index = self._table["raw_data"].index(row, column)
|
||||||
|
line.append(self._table["raw_data"].data(index))
|
||||||
|
writer.writerow(line)
|
||||||
|
|
||||||
def export_profile(self, reach, profile, file_name):
|
def export_profile(self, reach, profile, file_name, timestamps):
|
||||||
with open(file_name, 'w', newline='') as csvfile:
|
with open(file_name, 'w', newline='') as csvfile:
|
||||||
writer = csv.writer(csvfile, delimiter=',',
|
writer = csv.writer(csvfile, delimiter=',',
|
||||||
quotechar='|', quoting=csv.QUOTE_MINIMAL)
|
quotechar='|', quoting=csv.QUOTE_MINIMAL)
|
||||||
|
|
||||||
writer.writerow(["timestamp", "z", "q"])
|
writer.writerow(["timestamp", "z", "q"])
|
||||||
timestamps = sorted(self._results.get("timestamps"))
|
|
||||||
|
|
||||||
for ts in timestamps:
|
for ts in timestamps:
|
||||||
writer.writerow([
|
writer.writerow([
|
||||||
|
|
@ -635,3 +648,18 @@ class ResultsWindow(PamhyrWindow):
|
||||||
profile.get_ts_key(ts, "Z"),
|
profile.get_ts_key(ts, "Z"),
|
||||||
profile.get_ts_key(ts, "Q"),
|
profile.get_ts_key(ts, "Q"),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def export_current(self):
|
||||||
|
self.file_dialog(
|
||||||
|
select_file=False,
|
||||||
|
callback=lambda d: self.export_current_to(d[0])
|
||||||
|
)
|
||||||
|
|
||||||
|
def export_current_to(self, directory):
|
||||||
|
reach = self._results.river.reachs[self._get_current_reach()]
|
||||||
|
self.export_reach(reach, directory, [self._get_current_timestamp()])
|
||||||
|
|
||||||
|
def delete_tab(self, index):
|
||||||
|
tab_widget = self.find(QTabWidget, f"tabWidget")
|
||||||
|
self._additional_plot.pop(tab_widget.tabText(index))
|
||||||
|
tab_widget.removeTab(index)
|
||||||
|
|
|
||||||
|
|
@ -57,5 +57,12 @@ class ResultsTranslate(MainTranslate):
|
||||||
"name": _translate("Results", "Profile"),
|
"name": _translate("Results", "Profile"),
|
||||||
"water_elevation": self._dict["unit_water_elevation"],
|
"water_elevation": self._dict["unit_water_elevation"],
|
||||||
"discharge": self._dict["unit_discharge"],
|
"discharge": self._dict["unit_discharge"],
|
||||||
"speed": self._dict["unit_speed"],
|
"velocity": self._dict["unit_speed"],
|
||||||
|
"width": self._dict["unit_width"],
|
||||||
|
"max_depth": self._dict["unit_max_height"],
|
||||||
|
"mean_depth": self._dict["unit_mean_height"],
|
||||||
|
"wet_area": self._dict["unit_wet_area"],
|
||||||
|
"wet_perimeter": self._dict["unit_wet_perimeter"],
|
||||||
|
"hydraulic_radius": self._dict["unit_hydraulic_radius"],
|
||||||
|
"froude": self._dict["unit_froude"],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,6 @@ class PamhyrPlot(APlot):
|
||||||
self.canvas.axes.autoscale_view(True, True, True)
|
self.canvas.axes.autoscale_view(True, True, True)
|
||||||
self.canvas.axes.autoscale()
|
self.canvas.axes.autoscale()
|
||||||
|
|
||||||
self.canvas.figure.tight_layout()
|
|
||||||
self.canvas.figure.canvas.draw_idle()
|
self.canvas.figure.canvas.draw_idle()
|
||||||
|
|
||||||
self.toolbar_update()
|
self.toolbar_update()
|
||||||
|
|
@ -205,7 +204,6 @@ class PamhyrPlot(APlot):
|
||||||
self.canvas.axes.autoscale_view(True, True, True)
|
self.canvas.axes.autoscale_view(True, True, True)
|
||||||
self.canvas.axes.autoscale()
|
self.canvas.axes.autoscale()
|
||||||
|
|
||||||
self.canvas.figure.tight_layout()
|
|
||||||
self.canvas.figure.canvas.draw_idle()
|
self.canvas.figure.canvas.draw_idle()
|
||||||
|
|
||||||
self.toolbar_update()
|
self.toolbar_update()
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class MplCanvas(FigureCanvasQTAgg):
|
||||||
fig = Figure(
|
fig = Figure(
|
||||||
figsize=(width, height),
|
figsize=(width, height),
|
||||||
dpi=dpi,
|
dpi=dpi,
|
||||||
layout='tight',
|
layout='constrained',
|
||||||
)
|
)
|
||||||
super(MplCanvas, self).__init__(fig)
|
super(MplCanvas, self).__init__(fig)
|
||||||
|
|
||||||
|
|
@ -36,7 +36,6 @@ class MplCanvas(FigureCanvasQTAgg):
|
||||||
self.axes.yaxis.tick_left()
|
self.axes.yaxis.tick_left()
|
||||||
self.axes.xaxis.tick_bottom()
|
self.axes.xaxis.tick_bottom()
|
||||||
self.axes.spines[['top', 'right']].set_color('none')
|
self.axes.spines[['top', 'right']].set_color('none')
|
||||||
self.figure.tight_layout()
|
|
||||||
self.add_arrows()
|
self.add_arrows()
|
||||||
|
|
||||||
def add_arrows(self):
|
def add_arrows(self):
|
||||||
|
|
|
||||||
|
|
@ -55,16 +55,18 @@ class UnitTranslate(CommonWordTranslate):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(UnitTranslate, self).__init__()
|
super(UnitTranslate, self).__init__()
|
||||||
|
|
||||||
self._dict["unit_rk"] = _translate("Unit", "River Kilometric (m)")
|
self._dict["unit_rk"] = _translate("Unit", "River Kilometer (m)")
|
||||||
self._dict["unit_width"] = _translate("Unit", "Width (m)")
|
self._dict["unit_width"] = _translate("Unit", "Width (m)")
|
||||||
self._dict["unit_height"] = _translate("Unit", "Height (m)")
|
self._dict["unit_height"] = _translate("Unit", "Depth (m)")
|
||||||
|
self._dict["unit_max_height"] = _translate("Unit", "Max Depth (m)")
|
||||||
|
self._dict["unit_mean_height"] = _translate("Unit", "Mean Depth (m)")
|
||||||
self._dict["unit_diameter"] = _translate("Unit", "Diameter (m)")
|
self._dict["unit_diameter"] = _translate("Unit", "Diameter (m)")
|
||||||
self._dict["unit_thickness"] = _translate("Unit", "Thickness (m)")
|
self._dict["unit_thickness"] = _translate("Unit", "Thickness (m)")
|
||||||
self._dict["unit_elevation"] = _translate("Unit", "Elevation (m)")
|
self._dict["unit_elevation"] = _translate("Unit", "Elevation (m)")
|
||||||
self._dict["unit_water_elevation"] = _translate(
|
self._dict["unit_water_elevation"] = _translate(
|
||||||
"Unit", "Water elevation (m)"
|
"Unit", "Water elevation (m)"
|
||||||
)
|
)
|
||||||
self._dict["unit_speed"] = _translate("Unit", "Speed (m/s)")
|
self._dict["unit_speed"] = _translate("Unit", "Velocity (m/s)")
|
||||||
self._dict["unit_discharge"] = _translate("Unit", "Discharge (m³/s)")
|
self._dict["unit_discharge"] = _translate("Unit", "Discharge (m³/s)")
|
||||||
self._dict["unit_area"] = _translate("Unit", "Area (hectare)")
|
self._dict["unit_area"] = _translate("Unit", "Area (hectare)")
|
||||||
|
|
||||||
|
|
@ -74,6 +76,15 @@ class UnitTranslate(CommonWordTranslate):
|
||||||
self._dict["unit_date_s"] = _translate("Unit", "Date (sec)")
|
self._dict["unit_date_s"] = _translate("Unit", "Date (sec)")
|
||||||
self._dict["unit_date_iso"] = _translate("Unit", "Date (ISO format)")
|
self._dict["unit_date_iso"] = _translate("Unit", "Date (ISO format)")
|
||||||
|
|
||||||
|
self._dict["unit_wet_area"] = _translate("Unit", "Wet Area (m²)")
|
||||||
|
self._dict["unit_wet_perimeter"] = _translate(
|
||||||
|
"Unit", "Wet Perimeter (m)"
|
||||||
|
)
|
||||||
|
self._dict["unit_hydraulic_radius"] = _translate(
|
||||||
|
"Unit", "Hydraulic Radius (m)"
|
||||||
|
)
|
||||||
|
self._dict["unit_froude"] = _translate("Unit", "Froude number")
|
||||||
|
|
||||||
|
|
||||||
class MainTranslate(UnitTranslate):
|
class MainTranslate(UnitTranslate):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Dialog</class>
|
||||||
|
<widget class="QDialog" name="Dialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>356</width>
|
||||||
|
<height>107</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Options</string>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleName">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="locale">
|
||||||
|
<locale language="English" country="Europe"/>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Slope</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>999999.998999999952503</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="EstimateButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Estimate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
|
|
@ -73,6 +73,8 @@
|
||||||
<addaction name="action_add"/>
|
<addaction name="action_add"/>
|
||||||
<addaction name="action_del"/>
|
<addaction name="action_del"/>
|
||||||
<addaction name="action_sort"/>
|
<addaction name="action_sort"/>
|
||||||
|
<addaction name="action_generate_uniform"/>
|
||||||
|
<addaction name="action_generate_critical"/>
|
||||||
</widget>
|
</widget>
|
||||||
<action name="action_add">
|
<action name="action_add">
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
|
|
@ -119,6 +121,25 @@
|
||||||
<string>Sort points</string>
|
<string>Sort points</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</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>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@
|
||||||
<addaction name="action_meshing"/>
|
<addaction name="action_meshing"/>
|
||||||
<addaction name="action_update_rk"/>
|
<addaction name="action_update_rk"/>
|
||||||
<addaction name="action_purge"/>
|
<addaction name="action_purge"/>
|
||||||
|
<addaction name="action_shift"/>
|
||||||
</widget>
|
</widget>
|
||||||
<action name="action_import">
|
<action name="action_import">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
|
|
@ -226,6 +227,14 @@
|
||||||
<string>Purge cross-sections to keep a given number of points</string>
|
<string>Purge cross-sections to keep a given number of points</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="action_shift">
|
||||||
|
<property name="text">
|
||||||
|
<string>Shift</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Shift selected sections coordinates</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Dialog</class>
|
||||||
|
<widget class="QDialog" name="Dialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>381</width>
|
||||||
|
<height>144</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Y coordinate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_1">
|
||||||
|
<property name="text">
|
||||||
|
<string>X coordinate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_Y">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>-99999999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>99999999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_X">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>-99999999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>99999999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Z coordinate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_Z">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>-99999999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>99999999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
|
|
@ -27,14 +27,14 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButton_generate_1">
|
<widget class="QPushButton" name="pushButton_generate_1">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Generate from height</string>
|
<string>Generate height</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButton_generate_2">
|
<widget class="QPushButton" name="pushButton_generate_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Generate from discharge</string>
|
<string>Generate discharge</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
||||||
|
|
@ -39,19 +39,6 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTableView" name="tableView_profile"/>
|
<widget class="QTableView" name="tableView_profile"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QSlider" name="verticalSlider_profile">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="invertedAppearance">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="invertedControls">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
@ -145,7 +132,10 @@
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="tabsClosable">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab_4">
|
<widget class="QWidget" name="tab_4">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
|
|
||||||
|
|
@ -2168,13 +2168,13 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../View/ui/InitialConditions.ui" line="30"/>
|
<location filename="../View/ui/InitialConditions.ui" line="30"/>
|
||||||
<source>Generate from height</source>
|
<source>Generate height</source>
|
||||||
<translation>Générer pour une hauteur donnée</translation>
|
<translation>Générer une hauteur</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../View/ui/InitialConditions.ui" line="37"/>
|
<location filename="../View/ui/InitialConditions.ui" line="37"/>
|
||||||
<source>Generate from discharge</source>
|
<source>Generate discharge</source>
|
||||||
<translation>Générer pour un débit donné</translation>
|
<translation>Générer un débit</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../View/ui/InitialConditions.ui" line="98"/>
|
<location filename="../View/ui/InitialConditions.ui" line="98"/>
|
||||||
|
|
@ -3057,7 +3057,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../View/Translate.py" line="57"/>
|
<location filename="../View/Translate.py" line="57"/>
|
||||||
<source>Height (m)</source>
|
<source>Depth (m)</source>
|
||||||
<translation>Hauteur (m)</translation>
|
<translation>Hauteur (m)</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue