debug + interactive selection in lateral contrib

0.0.9
Theophile Terraz 2024-06-11 16:19:52 +02:00
parent ea146cbe87
commit 59fc80a10b
6 changed files with 325 additions and 7 deletions

View File

@ -0,0 +1,50 @@
# PlotKPC.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 PyQt5.QtCore import QCoreApplication
from View.HydraulicStructures.PlotKPC import PlotKPC
_translate = QCoreApplication.translate
class PlotKPZ(PlotKPC):
def __init__(self, canvas=None, trad=None, toolbar=None,
river=None, reach=None, profile=None,
parent=None):
super(PlotKPC, self).__init__(
canvas=canvas,
trad=trad,
data=river,
toolbar=toolbar,
parent=parent
)
self._current_reach = reach
self._current_profile = profile
self.label_x = self._trad["unit_kp"]
self.label_y = self._trad["unit_elevation"]
self._isometric_axis = False
self._auto_relim_update = True
self._autoscale_update = True
self.parent = parent
def onpick(self, event):
return

View File

@ -50,7 +50,7 @@ from View.Frictions.Table import (
) )
from View.Tools.Plot.PamhyrCanvas import MplCanvas from View.Tools.Plot.PamhyrCanvas import MplCanvas
from View.Geometry.PlotKPZ import PlotKPZ from View.Frictions.PlotKPZ import PlotKPZ
from View.Frictions.PlotStricklers import PlotStricklers from View.Frictions.PlotStricklers import PlotStricklers
from View.Frictions.translate import FrictionsTranslate from View.Frictions.translate import FrictionsTranslate
@ -135,10 +135,11 @@ class FrictionsWindow(PamhyrWindow):
self.plot = PlotKPZ( self.plot = PlotKPZ(
canvas=self.canvas, canvas=self.canvas,
data=self._reach.reach, reach=self._reach,
study=self._study, river=self._study.river,
trad=self._trad, trad=self._trad,
toolbar=None, toolbar=None,
parent=self
) )
self.plot.draw() self.plot.draw()

View File

@ -179,7 +179,6 @@ class PlotXY(PamhyrPlot):
self._init = True self._init = True
def draw_xy(self): def draw_xy(self):
self.line_xy = [] self.line_xy = []
for xy in zip(self.data.get_x(), self.data.get_y()): for xy in zip(self.data.get_x(), self.data.get_y()):
self.line_xy.append(np.column_stack(xy)) self.line_xy.append(np.column_stack(xy))

View File

@ -186,11 +186,9 @@ class PlotKPC(PamhyrPlot):
closest = self._closest_profile(event) closest = self._closest_profile(event)
index = self.parent.tableView.selectedIndexes() index = self.parent.tableView.selectedIndexes()
print(index)
if self.parent._table is not None: if self.parent._table is not None:
self.parent._table.setData(index[2], closest) self.parent._table.setData(index[2], closest)
return return
def _closest_profile(self, event): def _closest_profile(self, event):

View File

