diff --git a/pb_tool.cfg b/pb_tool.cfg
index fb8f230..5662690 100644
--- a/pb_tool.cfg
+++ b/pb_tool.cfg
@@ -48,7 +48,7 @@ plugin_path:/home/patrick/.local/share/QGIS/QGIS3/profiles/default/python/plugin
[files]
# Python files that should be deployed with the plugin
-python_files: __init__.py pegelonline.py pegelonline_dockwidget.py po_runner.py poGraph2.py
+python_files: __init__.py pegelonline.py pegelonline_dockwidget.py po_runner.py
# The main dialog file that is loaded (not compiled)
main_dialog: pegelonline_dockwidget_base.ui
diff --git a/pegelonline_dockwidget_base.ui b/pegelonline_dockwidget_base.ui
index 1936b0b..eb536be 100644
--- a/pegelonline_dockwidget_base.ui
+++ b/pegelonline_dockwidget_base.ui
@@ -6,8 +6,8 @@
0
0
- 290
- 676
+ 288
+ 660
@@ -39,65 +39,61 @@
Optionen:
-
+
-
-
+
-
-
-
-
-
-
- Name
-
-
-
- -
-
-
- Nummer
-
-
-
- -
-
-
- Betreiber
-
-
-
- -
-
-
- Zeitstempel
-
-
-
-
+
+
+ Name
+
+
-
-
-
-
-
-
- Aktueller Wert
-
-
-
- -
-
-
- MNW, MHW
-
-
-
- -
-
-
- NSW, HSW
-
-
-
-
+
+
+ Nummer
+
+
+
+ -
+
+
+ Organisation
+
+
+
+ -
+
+
+ Zeitstempel
+
+
+
+
+
+ -
+
+
-
+
+
+ Aktueller Wert
+
+
+
+ -
+
+
+ MNW, MHW
+
+
+
+ -
+
+
+ NSW, HSW
+
+
@@ -168,7 +164,7 @@
-
- Betreiber
+ Organisation
@@ -199,35 +195,137 @@
-
-
+
Pegelverlauf:
-
-
+
-
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
Station:
-
-
+
+
+
+ 0
+ 0
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 80
+ 0
+
+
+
+ Neu Laden
+
+
+
+
+
+ -
+
-
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
Tage
-
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+ 1
+
+
+ 30
+
+
+ 14
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 80
+ 0
+
+
+
+ Anzeigen
+
+
+ -
+
+
+ Bitte wählen...
+
+
+
diff --git a/poGraph2.py b/poGraph2.py
deleted file mode 100644
index 65034ff..0000000
--- a/poGraph2.py
+++ /dev/null
@@ -1,117 +0,0 @@
-import ctypes
-from urllib.parse import quote
-
-from PyQt5 import QtCore, QtGui
-from PyQt5 import QtWidgets
-
-from .pomodules import poBaseURL
-from .pomodules.urlreader import UrlReader
-
-
-class PoGraphDisplay(QtWidgets.QWidget):
-
- def __init__(self, parent=None):
- QtWidgets.QWidget.__init__(self, parent)
- self.setupUi(self)
-
- # Layer
- self.layer = None
-
- def setupUi(self, poGraphDisplay):
- """Definition der Benutzeroberflaeche des Wasserstanddiagramms mit den dazugehoerigen Funktionen."""
-
- # uebergeordnetes Layout
- self.verticalLayout = QtWidgets.QVBoxLayout(poGraphDisplay)
-
- # Erste Zeile ---
-
- self.horizontalLayout = QtWidgets.QHBoxLayout()
-
- # Label Station
- self.lbStation = QtWidgets.QLabel()
- self.lbStation.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
- self.horizontalLayout.addWidget(self.lbStation)
- self.lbStation.setText("Geben Sie hier eine Station ein:")
-
- # ComboBox Stations
- self.comboBox = QtWidgets.QComboBox()
- self.comboBox.setEditable(True)
- self.horizontalLayout.addWidget(self.comboBox)
-
- # Label Tage
- self.lbTage = QtWidgets.QLabel()
- self.lbTage.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
- self.lbTage.setText("Tage")
- self.horizontalLayout.addWidget(self.lbTage)
-
- # SpinBox Tage
- self.sbTage = QtWidgets.QSpinBox()
- self.sbTage.setMinimum(5)
- self.sbTage.setMaximum(30)
- self.sbTage.setProperty("value", 14)
- self.horizontalLayout.addWidget(self.sbTage)
-
- # PushButton Laden
- self.pbLaden = QtWidgets.QPushButton()
- self.pbLaden.setObjectName("pbLaden")
- self.pbLaden.setText("Laden")
- self.horizontalLayout.addWidget(self.pbLaden)
-
- # Signal Slots
- self.pbLaden.clicked.connect(self.doPbLaden)
- self.verticalLayout.addLayout(self.horizontalLayout)
-
- # Zweite Zeile ---
-
- # Label fuer den Graphen
- self.lbGraph = QtWidgets.QLabel()
- self.lbGraph.setText("")
- self.lbGraph.setObjectName("lbGraph")
- self.verticalLayout.addWidget(self.lbGraph)
-
- # Quellenhinweis
- self.lbDatenquelle = QtWidgets.QLabel()
- self.lbDatenquelle.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignLeading | QtCore.Qt.AlignVCenter)
- self.lbDatenquelle.setText("Die Daten werden von 'pegelonline.wsv.de' zur Verfügung gestellt.")
- self.verticalLayout.addWidget(self.lbDatenquelle)
-
- # Dritte Zeile ---
-
- spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.verticalLayout.addItem(spacerItem)
-
- def doLoadGraph(self):
- """Laedt die Stationsdaten anhand der vom Nutzer eingegebenen Daten."""
-
- # Anzahl der Tage in der SpinBox
- days = self.getCurrentDays()
-
- # Stationsname aus der ComboBox
- station = quote(self.getCurrentStation())
- url = poBaseURL + "/stations/%s/W/measurements.png?start=P%dD" % (station, days)
- ur = UrlReader(url)
- self.img_data = ur.getDataResponse()
-
- if ur.code > 299:
- AlertBox = ctypes.windll.user32.MessageBoxW
- AlertBox(None, "Beim Laden der Daten ist ein Fehler aufgetreten.", "Fehler", 0)
-
- else:
- # Grafik einsetzen
- pixmap = QtGui.QPixmap()
- pixmap.loadFromData(self.img_data)
- self.lbGraph.clear()
- self.lbGraph.setPixmap(pixmap)
- self.lbGraph.resize(pixmap.width(), pixmap.height())
-
- def doPbLaden(self):
- """Laedt den Graphen der ausgewaehlten Station."""
-
- if self.layer is None:
- self.doLoadGraph()
-
- def getCurrentDays(self):
- return self.sbTage.value()
-
- def getCurrentStation(self):
- return self.comboBox.currentText()
diff --git a/po_runner.py b/po_runner.py
index e8be14d..a291b7b 100644
--- a/po_runner.py
+++ b/po_runner.py
@@ -1,11 +1,14 @@
import os.path
from typing import Callable
+from PyQt5 import QtGui
from qgis._core import QgsVectorLayer, QgsProject, QgsLayerTreeLayer, QgsPalLayerSettings, QgsVectorLayerSimpleLabeling
from .pegelonline_dockwidget import PegelonlineDockWidget
-from .pomodules.poqgscurrentw import PoQgsCurrentW
-from .pomodules.poqgsstations import PoQgsStations
+from .pomodules.po_history import PoHistory
+from .pomodules.po_stations import PoStations
+from .pomodules.po_stations_qgs import PoQgsStations
+from .pomodules.po_waterlevels_qgs import PoQgsCurrentW
INFIX = ", ' - ', "
@@ -27,16 +30,12 @@ class PoRunner(object):
self.connect_basemap_signals()
self.connect_stations_signals()
self.connect_waterlevels_signals()
+ self.connect_history_signals()
+
+ self._historyLoadStations()
# basemap -----------------------------------------------------------------
- def disconnectStations(self):
- print("disconnectStations")
- self.stations = None
- self.ui.cbStationsVisible.setChecked(False)
-
- # basemap signals ---------------------------------------------------------
-
def _basemapCreate(self, path, name, disconnect: Callable[[], None]) -> None | QgsVectorLayer:
print("_basemapCreate: %s" % (name,))
path = os.path.join(self.local_dir, "basemap", path)
@@ -59,6 +58,8 @@ class PoRunner(object):
return basemap
+ # basemap signals ---------------------------------------------------------
+
def connect_basemap_signals(self):
print("connect_basemap_signals")
self.ui.cbBasemapLines.toggled.connect(self.cbBasemapLinesToggled)
@@ -98,28 +99,6 @@ class PoRunner(object):
# stations ----------------------------------------------------------------
- # noinspection DuplicatedCode
- def _stationsUpdateLabeling(self):
- print("_stationsUpdateLabeling")
- if self.stations is None:
- return
-
- fields = []
- if self.ui.cbStationsName.isChecked():
- fields.append("shortname")
- if self.ui.cbStationsNumber.isChecked():
- fields.append("number")
- if self.ui.cbStationsAgency.isChecked():
- fields.append("agency")
- if self.ui.cbStationsKm.isChecked():
- fields.append("km")
- if self.ui.cbStationsWater.isChecked():
- fields.append("water")
-
- self._layerUpdateLabeling(self.stations, fields)
-
- # stations signals --------------------------------------------------------
-
def connect_stations_signals(self):
print("connect_stations_signals")
# noinspection DuplicatedCode
@@ -169,31 +148,32 @@ class PoRunner(object):
print("cbStationsWaterToggled: %s" % (checked,))
self._stationsUpdateLabeling()
- # waterlevels -------------------------------------------------------------
+ def disconnectStations(self):
+ print("disconnectStations")
+ self.stations = None
+ self.ui.cbStationsVisible.setChecked(False)
# noinspection DuplicatedCode
- def _waterlevelsUpdateLabeling(self):
- if self.waterlevels is None:
+ def _stationsUpdateLabeling(self):
+ print("_stationsUpdateLabeling")
+ if self.stations is None:
return
fields = []
- if self.ui.cbWaterlevelsName.isChecked():
+ if self.ui.cbStationsName.isChecked():
fields.append("shortname")
- if self.ui.cbWaterlevelsNumber.isChecked():
+ if self.ui.cbStationsNumber.isChecked():
fields.append("number")
- if self.ui.cbWaterlevelsAgency.isChecked():
+ if self.ui.cbStationsAgency.isChecked():
fields.append("agency")
- if self.ui.cbWaterlevelsTimestamp.isChecked():
- fields.append("timestamp")
- if self.ui.cbWaterlevelsValue.isChecked():
- fields.append("value")
- if self.ui.cbWaterlevelsMean.isChecked():
- fields.append("stateMnwMhw")
- if self.ui.cbWaterlevelsAbsolute.isChecked():
- fields.append("stateNswHsw")
- self._layerUpdateLabeling(self.waterlevels, fields)
+ if self.ui.cbStationsKm.isChecked():
+ fields.append("km")
+ if self.ui.cbStationsWater.isChecked():
+ fields.append("water")
- # waterlevels signals -----------------------------------------------------
+ self._layerUpdateLabeling(self.stations, fields)
+
+ # waterlevels -------------------------------------------------------------
def connect_waterlevels_signals(self):
print("connect_waterlevels_signals")
@@ -261,6 +241,28 @@ class PoRunner(object):
self.waterlevels = None
self.ui.cbWaterlevelsVisible.setChecked(False)
+ # noinspection DuplicatedCode
+ def _waterlevelsUpdateLabeling(self):
+ if self.waterlevels is None:
+ return
+
+ fields = []
+ if self.ui.cbWaterlevelsName.isChecked():
+ fields.append("shortname")
+ if self.ui.cbWaterlevelsNumber.isChecked():
+ fields.append("number")
+ if self.ui.cbWaterlevelsAgency.isChecked():
+ fields.append("agency")
+ if self.ui.cbWaterlevelsTimestamp.isChecked():
+ fields.append("timestamp")
+ if self.ui.cbWaterlevelsValue.isChecked():
+ fields.append("value")
+ if self.ui.cbWaterlevelsMean.isChecked():
+ fields.append("stateMnwMhw")
+ if self.ui.cbWaterlevelsAbsolute.isChecked():
+ fields.append("stateNswHsw")
+ self._layerUpdateLabeling(self.waterlevels, fields)
+
# layers ------------------------------------------------------------------
def _layerSetVisible(self, basemap: QgsVectorLayer, visible):
@@ -338,3 +340,81 @@ class PoRunner(object):
layer.triggerRepaint()
else:
self.iface.mapCanvas().refresh()
+
+ # history signals ---------------------------------------------------------
+
+ def connect_history_signals(self):
+ self.ui.slHistoryStation.currentTextChanged.connect(self.slHistoryStationChanged)
+ self.ui.btnHistoryStationsRefresh.clicked.connect(self.btnHistoryStationsRefreshClicked)
+ self.ui.inHistoryDays.valueChanged.connect(self.inHistoryDaysChanged)
+ self.ui.btnHistoryGo.clicked.connect(self._historyLoadGraph)
+
+ def btnHistoryStationsRefreshClicked(self):
+ print("btnHistoryStationsRefreshClicked")
+ self._historyLoadStations()
+
+ def slHistoryStationChanged(self):
+ print("slHistoryStationChanged: %s" % (self.ui.slHistoryStation.currentText(),))
+ self._historyLoadGraph()
+
+ def inHistoryDaysChanged(self):
+ print("inHistoryDays: %s" % (self.ui.inHistoryDays.value(),))
+
+ def _historyLoadGraph(self):
+ station = self.ui.slHistoryStation.currentText()
+ days = self.ui.inHistoryDays.value()
+
+ print("_historyLoad: station=%s days=%s" % (station, days))
+
+ self.ui.lbHistory.clear()
+ self.ui.lbHistory.setText("Laden...")
+
+ if station == '' or station is None:
+ print("_historyLoad: Fehler: Ungültige Station: %s" % (station,))
+ self.ui.lbHistory.setText("Bitte Station wählen...")
+ return
+
+ if days is None or days < 1 or days > 30:
+ print("_historyLoad: Fehler: Ungültige Anzahl von Tagen: %s" % (days,))
+ self.ui.lbHistory.setText("Bitte Tage [1, 30] wählen...")
+ return
+
+ history = PoHistory(station, days)
+ image_data = history.download()
+
+ if image_data is None or len(image_data) == 0:
+ print("_historyLoad: Fehler: Keine Daten erhalten")
+ self.ui.lbHistory.setText("Fehler beim Download!")
+ return
+
+ pixmap = QtGui.QPixmap()
+ pixmap.loadFromData(image_data)
+ self.ui.lbHistory.setPixmap(pixmap)
+ self.ui.lbHistory.resize(pixmap.width(), pixmap.height())
+
+ def _historyLoadStations(self):
+ print("_init_history_signals")
+
+ # merke die aktuelle Station, um sie wiederherzustellen
+ bisherige_station = self.ui.slHistoryStation.currentText()
+
+ self.ui.slHistoryStation.clear()
+
+ stations = PoStations().getStations()
+ if stations is None or len(stations) == 0:
+ print("_init_history_signals: Fehler: Keine Stationen erhalten")
+ return
+
+ index = 0
+ neuer_index = None
+ for station in stations:
+ shortname = station['attributes']['shortname']
+ if shortname == bisherige_station:
+ neuer_index = index
+ self.ui.slHistoryStation.addItem(shortname)
+ index += 1
+
+ if neuer_index is not None:
+ self.ui.slHistoryStation.setCurrentIndex(neuer_index)
+ else:
+ self.ui.slHistoryStation.setCurrentIndex(0)
diff --git a/pomodules/po_history.py b/pomodules/po_history.py
new file mode 100644
index 0000000..3bd3137
--- /dev/null
+++ b/pomodules/po_history.py
@@ -0,0 +1,21 @@
+from urllib.parse import quote
+
+from . import poBaseURL
+from .urlreader import UrlReader
+
+
+class PoHistory(UrlReader):
+
+ def __init__(self, station: str, days: int):
+ super().__init__(poBaseURL + 'stations/%s/W/measurements.png?start=P%dD' % (quote(station), days))
+
+ def download(self):
+ print("download: Getting data...")
+
+ image_data = self.getDataResponse()
+ if image_data is None or len(image_data) == 0:
+ print("download: Fehler: Keine Daten erhalten")
+ return None
+
+ print("download: Complete")
+ return image_data
diff --git a/pomodules/postations.py b/pomodules/po_stations.py
similarity index 89%
rename from pomodules/postations.py
rename to pomodules/po_stations.py
index d585c3c..32fe3d9 100644
--- a/pomodules/postations.py
+++ b/pomodules/po_stations.py
@@ -2,17 +2,16 @@ from . import poBaseURL
from .urlreader import UrlReader
-class PoStations(object):
+class PoStations(UrlReader):
def __init__(self):
- self.url = poBaseURL + 'stations.json'
+ super().__init__(poBaseURL + 'stations.json')
def getStations(self):
print("getStations: Getting data...")
- reader = UrlReader(self.url)
- stations_json = reader.getJsonResponse()
- if stations_json is None:
+ stations_json = self.getJsonResponse()
+ if stations_json is None or len(stations_json) == 0:
print("getStations: Keine Stationen erhalten")
return None
diff --git a/pomodules/poqgsstations.py b/pomodules/po_stations_qgs.py
similarity index 87%
rename from pomodules/poqgsstations.py
rename to pomodules/po_stations_qgs.py
index a99e172..8da8646 100644
--- a/pomodules/poqgsstations.py
+++ b/pomodules/po_stations_qgs.py
@@ -2,13 +2,13 @@ from PyQt5.QtCore import QVariant
from qgis._core import QgsCoordinateReferenceSystem, QgsGeometry, QgsPointXY
from qgis.core import QgsFields, QgsFeature, QgsField
-from .postations import PoStations
+from .po_stations import PoStations
class PoQgsStations(PoStations):
def __init__(self):
- PoStations.__init__(self)
+ super().__init__()
self.fields = None
self.crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
@@ -25,7 +25,13 @@ class PoQgsStations(PoStations):
self.fields.append(QgsField('water', QVariant.String))
features = []
- for station in self.getStations():
+ stations = self.getStations()
+
+ if stations is None or len(stations) == 0:
+ print("getStations: Fehler: Keine Stationen erhalten")
+ return None
+
+ for station in stations:
feature = self._getFeatureForStation(station)
features.append(feature)
diff --git a/pomodules/pocurrentw.py b/pomodules/po_waterlevels.py
similarity index 86%
rename from pomodules/pocurrentw.py
rename to pomodules/po_waterlevels.py
index 4820c68..a24dfe2 100644
--- a/pomodules/pocurrentw.py
+++ b/pomodules/po_waterlevels.py
@@ -2,17 +2,16 @@ from . import poBaseURL
from .urlreader import UrlReader
-class PoCurrentW(object):
+class PoCurrentW(UrlReader):
def __init__(self):
- self.url = poBaseURL + 'stations.json?timeseries=W&includeTimeseries=true&includeCurrentMeasurement=true'
+ super().__init__(poBaseURL + 'stations.json?timeseries=W&includeTimeseries=true&includeCurrentMeasurement=true')
def getCurrentW(self):
print("getCurrentW: Getting data...")
- reader = UrlReader(self.url)
- stations_json = reader.getJsonResponse()
- if stations_json is None:
+ stations_json = self.getJsonResponse()
+ if stations_json is None or len(stations_json) == 0:
print("getCurrentW: FEHLER: Keine Stationen erhalten")
return None
diff --git a/pomodules/poqgscurrentw.py b/pomodules/po_waterlevels_qgs.py
similarity index 88%
rename from pomodules/poqgscurrentw.py
rename to pomodules/po_waterlevels_qgs.py
index 1133184..9037d14 100644
--- a/pomodules/poqgscurrentw.py
+++ b/pomodules/po_waterlevels_qgs.py
@@ -2,7 +2,7 @@ from PyQt5.QtCore import QVariant
from qgis._core import QgsCoordinateReferenceSystem, QgsGeometry, QgsPointXY
from qgis.core import QgsFields, QgsFeature, QgsField
-from .pocurrentw import PoCurrentW
+from .po_waterlevels import PoCurrentW
class PoQgsCurrentW(PoCurrentW):
@@ -25,7 +25,12 @@ class PoQgsCurrentW(PoCurrentW):
self.fields.append(QgsField('stateNswHsw', QVariant.String))
features = []
- for station in self.getCurrentW():
+ waterlevels = self.getCurrentW()
+ if waterlevels is None or len(waterlevels) > 0:
+ print("getCurrentW: Fehler: Keine Pegelstände erhalten")
+ return None
+
+ for station in waterlevels:
feature = self._getFeatureForStation(station)
features.append(feature)