diff --git a/prog/main.py b/prog/main.py index 7554ea46703febc0cab9655cc4ad1a465b03f03b..a966db35ff7c0e504e1961e317b983ccc04bd886 100755 --- a/prog/main.py +++ b/prog/main.py @@ -105,6 +105,11 @@ class DockWidgetWithClosedSignal(QDockWidget): self.closed.emit() super().closeEvent(event) +def no_space(lay): + lay.setSpacing(0) + lay.setContentsMargins(0, 0, 0, 0) + return lay + communications = {} @@ -933,8 +938,8 @@ class TripPointWindow(QWidget): stop = g.stops.get(json["id"], None) obj.id.setText(json["id"]) obj.name.setText(stop.name if stop else "") - obj.arrival.set_dt((datetime.datetime.fromisoformat(json["arrival_time"]))) - obj.departure.set_dt(datetime.datetime.fromisoformat(json["departure_time"])) + obj.arrival.set_dt(datetime.datetime.fromisoformat(json["arrival_time"]) if json["arrival_time"] else None) + obj.departure.set_dt(datetime.datetime.fromisoformat(json["departure_time"]) if json["departure_time"] else None) else: obj.name.setText("") obj.arrival.set_dt(None) @@ -968,12 +973,53 @@ class LayerWidget(QWidget): super().__init__() self.layers = layers - self._layout = QVBoxLayout() + self._layout = no_space(QHBoxLayout()) self.setLayout(self._layout) + self._visible = QCheckBox() + self._visible.setCheckState(Qt.Checked) + self._visible.stateChanged.connect(self.set_visible) + self._layout.addWidget(self._visible) + self._title = QLabel(title) self._layout.addWidget(self._title) + def set_visible(self, val): + for l in self.layers: + l.setItemVisibilityChecked(v) + + +class SetRangeWindow(QWidget): + def __init__(self, dt_from, dt_to, callback): + super().__init__() + self.callback = callback + self._layout = QVBoxLayout() + self.setLayout(self._layout) + + self._dt_from = QLineEdit(format_dt_to_user(dt_from)) + self._layout.addWidget(self._dt_from) + self._dt_from.returnPressed.connect(self.done) + + self._dt_to = QLineEdit(format_dt_to_user(dt_to)) + self._layout.addWidget(self._dt_to) + self._dt_to.returnPressed.connect(self.done) + + self._done = QPushButton("(Re)load") + self._done.clicked.connect(self.done) + self._layout.addWidget(self._done) + + self.setWindowTitle(f"{window_title_prefix} - range selector") + + @asyncSlot() + async def done(self): + dt_from = parse_dt_from_user(self._dt_from.text()) + dt_to = parse_dt_from_user(self._dt_to.text()) + self.hide() + del tmp_windows[self] + await self.callback(dt_from, dt_to) + + + class LoadRangeWidget(QWidget): def __init__(self, mwnd, route_id): @@ -1021,7 +1067,7 @@ class LoadRangeWidget(QWidget): self._dt_from.set_dt(self.dt_from) self._dt_to.set_dt(self.dt_to) - async def clear(self, dt_from, dt_to): + async def clear(self): self.dt_from = self.dt_to = None self.update_dt_labels() await self.cb_clear() @@ -1035,7 +1081,14 @@ class LoadRangeWidget(QWidget): await self.load(self.dt_to+datetime.timedelta(seconds=10), self.dt_to+datetime.timedelta(minutes=15)) def select_and_reload(self): - ... + async def callback(dt_from, dt_to): + self.stop_live() + await self.clear() + await self.load(dt_from, dt_to, strict=True) + + w = SetRangeWindow(self.dt_from, self.dt_to+datetime.timedelta(seconds=10), callback) + tmp_windows[w] = w + w.show() @asyncSlot() async def start_live(self): @@ -1073,8 +1126,10 @@ class LoadRangeWidget(QWidget): dt = dt_from.replace(second=0, microsecond=0, minute=0) while dt < dt_to: data, source_timestamps = await c.get_preprocessed_data(dt, self.route_id) + if strict: + source_timestamps = [x for x in source_timestamps if dt_from <= x and x < dt_to] data = await unzip_parse(data) - await self.cb_add_preprocessed_data(data, dt_minf, dt_pinf) + await self.cb_add_preprocessed_data(data, dt_from if strict else dt_minf, dt_to if strict else dt_pinf) if len(source_timestamps): print(self.dt_from, self.dt_to) print(source_timestamps[0], source_timestamps[-1]) @@ -1126,6 +1181,7 @@ class TripHistoryWidget(QWidget): self._load_range = LoadRangeWidget(self.mwnd, self.trip.trip_id.split("_")[0]) self._load_range.cb_add_preprocessed_data = self.add_preprocessed_data + self._load_range.cb_clear = self.clear_history self._load_range.cb_data_changed = self.redraw_all_async self._load_range.cb_add_live_data = self.add_live_data self._layout.addWidget(self._load_range) @@ -1145,13 +1201,17 @@ class TripHistoryWidget(QWidget): self.mwnd.map.removeLayer(self.history_points_layer) + async def clear_history(self): + self.th.history = [] + async def add_preprocessed_data(self, data, dt_from, dt_to): if self.trip.trip_id in data: - self.th.add_preprocessed_data(data[self.trip.trip_id]) + self.th.add_preprocessed_data(data[self.trip.trip_id], dt_from, dt_to) async def add_live_data(self, dt, data, data_by_trip_id): - self.th.add_history_point(dt, data_by_trip_id[self.trip.trip_id]) - self.redraw_all() + if self.trip.trip_id in data_by_trip_id: + self.th.add_history_point(dt, data_by_trip_id[self.trip.trip_id]) + self.redraw_all() async def load(self, dt_from, dt_to): @@ -1190,6 +1250,7 @@ class TripHistoryWidget(QWidget): line_points.append(point) geometry = QgsGeometry.fromPolylineXY(line_points) feat.setGeometry(geometry) + history_line_prov.truncate() history_line_prov.addFeatures([feat]) @@ -1201,6 +1262,7 @@ class TripHistoryWidget(QWidget): # feat["repeated"] = tp_data["repeated"] # feat["without_data"] = tp_data["without_data"] history_points_feats.append(feat) + history_points_prov.truncate() history_points_prov.addFeatures(history_points_feats) layer_updated(self.history_line_layer) @@ -1226,6 +1288,7 @@ class TripHistoryWidget(QWidget): feat.setGeometry(geometry) feats.append(feat) + prov.truncate() prov.addFeatures(feats) layer_updated(layer) @@ -1243,6 +1306,7 @@ class TripHistoryWidget(QWidget): points.append(QgsPointXY(x[1], x[0])) geometry = QgsGeometry.fromPolylineXY(points) feat.setGeometry(geometry) + shape_line_prov.truncate() shape_line_prov.addFeatures([feat]) shape_line_layer.updateExtents() @@ -1267,6 +1331,7 @@ class TripHistoryWidget(QWidget): feat["name"] = stop.stop.name feats.append(feat) + prov.truncate() prov.addFeatures(feats) layer_updated(self.history_line_layer)