@ -0,0 +1,259 @@
# PlotXY.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 tools import timer, trace
from View.Tools.PamhyrPlot import PamhyrPlot
from matplotlib import collections
import numpy as np
from PyQt5.QtCore import (
QCoreApplication, Qt, QItemSelectionModel,
QItemSelection, QItemSelectionRange,
)
from PyQt5.QtWidgets import QApplication, QTableView
_translate = QCoreApplication.translate
class PlotXY(PamhyrPlot):
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
table=None, parent=None):
super(PlotXY, self).__init__(
canvas=canvas,
trad=trad,
data=data,
toolbar=toolbar,
table=table,
parent=parent
)
self.line_xy = []
self.line_gl = []
self.label_x = self._trad["x"]
self.label_y = self._trad["y"]
self.before_plot_selected = None
self.plot_selected = None
self.after_plot_selected = None
self.parent=parent
self.line_xy_collection = None
self._table=table
self._colors = []
self._style = []
def onpick(self, event):
if event.mouseevent.inaxes != self.canvas.axes:
return
if event.mouseevent.button.value not in [1,3]:
return
closest = self._closest_section(event)
t = self.parent.current_tab()
tableView = self.parent.find(QTableView, f"tableView_{t}")
table = self.parent._table[t]
index = tableView.selectedIndexes()
kp = self.data.get_kp()
if self.parent._table is not None:
if event.mouseevent.button.value == 1:
table.setData(index[3], kp[closest[0]])
if event.mouseevent.button.value == 3:
table.setData(index[4], kp[closest[0]])
#self.update()
return
def _closest_section(self, event):
axes = self.canvas.axes
mx = event.mouseevent.xdata
my = event.mouseevent.ydata
bx, by = axes.get_xlim(), axes.get_ylim()
ratio = (bx[0] - bx[1]) / (by[0] - by[1])
segments = event.artist.get_segments()
ind = event.ind
points = []
for i in ind:
points = points + [[i, j] for j in segments[i]]
def dist_mouse(point):
x, y = point[1]
d2 = (((mx - x) / ratio) ** 2) + ((my - y) ** 2)
return d2
closest = min(
points, key=dist_mouse
)
return closest
@timer
def draw(self):
self.init_axes()
if self.data is None:
self.idle()
return
if self.data.number_profiles == 0:
self._init = False
self.idle()
return
self.draw_xy()
self.draw_lr()
self.draw_gl()
self.idle()
self._init = True
def draw_xy(self):
self.line_xy = []
for xy in zip(self.data.get_x(), self.data.get_y()):
self.line_xy.append(np.column_stack(xy))
self._colors, self._style = self.color_hightlight()
self.line_xy_collection = collections.LineCollection(self.line_xy,
colors = self._colors,
linestyle = self._style,
picker=10)
self.canvas.axes.add_collection(self.line_xy_collection)
def color_hightlight(self):
kp_min, kp_max = (-1, -1)
if self._highlight_data is not None:
kp_min, kp_max = self._highlight_data
colors = [self.color_plot for row in range(len(self._data))]
for i, kp in enumerate(self.data.get_kp_complete_profiles()):
if kp_min <= kp <= kp_max:
colors[i] = self.color_plot_current
style = ["-" for row in range(len(self._data))]
return colors, style
def draw_lr(self):
lx = []
ly = []
rx = []
ry = []
self.line_lr = []
for x, y in zip(self.data.get_x(),
self.data.get_y()):
lx.append(x[0])
ly.append(y[0])
rx.append(x[-1])
ry.append(y[-1])
line = self.canvas.axes.plot(
lx, ly,
color=self.color_plot_river_bottom,
linestyle="dotted",
lw=1.,
)
self.line_lr.append(line)
line = self.canvas.axes.plot(
rx, ry,
color=self.color_plot_river_bottom,
linestyle="dotted",
lw=1.,
)
self.line_lr.append(line)
def draw_gl(self):
x_complete = self.data.get_guidelines_x()
y_complete = self.data.get_guidelines_y()
ind = 0
self.line_gl = []
for x, y in zip(x_complete, y_complete):
line = self.canvas.axes.plot(
x, y, color=self.colors[ind % len(self.colors)],
linestyle=self.linestyle[ind // len(self.colors)]
)
self.line_gl.append(line)
ind += 1
@timer
def update(self):
if not self._init:
self.draw()
return
if self.data is None:
return
self.update_lr()
self.update_gl()
self.update_current()
self.update_idle()
def update_gl(self):
self.data.compute_guidelines()
x_complete = list(self.data.get_guidelines_x())
y_complete = list(self.data.get_guidelines_y())
# TODO comprendre à quoi sert ce bout de code
# ========>
#for i in range(self.data.number_profiles):
#if i < len(self.line_xy):
#self.line_xy[i][0].set_data(
#self.data.profile(i).x(),
#self.data.profile(i).y()
#)
#else:
#self.line_xy.append(
#self.canvas.axes.plot(
#self.data.profile(i).x(),
#self.data.profile(i).y(),
#color='r',
#**self.plot_default_kargs
#)
#)
# <========
for i in range(len(x_complete)):
if i < len(self.line_gl):
self.line_gl[i][0].set_data(
x_complete[i],
y_complete[i]
)
else:
self.line_gl.append(
self.canvas.axes.plot(
x_complete[i],
y_complete[i]
)
)
def update_current(self):
if self._current_data_update:
self._colors, self._style = self.color_hightlight()
self.line_xy_collection.set_colors(self._colors)
self.line_xy_collection.set_linestyle(self._style)
def update_lr(self):
for line in self.line_lr:
line[0].remove()
self.draw_lr()

View File

@ -54,7 +54,7 @@ from View.LateralContribution.Table import (
) )
from View.Tools.Plot.PamhyrCanvas import MplCanvas from View.Tools.Plot.PamhyrCanvas import MplCanvas
from View.Geometry.PlotXY import PlotXY from View.LateralContribution.PlotXY import PlotXY
from View.LateralContribution.translate import ( from View.LateralContribution.translate import (
LC_types, LCTranslate, LC_types, LCTranslate,
) )
@ -83,6 +83,7 @@ class LateralContributionWindow(PamhyrWindow):
self.setup_table() self.setup_table()
self.setup_graph() self.setup_graph()
self.tabs = self.find(QTabWidget, "tabWidget")
self.setup_connections() self.setup_connections()
def setup_table(self): def setup_table(self):
@ -148,6 +149,7 @@ class LateralContributionWindow(PamhyrWindow):
data=None, data=None,
trad=self._trad, trad=self._trad,
toolbar=None, toolbar=None,
parent=self
) )
def setup_connections(self): def setup_connections(self):
@ -156,6 +158,8 @@ class LateralContributionWindow(PamhyrWindow):
self.find(QAction, "action_edit").triggered.connect(self.edit) self.find(QAction, "action_edit").triggered.connect(self.edit)
self.find(QAction, "action_sort").triggered.connect(self.sort) self.find(QAction, "action_sort").triggered.connect(self.sort)
self.tabs.currentChanged.connect(self._set_current_reach)
for t in ["liquid", "solid", "suspenssion"]: for t in ["liquid", "solid", "suspenssion"]:
table = self.find(QTableView, f"tableView_{t}") table = self.find(QTableView, f"tableView_{t}")
table.selectionModel()\ table.selectionModel()\
@ -216,6 +220,7 @@ class LateralContributionWindow(PamhyrWindow):
data=data, data=data,
trad=self._trad, trad=self._trad,
toolbar=None, toolbar=None,
parent=self
) )
self.plot.highlight = highlight self.plot.highlight = highlight
self.plot.update() self.plot.update()
@ -292,3 +297,9 @@ class LateralContributionWindow(PamhyrWindow):
parent=self parent=self
) )
win.show() win.show()
#@pyqtSlot()
def onChange(self,i): #changed!
QtGui.QMessageBox.information(self,
"Tab Index Changed!",
"Current Tab Index: %d" % i ) #changed!