# -*- coding: utf-8 -*- import logging from functools import reduce from tools import timer from View.Tools.PamhyrPlot import PamhyrPlot from PyQt5.QtCore import ( QCoreApplication ) _translate = QCoreApplication.translate logger = logging.getLogger() class PlotSedProfile(PamhyrPlot): def __init__(self, canvas=None, trad=None, toolbar=None, results=None, reach_id=0, profile_id=0, parent=None): super(PlotSedProfile, self).__init__( canvas=canvas, trad=trad, data=results, toolbar=toolbar, parent=parent ) self._results = results self._current_timestamp = max(results.get("timestamps")) self._current_reach_id = reach_id self._current_profile_id = profile_id @property def results(self): return self.data @results.setter def results(self, results): self.data = results self._results = results self._current_timestamp = max(results.get("timestamps")) def get_zsl(self, profile): x = profile.geometry.get_station() z = profile.geometry.z() profiles_sl = list( map( lambda sl: sl[0], profile.get_ts_key(self._current_timestamp, "sl") ) ) profiles_sl_0 = list( map( lambda sl: sl[0], profile.get_ts_key(0.0, "sl") ) ) f = list(map(lambda p: 0, range(profile.geometry.number_points))) sl = [] sl_0 = [] for profile_sl, profile_sl_0 in zip(profiles_sl, profiles_sl_0): cur = [] cur_0 = [] for p in range(profile.geometry.number_points): cur.append(profile_sl) cur_0.append(profile_sl_0) sl.append(cur) sl_0.append(cur_0) # Compute sediment layer from initial data in function to # profile z_min z_sl = reduce( lambda acc, v: acc + [ list( map(lambda x, y: y - x, v, acc[-1]) ) ], sl_0, [z] ) # Diff between initial data and data att current timestamp d_sl = list( map( lambda ln0, lni: list( map( lambda z0, zi: z0 - zi, ln0, lni ) ), sl_0, sl ) ) # Apply diff for t0 for each layer Z z_sl = list( map( lambda z, d: list( map( lambda zn, dn: zn - dn, z, d ) ), z_sl, d_sl + [f] # HACK: Add dummy data for last layer ) ) return list(reversed(z_sl)) @timer def draw(self): self.canvas.axes.cla() self.canvas.axes.grid(color='grey', linestyle='--', linewidth=0.5) if self.data is None: return reach = self._results.river.reach(self._current_reach_id) profile = reach.profile(self._current_profile_id) if profile.geometry.number_points == 0: return self.canvas.axes.set_xlabel( _translate("MainWindow_reach", "X (m)"), color='black', fontsize=10 ) self.canvas.axes.set_ylabel( _translate("MainWindow_reach", "Height (m)"), color='black', fontsize=10 ) x = profile.geometry.get_station() z = profile.geometry.z() self.canvas.axes.set_xlim( left=min(x), right=max(x) ) z_sl = self.get_zsl(profile) self.line_kp_sl = [] for i, zsl in enumerate(z_sl): self.line_kp_sl.append(None) self.line_kp_sl[i], = self.canvas.axes.plot( x, zsl, linestyle="solid" if i == len(z_sl) - 1 else "--", lw=1.8, color='grey' if i == len(z_sl) - 1 else None ) self.canvas.figure.tight_layout() self.canvas.figure.canvas.draw_idle() if self.toolbar is not None: self.toolbar.update() self._init = False @timer def update(self, ind=None): if not self._init: self.draw() return if ind is None: logger.info("TODO: Update") self.canvas.axes.autoscale_view(True, True, True) self.canvas.figure.canvas.draw_idle() def set_reach(self, reach_id): self._current_reach_id = reach_id self._current_profile_id = 0 self.draw() def set_profile(self, profile_id): self._current_profile_id = profile_id self.draw() def set_timestamp(self, timestamp): self._current_timestamp = timestamp self.draw()