mirror of
https://gitlab.com/pamhyr/pamhyr2.git
synced 2026-10-30 03:20:41 +01:00
273 lines
7.5 KiB
Python
273 lines
7.5 KiB
Python
# PlotRKC.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
|
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
|
|
|
from PyQt5.QtCore import (
|
|
QCoreApplication, Qt,
|
|
)
|
|
from PyQt5.QtWidgets import QApplication
|
|
|
|
from matplotlib.collections import LineCollection
|
|
|
|
_translate = QCoreApplication.translate
|
|
|
|
|
|
class PlotRKC(PamhyrPlot):
|
|
def __init__(self, canvas=None, trad=None, toolbar=None,
|
|
river=None, reach=None, profile=None,
|
|
parent=None):
|
|
super(PlotRKC, 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_rk"]
|
|
self.label_y = self._trad["unit_elevation"]
|
|
|
|
self._isometric_axis = False
|
|
|
|
self._auto_relim_update = True
|
|
self._autoscale_update = True
|
|
self.parent = parent
|
|
self.anotate_lst = []
|
|
|
|
@property
|
|
def river(self):
|
|
return self.data
|
|
|
|
@river.setter
|
|
def river(self, river):
|
|
self.data = river
|
|
|
|
@timer
|
|
def draw(self, highlight=None):
|
|
self.init_axes()
|
|
|
|
if self.data is None:
|
|
self.profile = None
|
|
self.line_rk_zmin_zmax = None
|
|
self.line_rk_zmin = None
|
|
self.hs_vlines = None
|
|
return
|
|
|
|
if self._current_reach is None:
|
|
self.profile = None
|
|
self.line_rk_zmin_zmax = None
|
|
self.line_rk_zmin = None
|
|
self.hs_vlines = None
|
|
return
|
|
|
|
self.draw_data(highlight)
|
|
|
|
self.idle()
|
|
self._init = True
|
|
|
|
def draw_data(self, highlight):
|
|
reach = self._current_reach
|
|
rk = reach.reach.get_rk()
|
|
z_min = reach.reach.get_z_min()
|
|
z_max = reach.reach.get_z_max()
|
|
|
|
self.line_rk_zmin, = self.canvas.axes.plot(
|
|
rk, z_min,
|
|
color=self.color_plot_river_bottom,
|
|
lw=1.,
|
|
)
|
|
|
|
self.line_rk_zmax, = self.canvas.axes.plot(
|
|
rk, z_max,
|
|
color=self.color_plot_river_bottom,
|
|
lw=1.,
|
|
alpha=0.0
|
|
)
|
|
|
|
if len(rk) != 0:
|
|
self.line_rk_zmin_zmax = self.canvas.axes.vlines(
|
|
x=rk,
|
|
ymin=z_min, ymax=z_max,
|
|
color=self.color_highlight(highlight),
|
|
lw=1.,
|
|
picker=10
|
|
)
|
|
|
|
self.draw_hs()
|
|
# Draw HS
|
|
|
|
def draw_hs(self):
|
|
reach = self._current_reach
|
|
rk = reach.reach.get_rk()
|
|
z_min = reach.reach.get_z_min()
|
|
z_max = reach.reach.get_z_max()
|
|
lhs = filter(
|
|
lambda hs: hs._input_reach is reach,
|
|
filter(
|
|
lambda hs: hs._input_reach is not None,
|
|
self.data.hydraulic_structures.lst
|
|
)
|
|
)
|
|
|
|
vx = []
|
|
vymin = []
|
|
vymax = []
|
|
self.anotate_lst = []
|
|
hs_color = []
|
|
index = self.parent.tableView.selectedIndexes()
|
|
for i, hs in enumerate(lhs):
|
|
if i == index[0].row():
|
|
hs_color.append("blue")
|
|
elif hs.enabled:
|
|
hs_color.append("red")
|
|
else:
|
|
hs_color.append("darkgrey")
|
|
x = hs.input_rk
|
|
if x is not None:
|
|
a = self.canvas.axes.annotate(
|
|
" > " + hs.name,
|
|
(x, max(z_max)),
|
|
horizontalalignment='left',
|
|
verticalalignment='top',
|
|
annotation_clip=True,
|
|
fontsize=9,
|
|
color=hs_color[-1],
|
|
)
|
|
self.anotate_lst.append(a)
|
|
vx.append(x)
|
|
vymin.append(min(z_min))
|
|
vymax.append(max(z_max))
|
|
|
|
self.hs_vlines = self.canvas.axes.vlines(
|
|
x=vx, ymin=vymin, ymax=vymax,
|
|
linestyle="--",
|
|
lw=1.,
|
|
color=hs_color,
|
|
)
|
|
|
|
def color_highlight(self, highlight):
|
|
|
|
reach = self._current_reach
|
|
colors = [self.color_plot_river_bottom] * reach.reach.number_profiles
|
|
|
|
if highlight is not None:
|
|
rk = reach.reach.get_rk()
|
|
rows = [i for i in range(len(rk))
|
|
if (rk[i] >= highlight[0] and rk[i] <= highlight[1])]
|
|
if len(rows) > 0:
|
|
for row in rows:
|
|
colors[row] = "blue"
|
|
return colors
|
|
|
|
def set_reach(self, reach):
|
|
self._current_reach = reach
|
|
self._current_profile = None
|
|
self.update()
|
|
|
|
def set_profile(self, profile):
|
|
self._current_profile = profile
|
|
self.update_current_profile()
|
|
|
|
def update(self):
|
|
self.draw()
|
|
|
|
def update_current_profile(self):
|
|
reach = self._current_reach
|
|
rk = reach.reach.get_rk()
|
|
z_min = reach.reach.get_z_min()
|
|
z_max = reach.reach.get_z_max()
|
|
|
|
if self.profile is None:
|
|
self.draw()
|
|
else:
|
|
self.profile.set_data(
|
|
[self._current_profile.rk, self._current_profile.rk],
|
|
[self._current_profile.z_min(), self._current_profile.z_max()],
|
|
)
|
|
|
|
self.update_idle()
|
|
|
|
def clear(self):
|
|
if self.profile is not None:
|
|
self.profile[0].set_data([], [])
|
|
|
|
if self.line_rk_zmin_zmax is not None:
|
|
self.line_rk_zmin_zmax.remove()
|
|
self.line_rk_zmin_zmax = None
|
|
|
|
if self.line_rk_zmin is not None:
|
|
self.line_rk_zmin.set_data([], [])
|
|
|
|
if self.hs_vlines is not None:
|
|
self.hs_vlines.remove()
|
|
self.hs_vlines = None
|
|
|
|
for a in self.anotate_lst:
|
|
a.remove()
|
|
self.anotate_lst = []
|
|
|
|
self.canvas.figure.canvas.draw_idle()
|
|
|
|
def clear_profile(self):
|
|
if self.profile is not None:
|
|
self.profile[0].set_data([], [])
|
|
|
|
self.canvas.figure.canvas.draw_idle()
|
|
|
|
def onpick(self, event):
|
|
if event.mouseevent.inaxes != self.canvas.axes:
|
|
return
|
|
if event.mouseevent.button.value != 1:
|
|
return
|
|
|
|
modifiers = QApplication.keyboardModifiers()
|
|
if modifiers not in [Qt.ControlModifier,
|
|
Qt.NoModifier,
|
|
Qt.ShiftModifier]:
|
|
return
|
|
|
|
closest = self._closest_profile(event)
|
|
index = self.parent.tableView.selectedIndexes()
|
|
if self.parent._table is not None:
|
|
self.parent._table.setData(index[2], closest)
|
|
|
|
return
|
|
|
|
def _closest_profile(self, event):
|
|
|
|
s = event.artist.get_segments()
|
|
x = [i[0, 0] for i in s]
|
|
mx = event.mouseevent.xdata
|
|
points = enumerate(x)
|
|
|
|
def dist_mouse(point):
|
|
x = point[1]
|
|
d = abs(mx - x)
|
|
return d
|
|
|
|
closest = min(
|
|
points, key=dist_mouse
|
|
)
|
|
|
|
return closest[1]
|