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)))