diff --git a/doc/dev/documentation.org b/doc/dev/documentation.org
index 94768e8a..28fad839 100644
--- a/doc/dev/documentation.org
+++ b/doc/dev/documentation.org
@@ -456,6 +456,15 @@ of Bar (Listing [[sql-bar]] and [[sql-foo]]).
bar._sql_save(execute, data=data)
#+end_src
+Let see the results database scheme for Pamhyr2 at version v0.0.7 in
+Figure [[sql_schema]].
+
+#+NAME: sql_schema
+#+ATTR_LATEX: :width 16cm
+#+CAPTION: SQLite database scheme at Pamhyr2 version v0.0.7 (generate with [[https://gitlab.com/Screwtapello/sqlite-schema-diagram]])
+[[./images/schema_v0.0.7.png]]
+
+
[fn:sqlite] The SQLite web site: https://www.sqlite.org/index.html
(last access 2023-09-20)
diff --git a/doc/dev/images/schema_v0.0.7.png b/doc/dev/images/schema_v0.0.7.png
new file mode 100644
index 00000000..a09da69f
Binary files /dev/null and b/doc/dev/images/schema_v0.0.7.png differ
diff --git a/src/Meshing/Mage.py b/src/Meshing/Mage.py
index 393de9c4..9ce8f357 100644
--- a/src/Meshing/Mage.py
+++ b/src/Meshing/Mage.py
@@ -306,8 +306,6 @@ class MeshingWithMageMailleurTT(AMeshingTool):
st_file = self.export_reach_to_st(reach, tmp)
m_file = st_file.rsplit(".ST", 1)[0] + ".M"
- os.sync()
-
proc = QProcess()
proc.setWorkingDirectory(tmp)
diff --git a/src/Model/Geometry/PointXYZ.py b/src/Model/Geometry/PointXYZ.py
index cf678c24..9ba79e66 100644
--- a/src/Model/Geometry/PointXYZ.py
+++ b/src/Model/Geometry/PointXYZ.py
@@ -47,7 +47,7 @@ class PointXYZ(Point, SQLSubModel):
z INTEGER NOT NULL,
profile INTEGER NOT NULL,
sl INTEGER,
- FOREIGN KEY(profile) REFERENCES profileXYZ(id),
+ FOREIGN KEY(profile) REFERENCES geometry_profileXYZ(id),
FOREIGN KEY(sl) REFERENCES sedimentary_layer(id)
)
""")
@@ -220,3 +220,11 @@ class PointXYZ(Point, SQLSubModel):
Euclidean 3D distance between the two points
"""
return dist((p1.x, p1.y, p1.z), (p2.x, p2.y, p2.z))
+
+ @staticmethod
+ def areatriangle3d(p1, p2, p3):
+ a = PointXYZ.distance(p1, p2)
+ b = PointXYZ.distance(p2, p3)
+ c = PointXYZ.distance(p3, p1)
+ s = (a + b + c) / 2
+ return (s*(s-a) * (s-b)*(s-c)) ** 0.5
diff --git a/src/Model/Geometry/Profile.py b/src/Model/Geometry/Profile.py
index 33741eaa..17bf5c60 100644
--- a/src/Model/Geometry/Profile.py
+++ b/src/Model/Geometry/Profile.py
@@ -296,6 +296,11 @@ class Profile(object):
)
self._status.modified()
+ @timer
+ def reverse(self):
+ self._points.reverse()
+ self._status.modified()
+
# Sediment Layers
def get_sl(self):
diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py
index 6b344994..0bd8d83d 100644
--- a/src/Model/Geometry/ProfileXYZ.py
+++ b/src/Model/Geometry/ProfileXYZ.py
@@ -578,3 +578,32 @@ class ProfileXYZ(Profile, SQLSubModel):
break
return last_point
+
+ def purge(self, np_purge):
+ """
+ Remove points to keep at most np_purge points.
+ """
+
+ if (self.nb_points <= np_purge): return
+
+ nb_named = 2 # we consider the first and last point as named
+ area = [0.0]
+ for i in range(1, self.nb_points-1):
+ if self.point(i).point_is_named():
+ area.append(9999999.999)
+ nb_named += 1
+ else:
+ area.append(PointXYZ.areatriangle3d(self.point(i-1),self.point(i),self.point(i+1)))
+ area.append(0.0)
+
+ while (self.nb_points > max(np_purge, nb_named)):
+ to_rm = np.argmin(area[1:self.nb_points-1])+1
+ self.delete_i([to_rm])
+ area.pop(to_rm)
+ for i in [to_rm-1, to_rm]:
+ if (i == 0): continue
+ if (i == self.nb_points - 1): continue
+ if self.point(i).point_is_named():
+ area[i] = 9999999.999
+ else:
+ area[i] = PointXYZ.areatriangle3d(self.point(i-1),self.point(i),self.point(i+1))
diff --git a/src/Solver/CommandLine.py b/src/Solver/CommandLine.py
index 4afcbc9a..5f706d1a 100644
--- a/src/Solver/CommandLine.py
+++ b/src/Solver/CommandLine.py
@@ -167,8 +167,10 @@ class CommandLineSolver(AbstractSolver):
repertory, "pamhyr-study-description.txt"
)
- with open(path, "w+") as f:
- txt = study.description
+ with open(path, "w+", encoding='utf-8') as f:
+ txt = study.description\
+ .encode()\
+ .decode('utf-8', 'replace')
f.write(txt)
#######
diff --git a/src/Solver/Mage.py b/src/Solver/Mage.py
index f8b664fd..ea1c7635 100644
--- a/src/Solver/Mage.py
+++ b/src/Solver/Mage.py
@@ -282,6 +282,9 @@ class Mage(CommandLineSolver):
if bound.node is None:
continue
+ if not study.river.is_enable_node(bound.node):
+ continue
+
if bound.bctype == "ZD":
AVA.append(bound)
elif bound.bctype == "TD" or bound.bctype == "PC":
@@ -357,13 +360,7 @@ class Mage(CommandLineSolver):
with mage_file_open(os.path.join(repertory, f"{name}.RUG"), "w+") as f:
files.append(f"{name}.RUG")
- edges = study.river.edges()
- edges = list(
- filter(
- lambda e: e.is_enable(),
- edges
- )
- )
+ edges = study.river.enable_edges()
id = 1
for edge in edges:
@@ -495,6 +492,9 @@ class Mage(CommandLineSolver):
if not hs.input_reach.is_enable():
continue
+ if not hs.enabled:
+ continue
+
if hs.input_kp is None:
continue
@@ -510,25 +510,26 @@ class Mage(CommandLineSolver):
def _export_SIN_bhs(self, study, sin_dict, hs, f):
for bhs in hs.basic_structures:
- reach_id = study.river.get_edge_id(hs.input_reach) + 1
- param_str = ' '.join(
- [
- f'{p:>10.3f}'
- for p in self._export_SIN_parameters(bhs)
- ]
- )
+ if bhs.enabled:
+ reach_id = study.river.get_edge_id(hs.input_reach) + 1
+ param_str = ' '.join(
+ [
+ f'{p:>10.3f}'
+ for p in self._export_SIN_parameters(bhs)
+ ]
+ )
- name = bhs.name
- if name == "":
- name = f"HS_{bhs.id:>3}".replace(" ", "0")
- else:
- name = name.replace(" ", "_")
+ name = bhs.name
+ if name == "":
+ name = f"HS_{bhs.id:>3}".replace(" ", "0")
+ else:
+ name = name.replace(" ", "_")
- f.write(
- f"{sin_dict[bhs._type]} " +
- f"{reach_id} {float(hs.input_kp):>12.3f} " +
- f"{param_str} {name}\n"
- )
+ f.write(
+ f"{sin_dict[bhs._type]} " +
+ f"{reach_id} {float(hs.input_kp):>12.3f} " +
+ f"{param_str} {name}\n"
+ )
def _export_SIN_parameters(self, bhs):
res = [9999.999] * 5
@@ -802,7 +803,7 @@ class Mage8(Mage):
value = "O" if value.lower() == "y" else "N"
if name == "init_internal":
- value = ("p" if value.lower() in ["y", "yes", "true"]
+ value = ("p" if value.lower() in ["y", "yes", "true", "o"]
else "")
logger.debug(
diff --git a/src/View/Geometry/PlotAC.py b/src/View/Geometry/PlotAC.py
index 24567bef..cccffe24 100644
--- a/src/View/Geometry/PlotAC.py
+++ b/src/View/Geometry/PlotAC.py
@@ -129,7 +129,7 @@ class PlotAC(PamhyrPlot):
if txt.strip() in self.complete_gl:
color = self.color_complete_gl[
- lcomplete.index(txt)
+ lcomplete.index(txt) % len(self.color_complete_gl)
]
else:
color = self.color_incomplete_gl[
diff --git a/src/View/Geometry/PlotKPZ.py b/src/View/Geometry/PlotKPZ.py
index 35e9ffab..f4dbd790 100644
--- a/src/View/Geometry/PlotKPZ.py
+++ b/src/View/Geometry/PlotKPZ.py
@@ -167,7 +167,9 @@ class PlotKPZ(PamhyrPlot):
self.line_kp_zgl.append(
self.canvas.axes.plot(
- kp, z, lw=1., color=self.colors[ind]
+ kp, z, lw=1.,
+ color=self.colors[ind % len(self.colors)],
+ linestyle=self.linestyle[ind // len(self.colors)]
)
)
ind += 1
diff --git a/src/View/Geometry/PlotXY.py b/src/View/Geometry/PlotXY.py
index 6c3a3707..baa46d26 100644
--- a/src/View/Geometry/PlotXY.py
+++ b/src/View/Geometry/PlotXY.py
@@ -130,7 +130,8 @@ class PlotXY(PamhyrPlot):
self.line_gl = []
for x, y in zip(x_complete, y_complete):
line = self.canvas.axes.plot(
- x, y, color=self.colors[ind]
+ x, y, color=self.colors[ind % len(self.colors)],
+ linestyle=self.linestyle[ind // len(self.colors)]
)
self.line_gl.append(line)
ind += 1
diff --git a/src/View/Geometry/Profile/Table.py b/src/View/Geometry/Profile/Table.py
index c23eeb6f..21e202f8 100644
--- a/src/View/Geometry/Profile/Table.py
+++ b/src/View/Geometry/Profile/Table.py
@@ -250,6 +250,26 @@ class GeometryProfileTableModel(PamhyrTableModel):
self.endMoveRows()
self.layoutChanged.emit()
+ def purge(self):
+
+ self._undo.push(
+ PurgeCommand(
+ self._data, 24
+ )
+ )
+
+ self.layoutChanged.emit()
+
+ def reverse(self):
+
+ self._undo.push(
+ ReverseCommand(
+ self._data
+ )
+ )
+
+ self.layoutChanged.emit()
+
def paste(self, row, header, data):
if row > self._data.number_points:
return
diff --git a/src/View/Geometry/Profile/UndoCommand.py b/src/View/Geometry/Profile/UndoCommand.py
index 800bd4e0..a381feee 100644
--- a/src/View/Geometry/Profile/UndoCommand.py
+++ b/src/View/Geometry/Profile/UndoCommand.py
@@ -169,6 +169,34 @@ class MoveCommand(QUndoCommand):
self._profile.move_down_point(self._i)
+class ReverseCommand(QUndoCommand):
+ def __init__(self, profile):
+ QUndoCommand.__init__(self)
+
+ self._profile = profile
+
+ def undo(self):
+ self._profile.reverse()
+
+ def redo(self):
+ self._profile.reverse()
+
+
+class PurgeCommand(QUndoCommand):
+ def __init__(self, profile, np_purge):
+ QUndoCommand.__init__(self)
+
+ self._profile = profile
+ self._old = self._profile.points.copy()
+ self._np_purge = np_purge
+
+ def undo(self):
+ self._profile._points = self._old.copy()
+
+ def redo(self):
+ self._profile.purge(self._np_purge)
+
+
class PasteCommand(QUndoCommand):
def __init__(self, profile, row, points):
QUndoCommand.__init__(self)
diff --git a/src/View/Geometry/Profile/Window.py b/src/View/Geometry/Profile/Window.py
index d8f2da07..504eb25f 100644
--- a/src/View/Geometry/Profile/Window.py
+++ b/src/View/Geometry/Profile/Window.py
@@ -125,6 +125,8 @@ class ProfileWindow(PamhyrWindow):
"action_down": self.move_down,
"action_add": self.add,
"action_delete": self.delete,
+ "action_purge": self.purge,
+ "action_reverse": self.reverse,
}
for action in actions:
@@ -146,6 +148,12 @@ class ProfileWindow(PamhyrWindow):
self.update_plot()
self._propagate_update(key=Modules.GEOMETRY)
+ def _update(self, redraw=False, propagate=True):
+ if redraw:
+ self.update_plot()
+ if propagate:
+ self._propagate_update(key=Modules.GEOMETRY)
+
def update_plot(self):
self._tablemodel.blockSignals(True)
@@ -153,6 +161,14 @@ class ProfileWindow(PamhyrWindow):
self._tablemodel.blockSignals(False)
+ def _propagated_update(self, key=Modules(0)):
+ if Modules.GEOMETRY not in key:
+ return
+
+ print("=====TOTO=====")
+ self._tablemodel.layoutChanged.emit()
+ self._update(redraw=True, propagate=False)
+
def index_selected_row(self):
table = self.find(QTableView, "tableView")
rows = table.selectionModel()\
@@ -238,6 +254,14 @@ class ProfileWindow(PamhyrWindow):
self.update()
+ def purge(self):
+ self._tablemodel.purge()
+ self.update()
+
+ def reverse(self):
+ self._tablemodel.reverse()
+ self.update()
+
def _copy(self):
table = self.find(QTableView, "tableView")
rows = table.selectionModel().selectedRows()
diff --git a/src/View/Geometry/Table.py b/src/View/Geometry/Table.py
index 169771cb..26baa7fb 100644
--- a/src/View/Geometry/Table.py
+++ b/src/View/Geometry/Table.py
@@ -246,3 +246,12 @@ class GeometryReachTableModel(PamhyrTableModel):
self.layoutAboutToBeChanged.emit()
self.layoutChanged.emit()
+
+ def purge(self):
+
+ self._undo.push(
+ PurgeCommand(
+ self._data, 24
+ )
+ )
+ self.layoutChanged.emit()
diff --git a/src/View/Geometry/UndoCommand.py b/src/View/Geometry/UndoCommand.py
index f1d181f5..e5d48885 100644
--- a/src/View/Geometry/UndoCommand.py
+++ b/src/View/Geometry/UndoCommand.py
@@ -254,3 +254,23 @@ class MeshingCommand(QUndoCommand):
for profile in self._new_profiles:
self._reach.insert_profile(0, profile)
+
+
+class PurgeCommand(QUndoCommand):
+ def __init__(self, reach, np_purge):
+ QUndoCommand.__init__(self)
+
+ self._reach = reach
+ self._np_purge = np_purge
+
+ self._old = []
+ for profile in self._reach.profiles:
+ self._old.append(profile.points.copy())
+
+ def undo(self):
+ for i in range(self._reach.number_profiles):
+ self._reach.profiles[i]._points = self._old[i].copy()
+
+ def redo(self):
+ for profile in self._reach._profiles:
+ profile.purge(self._np_purge)
diff --git a/src/View/Geometry/Window.py b/src/View/Geometry/Window.py
index d63bf929..302237a3 100644
--- a/src/View/Geometry/Window.py
+++ b/src/View/Geometry/Window.py
@@ -188,6 +188,8 @@ class GeometryWindow(PamhyrWindow):
"action_delete": self.delete,
"action_edit": self.edit_profile,
"action_meshing": self.edit_meshing,
+ "action_update_kp": self.update_kp,
+ "action_purge": self.purge,
}
for action in actions:
@@ -227,7 +229,7 @@ class GeometryWindow(PamhyrWindow):
self._propagate_update(key=Modules.GEOMETRY)
def _propagated_update(self, key=Modules(0)):
- if Modules.NETWORK not in key:
+ if Modules.NETWORK not in key and Modules.GEOMETRY not in key:
return
self._update(propagate=False)
@@ -507,6 +509,13 @@ class GeometryWindow(PamhyrWindow):
self._table.move_down(row)
self.select_current_profile()
+ def update_kp(self):
+ pass
+
+ def purge(self):
+ self._table.purge()
+ self.update_redraw()
+
def duplicate(self):
rows = [
row.row() for row in
diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py b/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py
index 93ef8a37..9a39f49c 100644
--- a/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py
+++ b/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py
@@ -252,13 +252,14 @@ class BasicHydraulicStructuresWindow(PamhyrWindow):
self._checkbox.setChecked(self._hs.basic_structure(row).enabled)
def _set_basic_structure_state(self):
- row = self.index_selected_row()
-
- if row is not None:
- self._table.enabled(
- row,
- self._checkbox.isChecked()
- )
+ rows = self.index_selected_rows()
+ if len(rows) != 0:
+ for row in rows:
+ if row is not None:
+ self._table.enabled(
+ row,
+ self._checkbox.isChecked()
+ )
def update(self):
self._set_checkbox_state()
diff --git a/src/View/HydraulicStructures/Window.py b/src/View/HydraulicStructures/Window.py
index ff290d7a..1c6af72c 100644
--- a/src/View/HydraulicStructures/Window.py
+++ b/src/View/HydraulicStructures/Window.py
@@ -262,12 +262,14 @@ class HydraulicStructuresWindow(PamhyrWindow):
self._checkbox.setChecked(self._hs_lst.get(row).enabled)
def _set_structure_state(self):
- row = self.index_selected_row()
- if row is not None:
- self._table.enabled(
- row,
- self._checkbox.isChecked()
- )
+ rows = self.index_selected_rows()
+ if len(rows) != 0:
+ for row in rows:
+ if row is not None:
+ self._table.enabled(
+ row,
+ self._checkbox.isChecked()
+ )
def update(self):
self._set_checkbox_state()
diff --git a/src/View/MainWindow.py b/src/View/MainWindow.py
index f4d8bad7..ca6371a5 100644
--- a/src/View/MainWindow.py
+++ b/src/View/MainWindow.py
@@ -445,9 +445,15 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
logger.debug(f"Propagation of {keys}")
for _, window in self.sub_win_list:
window._propagated_update(key=keys)
+ self._do_propagate_update_rec(window, keys)
self._tab_widget_checker.update(modules=keys)
+ def _do_propagate_update_rec(self, window, keys):
+ for _, win in window.sub_win_list:
+ win._propagated_update(key=keys)
+ self._do_propagate_update_rec(win, keys)
+
def update(self):
self.set_title()
diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py
index e490339d..91770042 100644
--- a/src/View/Results/CustomPlot/Plot.py
+++ b/src/View/Results/CustomPlot/Plot.py
@@ -77,9 +77,9 @@ class CustomPlot(PamhyrPlot):
kp = reach.geometry.get_kp()
z_min = reach.geometry.get_z_min()
- self.canvas.axes.set_xlim(
- left=min(kp), right=max(kp)
- )
+ # self.canvas.axes.set_xlim(
+ # left=min(kp), right=max(kp)
+ # )
meter_axes = self.canvas.axes
m3S_axes = self.canvas.axes
@@ -88,10 +88,10 @@ class CustomPlot(PamhyrPlot):
lines = {}
if "elevation" in self._y:
- meter_axes.set_ylim(
- bottom=min(0, min(z_min)),
- top=max(z_min) + 1
- )
+ # meter_axes.set_ylim(
+ # bottom=min(0, min(z_min)),
+ # top=max(z_min) + 1
+ # )
line = meter_axes.plot(
kp, z_min,
@@ -108,10 +108,10 @@ class CustomPlot(PamhyrPlot):
)
)
- meter_axes.set_ylim(
- bottom=min(0, min(z_min)),
- top=max(water_z) + 1
- )
+ # meter_axes.set_ylim(
+ # bottom=min(0, min(z_min)),
+ # top=max(water_z) + 1
+ # )
line = meter_axes.plot(
kp, water_z, lw=1.,
@@ -133,10 +133,10 @@ class CustomPlot(PamhyrPlot):
)
)
- m3s_axes.set_ylim(
- bottom=min(0, min(q)),
- top=max(q) + 1
- )
+ # m3s_axes.set_ylim(
+ # bottom=min(0, min(q)),
+ # top=max(q) + 1
+ # )
line = m3s_axes.plot(
kp, q, lw=1.,
@@ -206,9 +206,9 @@ class CustomPlot(PamhyrPlot):
ts = list(results.get("timestamps"))
ts.sort()
- self.canvas.axes.set_xlim(
- left=min(ts), right=max(ts)
- )
+ # self.canvas.axes.set_xlim(
+ # left=min(ts), right=max(ts)
+ # )
x = ts
lines = {}
@@ -232,10 +232,10 @@ class CustomPlot(PamhyrPlot):
# Water elevation
z = profile.get_key("Z")
- meter_axes.set_ylim(
- bottom=min(0, min(z)),
- top=max(z) + 1
- )
+ # meter_axes.set_ylim(
+ # bottom=min(0, min(z)),
+ # top=max(z) + 1
+ # )
line = meter_axes.plot(
ts, z, lw=1.,
@@ -260,10 +260,10 @@ class CustomPlot(PamhyrPlot):
if "discharge" in self._y:
q = profile.get_key("Q")
- m3s_axes.set_ylim(
- bottom=min(0, min(q)),
- top=max(q) + 1
- )
+ # m3s_axes.set_ylim(
+ # bottom=min(0, min(q)),
+ # top=max(q) + 1
+ # )
line = m3s_axes.plot(
ts, q, lw=1.,
diff --git a/src/View/Results/PlotKPC.py b/src/View/Results/PlotKPC.py
index 1cab022e..71fa3aab 100644
--- a/src/View/Results/PlotKPC.py
+++ b/src/View/Results/PlotKPC.py
@@ -119,11 +119,14 @@ class PlotKPC(PamhyrPlot):
self.line_kp_sl.append(None)
self.line_kp_sl[i], = self.canvas.axes.plot(
kp, z,
- linestyle="solid" if i == len(final_z_sl) - 1 else "--",
+ linestyle=(
+ "solid" if i == len(final_z_sl) - 1
+ else self.linestyle[1:][i // len(self.colors)]
+ ),
lw=1.,
color=(
self.color_plot_river_bottom if i == len(final_z_sl) - 1
- else self.colors[i]
+ else self.colors[i % len(self.colors)]
)
)
diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py
index 45aaa009..155b971e 100644
--- a/src/View/Results/Window.py
+++ b/src/View/Results/Window.py
@@ -160,7 +160,10 @@ class ResultsWindow(PamhyrWindow):
self.canvas = MplCanvas(width=5, height=4, dpi=100)
self.canvas.setObjectName("canvas")
self.toolbar = PamhyrPlotToolbar(
- self.canvas, self
+ self.canvas, self, items=[
+ "home", "move", "zoom", "save",
+ "iso", "back/forward"
+ ]
)
self.plot_layout = self.find(QVBoxLayout, "verticalLayout")
self.plot_layout.addWidget(self.toolbar)
@@ -180,7 +183,10 @@ class ResultsWindow(PamhyrWindow):
self.canvas_2 = MplCanvas(width=5, height=4, dpi=100)
self.canvas_2.setObjectName("canvas_2")
self.toolbar_2 = PamhyrPlotToolbar(
- self.canvas_2, self
+ self.canvas_2, self, items=[
+ "home", "move", "zoom", "save",
+ "iso", "back/forward"
+ ]
)
self.plot_layout_2 = self.find(QVBoxLayout, "verticalLayout_2")
self.plot_layout_2.addWidget(self.toolbar_2)
@@ -199,7 +205,10 @@ class ResultsWindow(PamhyrWindow):
self.canvas_3 = MplCanvas(width=5, height=4, dpi=100)
self.canvas_3.setObjectName("canvas_3")
self.toolbar_3 = PamhyrPlotToolbar(
- self.canvas_3, self
+ self.canvas_3, self, items=[
+ "home", "move", "zoom", "save",
+ "iso", "back/forward"
+ ]
)
self.plot_layout_3 = self.find(QVBoxLayout, "verticalLayout_3")
self.plot_layout_3.addWidget(self.toolbar_3)
@@ -218,7 +227,10 @@ class ResultsWindow(PamhyrWindow):
self.canvas_4 = MplCanvas(width=5, height=4, dpi=100)
self.canvas_4.setObjectName("canvas_4")
self.toolbar_4 = PamhyrPlotToolbar(
- self.canvas_4, self
+ self.canvas_4, self, items=[
+ "home", "move", "zoom", "save",
+ "iso", "back/forward"
+ ]
)
self.plot_layout_4 = self.find(
QVBoxLayout, "verticalLayout_hydrograph")
diff --git a/src/View/Tools/PamhyrPlot.py b/src/View/Tools/PamhyrPlot.py
index 4b0c6f35..843be242 100644
--- a/src/View/Tools/PamhyrPlot.py
+++ b/src/View/Tools/PamhyrPlot.py
@@ -40,6 +40,7 @@ class PamhyrPlot(APlot):
color_plot_river_water_zone = "skyblue"
colors = list(mplcolors.TABLEAU_COLORS)
+ linestyle = ['solid', 'dashed', 'dashdot', 'dotted']
plot_default_kargs = {
"lw": 1.,
diff --git a/src/View/ui/GeometryCrossSection.ui b/src/View/ui/GeometryCrossSection.ui
index 6e6d62a5..f7c9158e 100644
--- a/src/View/ui/GeometryCrossSection.ui
+++ b/src/View/ui/GeometryCrossSection.ui
@@ -58,6 +58,8 @@
+
+
@@ -131,6 +133,22 @@
Sort reversed points by nearest neighbor
+
+
+ Purge
+
+
+ Purge the cross-section to keep a given number of points
+
+
+
+
+ Reverse
+
+
+ Reverse the points order
+
+
diff --git a/src/View/ui/GeometryReach.ui b/src/View/ui/GeometryReach.ui
index 95e25be1..22e54043 100644
--- a/src/View/ui/GeometryReach.ui
+++ b/src/View/ui/GeometryReach.ui
@@ -127,6 +127,8 @@
+
+
@@ -233,6 +235,22 @@
Meshing
+
+
+ Update KP
+
+
+ Recompute KP
+
+
+
+
+ Purge
+
+
+ Purge cross-sections to keep a given number of points
+
+
diff --git a/src/lang/fr.ts b/src/lang/fr.ts
index 839a5019..4b3a4a4d 100644
--- a/src/lang/fr.ts
+++ b/src/lang/fr.ts
@@ -31,7 +31,7 @@
Basic Hydraulic Structures
- Structure hydraulique élémentaire
+ Ouvrage hydraulique élémentaire
@@ -51,7 +51,7 @@
Upper elevation (m)
- Côte de mise en charge (m)
+ Cote de mise en charge (m)
@@ -61,7 +61,7 @@
Maximal loading elevation
- Côte de mise en charge maximale
+ Cote de mise en charge maximale
@@ -420,7 +420,7 @@
Bed load elevation (m)
- Côte du fond (m)
+ Cote du fond (m)
@@ -434,7 +434,7 @@
Dialog
-
+
Dialog
Dialog
@@ -449,7 +449,7 @@
Type
-
+
Description
Description
@@ -829,7 +829,7 @@
Form
-
+
Form
Formulaire
@@ -1055,17 +1055,17 @@
Geometry
-
+
X (m)
X (m)
-
+
Y (m)
Y (m)
-
+
Z (m)
Z (m)
@@ -1175,7 +1175,7 @@
Hydraulic Structures
- Structures hydraulique
+ Structures hydrauliques
@@ -1262,17 +1262,17 @@
Activer cette fenêtre
-
+
MainWindow
Fenêtre principale
-
+
toolBar
Barre d'outils
-
+
Add
Ajouter
@@ -1282,7 +1282,7 @@
Ajouter un casier
-
+
Delete
Supprimer
@@ -1292,7 +1292,7 @@
Supprimer casier(s)
-
+
Edit
Éditer
@@ -1327,7 +1327,7 @@
Éditer la couche sedimentaire
-
+
Ctrl+E
Ctrl+E
@@ -1397,7 +1397,7 @@
Nouvelle étude
-
+
Ctrl+N
Ctrl+N
@@ -1482,12 +1482,12 @@
Éditer la géométrie
-
+
Import geometry
Importer une géométrie
-
+
Export geometry
Exporter la géométrie
@@ -1682,7 +1682,7 @@
Éditer les casiers
-
+
Hydraulic structures
Structures hydraulique
@@ -1727,7 +1727,7 @@
Supprimer la(les) couche(s) sédimentaire(s) sélectionnée(s)
-
+
Ctrl+D
Ctrl+D
@@ -1762,7 +1762,7 @@
Ajouter une condition aux limites ou un apport ponctuel
-
+
Delete current selected rows
Supprimer les lignes selectionnées
@@ -1772,7 +1772,7 @@
Éditer une condition aux limites ou un apport ponctuel
-
+
Sort
Trier
@@ -1824,7 +1824,7 @@
Water elevation
- Côte de l'eau
+ Cote de l'eau
@@ -1842,7 +1842,7 @@
Recharger
-
+
Export
Exporter
@@ -1852,7 +1852,7 @@
Exporter les données brutes
-
+
delete
supprimer
@@ -1917,87 +1917,87 @@
Supprimer points
-
+
Edit selected hydraulic structure
Éditer l'ouvrage hydraulique sélectionné
-
+
Stop
Stoper
-
+
Start
Démarrer
-
+
Pause
Pause
-
+
LogFile
Fichier de log
-
+
results
resultats
-
+
add
Ajouter
-
+
Add a point on cross-section
Ajouter un point à la section en travers
-
+
Delete selected point(s)
Supprimer le(s) point(s) sélectionné(s)
-
+
up
Monter
-
+
Move up selected point(s)
Déplacer le point sélectionné vers le haut
-
+
down
Descendre
-
+
Mode down selected point(s)
Déplacer le point sélectionné vers le bas
-
+
sort_asc
sort_asc
-
+
Sort points by nearest neighbor
Trier les points par leurs plus proches voisins
-
+
sort_des
sort_des
-
+
Sort reversed points by nearest neighbor
Trie inverser les points par leurs plus proche voisins
@@ -2014,10 +2014,10 @@
Sort points by elevation
- Trier les points par leur côte
+ Trier les points par leur cote
-
+
Edit sediment layers list
Éditer la liste des couches sédimentaires
@@ -2112,52 +2112,52 @@
Éditer les couches sédimentaires
-
+
Import
Importer
-
+
Add a cross-section
Ajouter une section en travers
-
+
Delete selected cross-section(s)
Supprimer la(es) section(s) en travers sélectionnée(s)
-
+
edit
éditer
-
+
Edit selected cross section(s)
Éditer la(es) section(s) en travers sélectionnée(s)
-
+
Sort cross-sections by ascending KP
Trier les sections en travers par PK croissant
-
+
Sort cross-sections by descending KP
Trier les sections en travers par PK décroissant
-
+
Move up selected cross-section(s)
Déplacer la(s) section(s) en travers vers le haut
-
+
Move down selected cross-section(s)
Déplacer la(es) section(s) en travers vers le bas
-
+
Meshing
Maillage
@@ -2261,6 +2261,41 @@
Edit the study information
Éditer les information de l'étude
+
+
+ Update KP
+
+
+
+
+ Recompute KP
+
+
+
+
+ Purge
+
+
+
+
+ Purge cross-sections to keep a given number of points
+
+
+
+
+ Purge the cross-section to keep a given number of points
+
+
+
+
+ Reverse
+
+
+
+
+ Reverse the points order
+
+
MainWindowProfile
@@ -2472,12 +2507,12 @@
Water elevation
- Côte de l'eau
+ Cote de l'eau
Max water elevation
- Côte maximum de l'eau
+ Cote maximum de l'eau
@@ -2913,12 +2948,12 @@
Elevation (m)
- Côte (m)
+ Cote (m)
Water elevation (m)
- Côte de l'eau (m)
+ Cote de l'eau (m)
diff --git a/tools/license.el b/tools/license.el
index afb49975..1d08c959 100644
--- a/tools/license.el
+++ b/tools/license.el
@@ -109,3 +109,59 @@
(mapcar 'pamhyr--insert-license
(mapcar (lambda (file) (concat root "/" file))
files-without-copyright))))
+
+(defvar pamhyr-mail-template "Bonjour,
+
+La version @version de Pamhyr2 est disponible.
+
+
+
+---Change-logs-------------------@version---
+@description
+------------------------------------------
+
+---Liens-utiles---------------------------
+ Télécharger cette version :
+ https://gitlab.irstea.fr/theophile.terraz/pamhyr/-/releases/@version
+
+ La documentation (en anglais) :
+ https://gitlab.irstea.fr/theophile.terraz/pamhyr/-/wikis/home
+
+ Rapporter un problème :
+ https://gitlab.irstea.fr/theophile.terraz/pamhyr/-/issues
+ ou directement par mail à :
+
+------------------------------------------
+
+
+
+---/!\--Attention-------------------------
+ Pour les utilisateurs Windows : Certains antivirus peuvent détecter Pamhyr2 comme un virus, c'est un faux positif, le problème est connu et vient de l'exécutable généré par PyInstaller.
+ Nous n'avons pas encore de solution pour régler ce problème.
+ Si c'est votre cas, il faudra ajouter une exception dans votre antivirus si vous voulez utiliser Pamhyr2.
+ Sinon, il est aussi possible de passer par WSL et utiliser la version Linux sous Windows.
+
+ Rapport d'antivirus :
+------------------------------------------
+
+Bon weekend,
+")
+
+(require 'web)
+(require 'json)
+
+(defun pamhyr-release-mail (release)
+ (interactive "sRelease name: ")
+ (web-http-get
+ (lambda (httpc header my-data)
+ (let* ((data (json-read-from-string my-data))
+ (release (cdr (assoc 'tag_name data)))
+ (description (cdr (assoc 'description data))))
+ (let ((buffer (generate-new-buffer (format "* mail-%s *" release))))
+ (with-current-buffer buffer
+ (insert
+ (string-replace "@description" description
+ (string-replace "@version" release
+ pamhyr-mail-template)))
+ (set-buffer buffer)))))
+ :url (concat "https://gitlab.irstea.fr/api/v4/projects/2779/releases/" release)))